Vai al contenuto
Home » 🧭 Howto – Guide Tecniche per Tor, Privacy e Sicurezza » 📧 Mail Server Tor: Postfix, Dovecot, Nginx su Hidden Service » 🔒 Mail Server su Tor: Hardening UFW, Fail2Ban e TLS – Parte 2

🔒 Mail Server su Tor: Hardening UFW, Fail2Ban e TLS – Parte 2

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.