Introduzione
Questa seconda parte è dedicata all’hardening del Mail Server operativo su rete Tor. Per una visione completa del progetto, si consiglia di consultare prima la guida “Mail Server su Tor con Nginx & RainLoop Webmail – Parte 1“, che introduce l’installazione e la configurazione iniziale. L’obiettivo è aumentare la sicurezza, proteggere i dati degli utenti e garantire l’affidabilità dei servizi SMTP/IMAP/Webmail esposti tramite Hidden Service.
⚖️ 1. Firewall e Protezione della Rete
La prima linea di difesa di un sistema esposto, anche solo su rete Tor, è il firewall. Limitare le porte aperte e bloccare il traffico non necessario riduce drasticamente la superficie d’attacco.
Installazione di UFW:
apt update && apt install ufw
# Disabilitare il supporto IPv6 (se non utilizzato)
# 📌 Nota: In ambienti privati Tor-Based senza uso di IPv6, è consigliato disabilitare il supporto IPv6.
vi /etc/default/ufw
All’interno del file /etc/default/ufw
, modificare la riga:
IPV6=yes
in:
IPV6=no
Successivamente, resettare UFW per applicare il cambiamento:
ufw reset
Configurazione regole base:
Impostazioni di default restrittive
ufw default deny incoming
ufw default deny outgoing
# Consentire porte in ingresso solo per i servizi Mail e Web in chiaro (HTTP locale, Tor cifra già)
ufw allow 25/tcp # SMTP
ufw allow 143/tcp # IMAP
ufw allow 993/tcp # IMAPS
ufw allow 80/tcp # HTTP (Webmail su Hidden Service .onion)
# Accesso SSH solo da IP/macchina di amministrazione
ufw allow from 172.16.16.205 to any port 22 proto tcp
# Consentire traffico locale e necessario a Tor
ufw allow in on lo
ufw allow out on lo
# Consentire accesso proxy Tor
ufw allow out to 127.0.0.1 port 9050 proto tcp
# Consentire DNS systemd-resolved (opzionale)
ufw allow out to 127.0.0.53 port 53 proto udp
# Consentire traffico Tor verso relay e directory (obbligatorio)
ufw allow out to any port 9001 proto tcp
ufw allow out to any port 9030 proto tcp
# Abilitare UFW
ufw enable
# Mostrare lo stato delle regole
ufw status numbered
Note:
- Bloccare tutte le connessioni in uscita eccetto quelle necessarie a Tor e alla risoluzione DNS locale.
- Consentire accesso SSH solo dal proprio IP di gestione o, se richiesto, dall’intera rete di amministrazione.
Verifica stato UFW:
ufw status verbose
🔄 Gestione Temporanea Aggiornamenti di Sistema
Per mantenere il server aggiornato senza compromettere la sicurezza:
Script per aggiornare il sistema:
Crea uno script /root/update_and_lock.sh
:
vi /root/update_and_lock.sh
Inserisci il seguente contenuto:
#!/bin/bash
# Timeout massimo per apt in secondi
APT_TIMEOUT=600
# Variabili stato
RESULT=""
FIREWALL_RESET=0
echo "[*] Sblocco temporaneo delle porte 53, 80 e 443 in uscita..."
ufw allow out to any port 53 proto udp
ufw allow out to any port 80 proto tcp
ufw allow out to any port 443 proto tcp
echo "[*] Avvio aggiornamento del sistema..."
# Primo: aggiornamento della lista pacchetti
timeout $APT_TIMEOUT apt update -o Acquire::ForceIPv4=true | tee /tmp/apt_update_output.txt
UPDATE_STATUS=$?
if [ $UPDATE_STATUS -eq 124 ]; then
echo "[!] Errore: aggiornamento fallito per timeout (${APT_TIMEOUT}s) durante apt update."
RESULT="Errore: timeout durante aggiornamento."
else
if grep -q "Failed to fetch" /tmp/apt_update_output.txt; then
echo "[!] Errore: alcuni repository non sono stati raggiunti correttamente!"
grep "Failed to fetch" /tmp/apt_update_output.txt
RESULT="Errore: repository non raggiungibili."
else
# Controllo pacchetti aggiornabili
UPGRADABLE=$(apt list --upgradable 2>/dev/null | grep -v "Listing..." | wc -l)
if [ $UPGRADABLE -eq 0 ]; then
echo "[+] Nessun pacchetto da aggiornare. Sistema già aggiornato."
RESULT="Sistema già aggiornato."
else
echo "[*] Pacchetti da aggiornare trovati: $UPGRADABLE. Avvio upgrade..."
timeout $APT_TIMEOUT apt upgrade -y -o Acquire::ForceIPv4=true | tee /tmp/apt_upgrade_output.txt
UPGRADE_STATUS=$?
if [ $UPGRADE_STATUS -eq 0 ]; then
echo "[+] Sistema aggiornato correttamente."
RESULT="Aggiornamento eseguito con successo."
elif [ $UPGRADE_STATUS -eq 124 ]; then
echo "[!] Errore: timeout durante apt upgrade."
RESULT="Errore: timeout durante aggiornamento."
else
echo "[!] Errore durante apt upgrade. Codice uscita: $UPGRADE_STATUS"
RESULT="Errore durante upgrade."
fi
fi
fi
fi
echo "[*] Pulizia file temporanei..."
rm -f /tmp/apt_update_output.txt /tmp/apt_upgrade_output.txt
echo "[*] Ripristino delle regole firewall..."
ufw delete allow out to any port 53 proto udp
ufw delete allow out to any port 80 proto tcp
ufw delete allow out to any port 443 proto tcp
if [ $? -eq 0 ]; then
FIREWALL_RESET=1
fi
echo "[+] Firewall ripristinato. Stato attuale delle regole:"
ufw status numbered
# Messaggio finale riepilogativo
echo ""
echo "=========================================="
echo "[*] Risultato aggiornamento:"
echo "$RESULT"
if [ $FIREWALL_RESET -eq 1 ]; then
echo "Firewall ripristinato in modalità sicura."
else
echo "Attenzione: firewall potrebbe non essere ripristinato correttamente!"
fi
echo "=========================================="
# Exit coerente
case $RESULT in
"Sistema già aggiornato."|"Aggiornamento eseguito con successo.")
exit 0
;;
*)
exit 1
;;
esac
chmod +x /root/update_and_lock.sh
Esecuzione dello script:
/root/update_and_lock.sh
📌 Questo metodo consente di aggiornare i pacchetti in sicurezza, mantenendo il server Tor completamente isolato nella configurazione normale.
Alternative: Per configurazioni più complesse o prestazioni superiori, considerare nftables come firewall di sistema.
🌐 2. Configurazione Sicura Nginx per Hidden Service
Limitare l’ascolto solo su localhost (127.0.0.1)
Modifica il file /etc/nginx/sites-available/rainloop
:
vi /etc/nginx/sites-available/rainloop
Sostituisci:
listen 80;
con:
listen 127.0.0.1:80;
Commenta o elimina eventuali linee listen [::]:80;
se presenti.
Rimuovere configurazioni predefinite non utilizzate
rm /etc/nginx/sites-available/default
rm /etc/nginx/sites-enabled/default
Riavvio Nginx
systemctl restart nginx
Verifica che Nginx ascolti SOLO su localhost
ss -lnpt | grep ':80'
Output atteso:
LISTEN 0 511 127.0.0.1:80 *:* users:(("nginx",pid=...,fd=...))
Configurazione completa Virtual Host RainLoop con Accesso Protetto
Per aumentare la sicurezza del servizio nascosto e impedire l’identificazione immediata come Webmail, è stata applicata una protezione HTTP Basic su tutto il sito. L’accesso sarà consentito solo agli utenti ai quali verranno fornite direttamente le credenziali generate tramite htpasswd
, consentendo loro di utilizzare sia la Webmail sia il pannello di amministrazione.

