Server Name Indication (SNI) per qmail e dovecot

18 marzo 2026 by Roberto Puzzanghera 0 commenti

Server Name Indication (SNI) è una estensione del protocollo TLS che consente a un server di presentare differenti certificati a seconda dell'hostname richiesto dal client durante il saluto TLS.

In un ambiente email moderno, molti domini condividono uno stesso indirizzo IP per i servizi SMTP, IMAP, POP3 e submission. Senza SNI, un amministratore di un server email può presentare un solo certificato per ogni socket disponibile, cosa che obbliga l'aministratore ad affidarsi a certificati multi-dominio (SAN) o a certificati con wildcard. Questo approccio aumenta i problemi operativi tra gli utenti finali novelli, che spesso non sono in grado di usare la configurazione automatica del client per configurare correttamente le loro mailbox.

L'abilitazione di SNI nei serivizi mail consente al server di presentare il certificato appropriato basato sull'hostname richiesto dal client, contenuto nel suo indirizzo email.

La funzionalità SNI per la mia distribuzione qmail è stata aggiunta da Andreas Gerstlauer (commit qui e qui), che vorrei ringraziare.

Creazione dei certificati

Supponiamo di voler creare certificati differenti per domain1.tld e per domain2.tld. Usiamo dehydrated per creare i due certificati. Modificare /etc/dehydrated/domains.txt in questo modo:

domain1.tld imap.domain1.tld pop3.domain1.tld smtp.domain1.tld
domain2.tld imap.domain2.tld pop3.domain2.tld smtp.domain2.tld

Come sappiamo, non appena si lancia il comando dehydrated -c, uno specifico certificato viene costruito per ciascuna rige in domains.txt. Il nome di ciascun certificato corrisponde al primo dominio della riga, mentre gli altri domini di quella riga sono nomi alternativi (SAN) per lo stesso certificato. E' necessario mettere lì tutti domini che le procedure automatiche dei client di posta cercheranno di immaginare metre si configura la mailbox. Per esempio, se si sta configurando roberto@sagredo.eu, la procedura automatizzata probabilmente controllerà l'esistenza di smtp.sagredo.eu per il server SMTPimap.sagredo.eu per l'IMAP.

In qmail, quando il client supporta SNI, i certificati SSL di domini specifici devono essere impostati nel seguente modo:

QMAILDIR/control/servercerts/<FQDN>/servercert.pem

Ho modificato lo script hook.sh per dehydrated al fine di salvare il primo certificato (prima riga in domains.txt) in

QMAILDIR/control/servercert.pem

e tutti gli altri certificati, a partire dalla riga due, in

QMAILDIR/control/servercerts/<FQDN>/servercert.pem

QMAILDIR/control/servercert.pem è usato come default, nel caso non possa essere trovato nel server un certificato appropriato per l'hostname richiesto.

Nel nostro esempio è necessario preparare i seguenti certificati:

QMAILDIR/control/servercert/servercert.pem
QMAILDIR/control/servercerts/domain2.tld/servercert.pem

Riguardo a dovecot, è necessario dichiarare i certificati addizionali per SNI nel modo seguente:

local_name domain2.tld { 
 ssl_server_cert_file = /etc/dehydrated/certs/domain2.tld/fullchain.pem 
 ssl_server_key_file  = /etc/dehydrated/certs/domain2.tld/privkey.pem 
} 
local_name *.domain2.tld { 
 ssl_server_cert_file = /etc/dehydrated/certs/test.sagredo.eu/fullchain.pem 
 ssl_server_key_file  = /etc/dehydrated/certs/test.sagredo.eu/privkey.pem 
}

Queste impostazioni per dovecot vengono aggiunte in automatico dallo script hook.sh.

Test dei certificati

Per testare SNI con openssl è necessario passare l'opzione -servername.

openssl s_client -starttls smtp -connect serverIP:587 -servername domain2.tld 2>/dev/null | grep subject=CN

In pratica, ci stiamo connettendo all'IP del mail server e richiedendo un certificato per il dominio domain2.tld. Se il server non fornisce un certificato per domain2.tld, allora verrà servito quello di default, che è /var/qmail/control/servercert.pem.

Alla fine del certificato abbiamo il Common Name (CN):

subject=CN = domain2.tld

che il FQDN per il quale il certificato è stato rilasciato. Se si ottiene domain2.tld o smtp.domain2.tld o ogni altro dominio avente domain2.tld come dominio di secondo livello, allora SNI sta funzionando bene e il client è in grado di indicare il certificato associato al dominio dal quale si sta connettendo.

Stesso esempio per i protocolli IMAPPOP3:

# openssl s_client -connect serverIP:995 -servername domain2.tld 2>/dev/null | grep subject=CN
subject=CN = domain2.tld

# openssl s_client -connect serverIP:993 -servername domain2.tld 2>/dev/null | grep subject=CN
subject=CN = domain2.tld

Il SAN (Subject Alternative Name) del certificato è la lista dei domini che sono protetti da quel certifcato:

# openssl x509 -in /var/qmail/control/servercert.pem -noout -text | grep -A1 "Subject Alternative Name"     
           X509v3 Subject Alternative Name:  
               DNS:domain1.tld, DNS:smtp.domain1.tld, DNS:imap.domain1.tld, DNS:pop3.domain1.tld,

Si può ottenere il SAN quando ci si connette da remoto nel modo seguente:

openssl s_client -starttls smtp -connect domain1.tld:587 2>/dev/null |
  openssl x509 -noout -text | 
  grep -A1 "Subject Alternative Name"

Aggiungi un commento

qmail notes

Pay me a coffee:

PayPal - The safer, easier way to pay online.

LXC scripts
Other contents
Guide per gli utenti
Ultimi commenti
Vedi anche...
Articoli recenti

RSS feeds