I'm trying to set up Dovecot with multiple vhosts using SSL.
I've set up my main domain (example.de) and for my vhosts (example2.com & example3.co.uk) I'm using the local -option.
My problem:
When I connect to my server, it complains about a wrong hostname (example3.co.uk) on my main and other domain for the certificate.
How can I make dovecot use the correct certificate for each host?
Here's my dovecot config:
listen = *
ssl = yes
protocols = imap pop3
disable_plaintext_auth = no
auth_mechanisms = plain login
mail_access_groups = vmail
default_login_user = vmail
first_valid_uid = 2222
first_valid_gid = 2222
#mail_location = maildir:~/Maildir
mail_location = maildir:/home/vmail/%d/%n
passdb {
driver = passwd-file
args = scheme=SHA1 /etc/dovecot/passwd
}
userdb {
driver = static
args = uid=2222 gid=2222 home=/home/vmail/%d/%n allow_all_users=yes
}
service auth {
unix_listener auth-client {
group = postfix
mode = 0660
user = root
}
user = root
}
service imap-login {
process_min_avail = 1
user = vmail
}
ssl_cert = </etc/pki/tls/certs/example.de.crt
ssl_key = </etc/pki/tls/private/example.de.key
local ohmygodpresents.com {
ssl_cert = </etc/pki/tls/certs/example2.com.crt
ssl_key = </etc/pki/tls/private/example2.com.key
}
local ohmygodpresents.co.uk {
ssl_cert = </etc/pki/tls/certs/example3.co.uk.crt
ssl_key = </etc/pki/tls/private/example3.co.uk.key
}
How can I make dovecot use the correct certificate for each host?
Its not Dovecot per se.
The client needs to use TLS 1.0 or above, and it needs to utilize the Server Name Indication (SNI) extension. Otherwise, Dovecot does not know which virtual server the client is attempting to connect to when the channel is being set up.
You can duplicate/test it with OpenSSL s_client
. For example, a "good" connection:
openssl s_client -tls1 -starttls smtp -connect mail.example.com:587 -servername mail.example.com
In the above example, Dovecot will know to send the certificate for example.com
when the SSL/TLS connection is started. Even though a STARTTLS
extension is used in mail, Dovecot does not know the virtual server because the RCPT
command has not yet been sent. Because the RCPT
command has not been sent, Dovecot does not know the user or his/her domain.
Here's a "bad" connection. Its SSLv3, so it cannot utilize SNI (SNI is a TLS extension):
openssl s_client -ssl3 -starttls smtp -connect mail.example.com:587
Here's another "bad" connection. Its TLS 1.0, but it does not utlize SNI:
openssl s_client -tls1 -starttls smtp -connect mail.example.com:587
You can also duplicate/test/observe with Wireshark. SNI is sent in the plain text as part of the ClientHello
. So you will be able to see protocols, cipher suites, extensions like SNI, and other parameters. Everything in SSL/TLS's handshake and key exchange are plain text (some hand waiving). The plain text messages are integrity checked later when the Finished
messages are sent.
You can disable SSLv2/SSLv3 and force TLS, and things will work as expected for most clients. However, a client does not have to send the SNI extension. Windows XP clients will be a problem - they utilize TLS 1.0 but omit SNI. So there's really no fix other than using a modern client.
Your other option is to create a "super certificate". That is, use a certificates with all the DNS names that the mail server serves. In your case, use one certificate with SANs of DNS:3und80.de
, DNS:ohmygodpresents.co.uk
, DNS:example1.com
, etc. Every time you add a new domain or remove an existing domain, you will have to get a new certificate.