Esempio completo di file /etc/nginx/sites-available/rainloop
:
server {
listen 127.0.0.1:80;
server_name stealtcei5vmjc2vyn7dbfvosdmrq3abox4h2mctomalugujdxjmlzad.onion;
root /var/www/rainloop;
index index.php index.html;
access_log /var/log/nginx/rainloop_access.log;
error_log /var/log/nginx/rainloop_error.log;
# BLOCCA accesso alla cartella /data (importantissimo)
location ~ ^/data {
deny all;
return 403;
}
# Protezione HTTP Basic su tutto il servizio Webmail
location / {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Creazione credenziali di accesso HTTP Basic
Esegui lo script per installare i pacchetti richiesti:
sh /root/install_and_lock.sh
Quando compare il prompt:
[*] Inserisci i pacchetti da installare (separati da spazio): apache2-utils
inserisci apache2-utils
e premi INVIO.
Poi continua con:
htpasswd -c /etc/nginx/.htpasswd adminpanel
Quando richiesto, scegli una password complessa e sicura
Verifica e ricarica configurazione
nginx -t && systemctl reload nginx
🔐 3. Fail2Ban e Protezioni Antibruteforce
Fail2Ban è una protezione aggiuntiva che monitora i log e blocca IP sospetti in caso di tentativi di accesso falliti.
Considerazioni Specifiche per Hidden Services Tor
- Nginx su Hidden Service non è protetto efficacemente da Fail2Ban: tutto il traffico arriva come
127.0.0.1
(localhost) tramite Tor, quindi Fail2Ban non può distinguere i veri IP degli attaccanti. - Protezione utile invece su:
- SSH: contro tentativi di brute force provenienti dalla LAN o tramite errori di configurazione.
- Postfix (SMTP): per proteggere l’autenticazione SMTP.
- Dovecot (IMAP/IMAPS): per difendere gli accessi alle caselle di posta.
Installazione Sicura di Fail2Ban e Pacchetti Multipli
Per evitare problemi dovuti al firewall restrittivo durante l’installazione di pacchetti, utilizzare uno script che sblocca temporaneamente le porte necessarie:
Crea /root/install_and_lock.sh
:
#!/bin/bash
# Script per installare pacchetti temporaneamente sbloccando il firewall
# Sblocca porte necessarie
echo "[*] Sblocco temporaneo delle porte 53, 80 e 443 in uscita..."
ufw allow out to any port 53 proto udp
ufw allow out to any port 80 proto tcp
ufw allow out to any port 443 proto tcp
# Chiede quali pacchetti installare
read -p "[*] Inserisci i pacchetti da installare (separati da spazio): " PACKAGES
# Esegue l'installazione
apt update -o Acquire::ForceIPv4=true
apt install -y $PACKAGES
INSTALL_STATUS=$?
# Ripristina le regole firewall
echo "[*] Ripristino delle regole firewall..."
ufw delete allow out to any port 53 proto udp
ufw delete allow out to any port 80 proto tcp
ufw delete allow out to any port 443 proto tcp
if [ $INSTALL_STATUS -eq 0 ]; then
echo "[+] Installazione completata con successo."
else
echo "[!] Errore durante l'installazione."
fi
echo "[+] Firewall ripristinato. Stato attuale delle regole:"
ufw status numbered
exit $INSTALL_STATUS
Rendi eseguibile:
chmod +x /root/install_and_lock.sh
Per installare più pacchetti:
/root/install_and_lock.sh
(esempio: fail2ban wget curl
)
Configurazione Base Fail2Ban
Modifica /etc/fail2ban/jail.conf
backend = systemd
Crea /etc/fail2ban/jail.local
:
[sshd]
enabled = true
port = ssh
logpath = /var/log/auth.log
maxretry = 3
findtime = 3600
bantime = 86400
banaction = ufw
[postfix]
enabled = true
port = smtp,ssmtp,submission
filter = postfix
logpath = /var/log/mail.log
maxretry = 3
findtime = 3600
bantime = 86400
banaction = ufw
[dovecot]
enabled = true
port = imap,imaps,submission,465,smtps
filter = dovecot
logpath = /var/log/mail.log
maxretry = 3
findtime = 3600
bantime = 86400
banaction = ufw
Riavvia e verifica Fail2Ban
systemctl restart fail2ban
systemctl status fail2ban
fail2ban-client status sshd
fail2ban-client status postfix
fail2ban-client status dovecot
Visualizza IP bannati:
fail2ban-client get sshd banned
fail2ban-client get postfix banned
fail2ban-client get dovecot banned
Sblocca un IP manualmente:
fail2ban-client set sshd unbanip IP_DA_SBLOCCARE
fail2ban-client set postfix unbanip IP_DA_SBLOCCARE
fail2ban-client set dovecot unbanip IP_DA_SBLOCCARE
✅ 4. Cifratura e Sicurezza TLS
La cifratura TLS è fondamentale anche in ambienti Tor-based, per proteggere la comunicazione tra client e server mail. Anche se la rete è anonima, TLS aggiunge un ulteriore strato di sicurezza e compatibilità con i client come Thunderbird.
Certificati TLS Autofirmati
Per ambienti Tor privati si utilizzano certificati TLS autofirmati.
Generazione con OpenSSL:
openssl req -x509 -nodes -days 3650 \
-newkey rsa:4096 \
-keyout /etc/ssl/private/stealthmail.key \
-out /etc/ssl/certs/stealthmail.crt \
-subj "/CN=stealthmail.onion"
chmod 600 /etc/ssl/private/stealthmail.key
Integrazione in Postfix (STARTTLS)
Modifica completa di /etc/postfix/main.cf
:
smtpd_banner = ESMTP (Debian/GNU)
biff = no
append_dot_mydomain = no
readme_directory = no
compatibility_level = 3.6
# TLS settings
smtpd_tls_cert_file = /etc/ssl/certs/stealthmail.crt
smtpd_tls_key_file = /etc/ssl/private/stealthmail.key
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_tls_security_level = may
smtpd_tls_protocols = !SSLv2 !SSLv3 !TLSv1 !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2 !SSLv3 !TLSv1 !TLSv1.1
smtpd_tls_ciphers = high
smtpd_tls_mandatory_ciphers = high
smtp_tls_CApath = /etc/ssl/certs
smtp_tls_security_level = may
smtp_tls_session_cache_database = btree:/smtp_scache
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = StealthMail
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = localhost, stealtcei5vmjc2vyn7dbfvosdmrq3abox4h2mctomalugujdxjmlzad.onion
home_mailbox = Maildir/
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = loopback-only
inet_protocols = all
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_sasl_authenticated, reject_unauth_destination
disable_dns_lookups = yes
transport_maps = hash:/etc/postfix/transport
Modifica completa di /etc/postfix/master.cf
:
smtp inet n - y - - smtpd
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
pickup unix n - y 60 1 pickup
cleanup unix n - y - 0 cleanup
qmgr unix n - n 300 1 qmgr
tlsmgr unix - - y 1000? 1 tlsmgr
rewrite unix - - y - - trivial-rewrite
bounce unix - - y - 0 bounce
defer unix - - y - 0 bounce
trace unix - - y - 0 bounce
verify unix - - y - 1 verify
flush unix n - y 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - y - - smtp
relay unix - - y - - smtp
-o syslog_name=postfix/
showq unix n - y - - showq
error unix - - y - - error
retry unix - - y - - error
discard unix - - y - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - y - - lmtp
anvil unix - - y - 1 anvil
scache unix - - y - 1 scache
postlog unix-dgram n - n - 1 postlogd
maildrop unix - n n - - pipe
uucp unix - n n - - pipe
ifmail unix - n n - - pipe
bsmtp unix - n n - - pipe
scalemail-backend unix - n n - 2 pipe
mailman unix - n n - - pipe
smtpd pass - - n - - smtpd
-o smtpd_sasl_auth_enable=yes
Riavvia Postfix:
systemctl restart postfix
🔵 Nota: Su server di produzione si consiglia l’uso del comando postconf
per apportare modifiche sicure e verificabili ai parametri di Postfix.
Integrazione in Dovecot (IMAPS)
Modifica completa di /etc/dovecot/conf.d/10-ssl.conf
:
##
## SSL settings
##
# SSL/TLS support
ssl = required
# Certificato TLS autofirmato per Dovecot
ssl_cert = </etc/ssl/certs/stealthmail.crt
ssl_key = </etc/ssl/private/stealthmail.key
# Protocollo minimo accettato: TLSv1.2
ssl_min_protocol = TLSv1.2
# Ciphersuite sicura: solo algoritmi robusti
ssl_cipher_list = HIGH:!aNULL:!MD5
# Directory certificati CA di sistema
ssl_client_ca_dir = /etc/ssl/certs
# Parametri Diffie-Hellman sicuri
ssl_dh = </usr/share/dovecot/dh.pem
Riavvia Dovecot:
systemctl restart dovecot
Verifica TLS
Dopo il riavvio dei servizi, è consigliabile testare la configurazione TLS:
# Test di connessione TLS Postfix (SMTP Submission)
openssl s_client -connect 127.0.0.1:587 -starttls smtp
# Test di connessione TLS Dovecot (IMAPS)
openssl s_client -connect 127.0.0.1:993
🛡️ Conclusione
Nella Parte 3 della guida affronteremo la gestione operativa del server: backup automatici, monitoraggio avanzato dei log, hardening del sistema operativo e configurazione sicura di client come Thunderbird per l’accesso protetto alla Webmail e alla posta tramite rete Tor.