Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dovecot with virtual hosts and SSL - wrong certificate?

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
}
like image 660
3und80 Avatar asked May 05 '14 15:05

3und80


1 Answers

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.

like image 70
jww Avatar answered Oct 30 '22 21:10

jww