Postfix Dovecot MySQL su Ubuntu 22.04
Introduzione
Questa guida vi accompagnerà passo dopo passo nella configurazione di un mail server completo e sicuro utilizzando Postfix (SMTP), Dovecot (IMAP/POP3), MariaDB (database utenti) e Rspamd (antispam). Il server utilizzerà esclusivamente connessioni crittografate con certificati Let’s Encrypt.
Al termine avrete un server email professionale con:
- Domini e utenti virtuali gestiti via database
- Crittografia TLS obbligatoria per tutte le connessioni
- Filtri antispam avanzati
- Protezione contro attacchi brute-force
- Supporto per filtri Sieve lato server
1. Prerequisiti e Preparazione del Sistema
Requisiti Base
Per questa guida avrete bisogno di:
- Una VPS con IP statico (consiglio Hetzner per affidabilità e prezzi)
- Ubuntu 22.04 LTS installato
- Un dominio registrato con accesso alla configurazione DNS
- Almeno 2GB di RAM (4GB consigliati)
Configurazione DNS
Prima di iniziare, configurate correttamente i record DNS del vostro dominio:
# Record A per il server mail
mail.esempio.com A [IP_VPS]
# Record MX per il dominio
esempio.com MX 10 mail.esempio.com
# Record PTR (reverse DNS) - da configurare nel pannello del provider VPS
[IP_VPS] PTR mail.esempio.com
# Record SPF per autorizzare il server a inviare mail
esempio.com TXT "v=spf1 mx -all"
Importante: Il record PTR deve corrispondere all’hostname del server. Verificate con:
hostname -f
# Deve restituire: mail.esempio.com
Installazione Pacchetti
Aggiorniamo il sistema e installiamo tutti i componenti necessari:
apt update && apt upgrade -y
apt install -y \
mariadb-server \
postfix postfix-pcre postfix-mysql \
dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd \
dovecot-mysql dovecot-sieve dovecot-managesieved \
rspamd redis-server \
certbot \
pwgen \
fail2ban \
ufw
Durante l’installazione di Postfix, selezionate “Internet Site” e inserite il vostro dominio (esempio.com).
2. Certificati SSL/TLS con Let’s Encrypt
Generiamo subito i certificati SSL che proteggeranno tutte le comunicazioni:
# Fermiamo temporaneamente i servizi che usano la porta 80
systemctl stop apache2 nginx
# Generiamo il certificato con chiave RSA 4096 bit
certbot certonly --standalone --rsa-key-size 4096 -d mail.esempio.com
# Configuriamo il rinnovo automatico con riavvio servizi
cat > /etc/letsencrypt/cli.ini << EOF
post-hook = systemctl restart postfix dovecot
EOF
3. Configurazione Database MariaDB
Sicurezza Database
Prima di tutto, mettiamo in sicurezza MariaDB:
mysql_secure_installation
# Rispondete:
# - Set root password? [Y]
# - Remove anonymous users? [Y]
# - Disallow root login remotely? [Y]
# - Remove test database? [Y]
# - Reload privilege tables? [Y]
Creazione Database e Utente
Generiamo una password sicura per l'utente del database:
# Genera password di 30 caratteri
pwgen -s1 30
# Esempio output: rEfsoI2KSejLEHmDNvAYnVEHr8o1ig
Ora creiamo il database e le tabelle:
mysql -u root -p
-- Creazione database e utente
CREATE DATABASE mailserver;
CREATE USER 'mailuser'@'localhost' IDENTIFIED BY 'rEfsoI2KSejLEHmDNvAYnVEHr8o1ig';
GRANT ALL PRIVILEGES ON mailserver.* TO 'mailuser'@'localhost';
FLUSH PRIVILEGES;
USE mailserver;
-- Tabella domini
CREATE TABLE IF NOT EXISTS `virtual_domains` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Tabella utenti
CREATE TABLE IF NOT EXISTS `virtual_users` (
`id` int(11) NOT NULL auto_increment,
`domain_id` int(11) NOT NULL,
`email` varchar(100) NOT NULL,
`password` varchar(150) NOT NULL,
`quota` bigint(20) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Tabella alias
CREATE TABLE IF NOT EXISTS `virtual_aliases` (
`id` int(11) NOT NULL auto_increment,
`domain_id` int(11) NOT NULL,
`source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
EXIT;
Aggiunta Domini e Utenti
Per aggiungere un dominio e un utente, prima generiamo una password criptata:
# Genera password utente
pwgen -s1 20
# Esempio: xK9mNp2Lq8Rt5Yw3Zb7
# Cripta la password con SHA256
doveadm pw -s SHA256-CRYPT
# Inserite la password quando richiesto
# Output esempio: {SHA256-CRYPT}$5$xvxyx8xOf5MSGsK.$zEBRszEg...
Ora aggiungiamo dominio e utente al database:
mysql -u root -p mailserver
-- Aggiungi dominio
INSERT INTO virtual_domains (name) VALUES ('esempio.com');
-- Aggiungi utente (usa l'hash generato sopra)
INSERT INTO virtual_users (domain_id, email, password)
VALUES (1, 'info@esempio.com', '{SHA256-CRYPT}$5$xvxyx8xOf5MSGsK.$zEBRszEg...');
-- Aggiungi alias
INSERT INTO virtual_aliases (domain_id, source, destination)
VALUES (1, 'postmaster@esempio.com', 'info@esempio.com');
EXIT;
4. Configurazione Postfix
File di Mapping MySQL
Creiamo i file che permettono a Postfix di interrogare il database:
# File: /etc/postfix/mysql-virtual-mailbox-domains.cf
cat > /etc/postfix/mysql-virtual-mailbox-domains.cf << EOF
user = mailuser
password = rEfsoI2KSejLEHmDNvAYnVEHr8o1ig
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'
EOF
# File: /etc/postfix/mysql-virtual-mailbox-maps.cf
cat > /etc/postfix/mysql-virtual-mailbox-maps.cf << EOF
user = mailuser
password = rEfsoI2KSejLEHmDNvAYnVEHr8o1ig
hosts = 127.0.0.1
dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s'
EOF
# File: /etc/postfix/mysql-virtual-alias-maps.cf
cat > /etc/postfix/mysql-virtual-alias-maps.cf << EOF
user = mailuser
password = rEfsoI2KSejLEHmDNvAYnVEHr8o1ig
hosts = 127.0.0.1
dbname = mailserver
query = SELECT destination FROM virtual_aliases WHERE source='%s'
EOF
# Impostiamo i permessi corretti
chmod 640 /etc/postfix/mysql-*.cf
chown root:postfix /etc/postfix/mysql-*.cf
Configurazione main.cf
Configuriamo Postfix modificando il file principale:
# Backup del file originale
cp /etc/postfix/main.cf /etc/postfix/main.cf.backup
# Configurazione base
postconf -e "myhostname = mail.esempio.com"
postconf -e "mydomain = esempio.com"
postconf -e "myorigin = \$mydomain"
postconf -e "mydestination = localhost"
postconf -e "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128"
# Domini e mailbox virtuali
postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp"
postconf -e "virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf"
postconf -e "virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf"
postconf -e "virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf"
# Autenticazione SASL via Dovecot
postconf -e "smtpd_sasl_type = dovecot"
postconf -e "smtpd_sasl_path = private/auth"
postconf -e "smtpd_sasl_auth_enable = yes"
postconf -e "broken_sasl_auth_clients = yes"
# TLS/SSL
postconf -e "smtpd_tls_cert_file = /etc/letsencrypt/live/mail.esempio.com/fullchain.pem"
postconf -e "smtpd_tls_key_file = /etc/letsencrypt/live/mail.esempio.com/privkey.pem"
postconf -e "smtpd_tls_security_level = may"
postconf -e "smtpd_tls_auth_only = yes"
postconf -e "smtp_tls_security_level = may"
postconf -e "smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1"
postconf -e "smtpd_tls_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1"
postconf -e "smtpd_tls_mandatory_ciphers = high"
postconf -e "tls_high_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305"
# Restrizioni
postconf -e "smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination"
postconf -e "smtpd_relay_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination"
# Limiti
postconf -e "message_size_limit = 52428800"
postconf -e "mailbox_size_limit = 0"
Configurazione master.cf
Abilitiamo la submission port (587) per l'invio autenticato:
# Modifichiamo /etc/postfix/master.cf
# Decommentiamo e modifichiamo le seguenti righe:
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_tls_auth_only=yes
-o smtpd_reject_unlisted_recipient=no
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
Creazione Utente e Directory Mail
# Creiamo utente e gruppo per le mailbox virtuali
groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/vmail -m
chown -R vmail:vmail /var/vmail
Configurazione Autenticazione
Modifichiamo /etc/dovecot/conf.d/10-auth.conf:
# Meccanismi di autenticazione
auth_mechanisms = plain login
# Disabilita autenticazione in chiaro senza TLS
disable_plaintext_auth = yes
# Commenta la riga auth-system e decommenta auth-sql
#!include auth-system.conf.ext
!include auth-sql.conf.ext
Configurazione SQL
Creiamo /etc/dovecot/dovecot-sql.conf.ext:
driver = mysql
connect = host=127.0.0.1 dbname=mailserver user=mailuser password=rEfsoI2KSejLEHmDNvAYnVEHr8o1ig
default_pass_scheme = SHA256-CRYPT
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u'
user_query = SELECT email as user, \
'vmail' as uid, 'vmail' as gid, \
'/var/vmail/%d/%n' as home, \
'*:storage=1G' as quota_rule \
FROM virtual_users WHERE email='%u'
iterate_query = SELECT email AS user FROM virtual_users
Configurazione Mail Location
Modifichiamo /etc/dovecot/conf.d/10-mail.conf:
mail_location = maildir:~/Maildir
mail_uid = vmail
mail_gid = vmail
first_valid_uid = 5000
last_valid_uid = 5000
Configurazione SSL
Modifichiamo /etc/dovecot/conf.d/10-ssl.conf:
ssl = required
ssl_cert =
Configurazione Master Services
Modifichiamo /etc/dovecot/conf.d/10-master.conf:
service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}
}
service pop3-login {
inet_listener pop3 {
port = 0 # Disabilitato
}
inet_listener pop3s {
port = 0 # Disabilitato
}
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
unix_listener auth-userdb {
mode = 0600
user = vmail
}
}
service auth-worker {
user = vmail
}
Abilitazione Sieve
Modifichiamo /etc/dovecot/conf.d/20-lmtp.conf:
protocol lmtp {
mail_plugins = $mail_plugins sieve
}
E /etc/dovecot/conf.d/90-sieve.conf:
plugin {
sieve = file:~/sieve;active=~/.dovecot.sieve
sieve_global_path = /var/vmail/sieve/default.sieve
sieve_dir = ~/sieve
sieve_max_script_size = 1M
}
6. Configurazione Rspamd (Antispam)
Rspamd è un sistema antispam avanzato che proteggerà il server da spam e malware.
Configurazione Base
# Configuriamo rspamd per integrarsi con Postfix
cat > /etc/rspamd/local.d/worker-controller.inc << EOF
password = "\$2\$zy8npwwgqbpgo5ujnug6of3zy3rgpbmj\$k6mmm9xe3jugxr1bii4o5gxjfhqjjh4pg3iyhka4rq3479bjqzny";
enable_password = "\$2\$zy8npwwgqbpgo5ujnug6of3zy3rgpbmj\$k6mmm9xe3jugxr1bii4o5gxjfhqjjh4pg3iyhka4rq3479bjqzny";
EOF
# Configurazione milter
cat > /etc/rspamd/local.d/worker-proxy.inc << EOF
bind_socket = "127.0.0.1:11332";
milter = yes;
timeout = 120s;
upstream "local" {
default = yes;
self_scan = yes;
}
EOF
# Aggiungiamo rspamd a Postfix
postconf -e "smtpd_milters = inet:127.0.0.1:11332"
postconf -e "non_smtpd_milters = inet:127.0.0.1:11332"
postconf -e "milter_default_action = accept"
# Riavviamo rspamd
systemctl restart rspamd
DKIM Signing
# Generiamo chiave DKIM
mkdir -p /var/lib/rspamd/dkim/
rspamadm dkim_keygen -b 2048 -s mail -k /var/lib/rspamd/dkim/mail.key > /var/lib/rspamd/dkim/mail.txt
chown -R _rspamd:_rspamd /var/lib/rspamd/dkim
# Configuriamo DKIM
cat > /etc/rspamd/local.d/dkim_signing.conf << EOF
selector = "mail";
path = "/var/lib/rspamd/dkim/\$selector.key";
allow_username_mismatch = true;
EOF
# Il record DNS DKIM da aggiungere si trova in:
cat /var/lib/rspamd/dkim/mail.txt
7. Configurazione Fail2ban
Proteggiamo il server da attacchi brute-force:
# Creiamo jail per Postfix
cat > /etc/fail2ban/jail.d/postfix.conf << EOF
[postfix-sasl]
enabled = true
filter = postfix-sasl
action = iptables-multiport[name=postfix-sasl, port="25,587,465", protocol=tcp]
logpath = /var/log/mail.log
maxretry = 3
bantime = 3600
EOF
# Jail per Dovecot
cat > /etc/fail2ban/jail.d/dovecot.conf << EOF
[dovecot]
enabled = true
filter = dovecot
action = iptables-multiport[name=dovecot, port="143,993,110,995", protocol=tcp]
logpath = /var/log/mail.log
maxretry = 3
bantime = 3600
EOF
# Riavviamo fail2ban
systemctl restart fail2ban
8. Configurazione Firewall
# Configuriamo UFW
ufw allow 22/tcp # SSH
ufw allow 25/tcp # SMTP
ufw allow 587/tcp # Submission
ufw allow 143/tcp # IMAP
ufw allow 993/tcp # IMAPS
ufw allow 80/tcp # HTTP (per Let's Encrypt)
ufw allow 443/tcp # HTTPS
# Abilitiamo il firewall
ufw enable
9. Test e Verifica
Test Database
# Test mapping Postfix
postmap -q esempio.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
# Output atteso: 1
postmap -q info@esempio.com mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
# Output atteso: 1
postmap -q postmaster@esempio.com mysql:/etc/postfix/mysql-virtual-alias-maps.cf
# Output atteso: info@esempio.com
Test Servizi
# Verifica configurazione Postfix
postfix check
# Verifica configurazione Dovecot
dovecot -n
# Test connessione SMTP
telnet localhost 25
EHLO test
# Dovrebbe mostrare STARTTLS e AUTH
# Test IMAP
telnet localhost 143
a1 LOGIN info@esempio.com password
# Dovrebbe autenticarsi correttamente
Test SSL/TLS
# Test certificato SMTP
openssl s_client -connect mail.esempio.com:587 -starttls smtp
# Test certificato IMAP
openssl s_client -connect mail.esempio.com:993
Per configurare un client email (Thunderbird, Outlook, etc.), usate questi parametri:
- Server IMAP: mail.esempio.com, Porta 993, SSL/TLS
- Server SMTP: mail.esempio.com, Porta 587, STARTTLS
- Username: indirizzo email completo (info@esempio.com)
- Password: la password dell'utente
- Autenticazione: Password normale
11. Manutenzione e Monitoraggio
Log Files
I log principali da monitorare:
# Log mail generale
tail -f /var/log/mail.log
# Log errori
tail -f /var/log/mail.err
# Log rspamd
tail -f /var/log/rspamd/rspamd.log
# Statistiche rspamd
rspamc stat
Backup
# Script backup database
#!/bin/bash
mysqldump mailserver > /backup/mailserver-$(date +%Y%m%d).sql
# Backup mailbox
rsync -av /var/vmail/ /backup/vmail/
# Backup configurazioni
tar czf /backup/mail-config-$(date +%Y%m%d).tar.gz \
/etc/postfix /etc/dovecot /etc/rspamd
Aggiornamenti
# Aggiornamento sicuro del sistema
apt update
apt upgrade -y
systemctl restart postfix dovecot rspamd
Risoluzione Problemi Comuni
Errore "Relay access denied"
Verificate che l'utente sia autenticato e che il dominio sia configurato correttamente nel database.
Certificati non funzionanti
Verificate i permessi e i percorsi dei certificati. Dovecot necessita del carattere < prima del percorso.
Mail in spam
Assicuratevi di aver configurato correttamente SPF, DKIM e DMARC. Verificate anche il PTR record.
Conclusioni
Ora avete un mail server completo e sicuro. Ricordate di:
- Monitorare regolarmente i log
- Mantenere il sistema aggiornato
- Fare backup regolari
- Testare periodicamente la deliverability
- Aggiornare i certificati SSL prima della scadenza
Per ulteriore sicurezza, considerate l'implementazione di SPF, DKIM e DMARC record DNS completi per migliorare la reputazione del vostro server.