7

After implementing certificate authentication on Nginx web server, I would like to do the same on Dovecot mail server. The idea is to create your own CA and manage certificates (both issuing and revoking). To verify the client certificate you need your root CA certificate and the CRL. In order to establish a secure connection, a certificate signed by a true CA can be used (if you don't want to import your own root CA certificate on every workstation).

So far, I have read these pages from the Dovecot official wiki:

  1. http://wiki2.dovecot.org/SSL
  2. http://wiki2.dovecot.org/SSL/DovecotConfiguration

Which have got me to this configuration file:

listen = *,[::]
protocols = imap pop3
auth_mechanisms = plain login
disable_plaintext_auth = no
log_timestamp = "%Y-%m-%d %H:%M:%S "
mail_privileged_group = vmail
ssl = required
ssl_cert = </etc/postfix/smtpd.cert
ssl_key = </etc/postfix/smtpd.key
ssl_ca = </etc/postfix/ca.pem
ssl_cert_username_field = emailAddress
ssl_verify_client_cert = yes
ssl_require_crl = yes
auth_ssl_require_client_cert = yes
ssl_username_from_cert = yes
passdb {
  args = /etc/dovecot/dovecot-sql.conf
  driver = sql
}
userdb {
  args = /etc/dovecot/dovecot-sql.conf
  driver = sql
}
plugin {
  quota = dict:user::file:/var/vmail/%d/%n/.quotausage
  sieve=/var/vmail/%d/%n/.sieve
}
service auth {
  unix_listener /var/spool/postfix/private/auth {
    group = postfix
    mode = 0660
    user = postfix
  }
  unix_listener auth-userdb {
    group = vmail
    mode = 0600
    user = vmail
  }
  user = root
}
service imap-login {
  client_limit = 1000
  process_limit = 500
}
protocol imap {
  mail_plugins = quota imap_quota
}
protocol pop3 {
  pop3_uidl_format = %08Xu%08Xv
  mail_plugins = quota
}
protocol lda {
  mail_plugins = sieve quota
}

The ca.pem, which is used to validate client certificates, is formatted according to the second link above and contains the root CA certificate and the CRL, both in PEM format. Also the certificate and key pair used to establish the secure connection are in PEM format (even though the extensions are .cert and .key).

The settings mentioned in the second link above: ssl_username_from_cert = yes (which is used in combination with ssl_cert_username_field (which defaults to commonName) yields an error:

doveconf: Fatal: Error in configuration file /etc/dovecot/dovecot.conf line 15: Unknown setting: ssl_username_from_cert
[....] Restarting IMAP/POP3 mail server: dovecotdoveconf: Fatal: Error in configuration file /etc/dovecot/dovecot.conf line 15: Unknown setting: ssl_username_from_cert
failed!

Commenting out that option and restarting Dovecot, I get no configuration errors, but it's not working. A shell test results in:

openssl s_client -connect mail.example.com:imaps
CONNECTED(00000003)

That's all.

If I comment out all the lines referring to the certificate authentication (all the line beginning with ssl, except ssl, ssl_cert and ssl_key pair, those are used to allow only secured SSL/TLS connections), it works, but I get not certificate authentication.

Searches on Google result in implementing secured SSL/TLS connections (which I have done so far). This guide, which explains exactly what I want to do, isn't finished. Right at the Dovecot configuration file, it has a ToDo list.

I'm running version 2.1.7 of Dovecot on an Linux Debian 7 (Wheezy) - currently the Debian stable version.

Any help is appreciated.

Note: I want to implement this only for the IMAP protocol.

EDIT 1:

If you notice something wrong (bad practice, insecure), please leave a comment!

After changing ssl_username_from_cert with auth_ssl_username_from_cert and restarting Dovecot, everything seems to work well.

openssl s_client -connect mail.example.com:imaps
CONNECTED(00000003)
depth=0 description = XXXXXXXXXXXXXXXX, C = XX, CN = mail.example.com, emailAddress = postmaster@example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 description = XXXXXXXXXXXXXXXX, C = XX, CN = mail.example.com, emailAddress = postmaster@example.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 description = XXXXXXXXXXXXXXXX, C = XX, CN = mail.example.com, emailAddress = postmaster@example.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/description=XXXXXXXXXXXXXXXX/C=XX/CN=mail.example.com/emailAddress=postmaster@example.com
   i:/C=XX/O=Company Ltd./OU=Some High Security Name/CN=Certificate Class
---
Server certificate
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXX
-----END CERTIFICATE-----
subject=/description=XXXXXXXXXXXXXXXX/C=XX/CN=mail.example.com/emailAddress=postmaster@example.com
issuer=/C=XX/O=Company Ltd./OU=Some High Security Name/CN=Certificate Class
---
Acceptable client certificate CA names
/C=XX/ST=Some-State/O=Another Company Ltd.
---
SSL handshake has read 3107 bytes and written 519 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: zlib compression
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : DHE-RSA-AES256-GCM-SHA384
    Session-ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Session-ID-ctx: 
    Master-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - XX XX XX XX XX XX XX XX-XX XX XX XX XX XX XX XX   XXXXXXXXXXXXXXXX
    0010 - XX XX XX XX XX XX XX XX-XX XX XX XX XX XX XX XX   XXXXXXXXXXXXXXXX
    0020 - XX XX XX XX XX XX XX XX-XX XX XX XX XX XX XX XX   XXXXXXXXXXXXXXXX
    0030 - XX XX XX XX XX XX XX XX-XX XX XX XX XX XX XX XX   XXXXXXXXXXXXXXXX
    0040 - XX XX XX XX XX XX XX XX-XX XX XX XX XX XX XX XX   XXXXXXXXXXXXXXXX
    0050 - XX XX XX XX XX XX XX XX-XX XX XX XX XX XX XX XX   XXXXXXXXXXXXXXXX
    0060 - XX XX XX XX XX XX XX XX-XX XX XX XX XX XX XX XX   XXXXXXXXXXXXXXXX
    0070 - XX XX XX XX XX XX XX XX-XX XX XX XX XX XX XX XX   XXXXXXXXXXXXXXXX
    0080 - XX XX XX XX XX XX XX XX-XX XX XX XX XX XX XX XX   XXXXXXXXXXXXXXXX
    0090 - XX XX XX XX XX XX XX XX-XX XX XX XX XX XX XX XX   XXXXXXXXXXXXXXXX

    Compression: 1 (zlib compression)
    Start Time: 1409206799
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN] Dovecot ready.

and

doveconf -a | grep ssl
auth_ssl_require_client_cert = yes
auth_ssl_username_from_cert = yes
imapc_ssl = no
imapc_ssl_ca_dir = 
imapc_ssl_verify = yes
pop3c_ssl = no
pop3c_ssl_ca_dir = 
pop3c_ssl_verify = yes
    ssl = no
    ssl = yes
    ssl = no
    ssl = yes
service ssl-params {
  executable = ssl-params
  unix_listener login/ssl-params {
ssl = required
ssl_ca = </etc/postfix/ca.pem
ssl_cert = </etc/postfix/smtpd.cert
ssl_cert_username_field = emailAddress
ssl_cipher_list = ALL:!LOW:!SSLv2:!EXP:!aNULL
ssl_client_cert = 
ssl_client_key = 
ssl_crypto_device = 
ssl_key = </etc/postfix/smtpd.key
ssl_key_password = 
ssl_parameters_regenerate = 1 weeks
ssl_protocols = !SSLv2
ssl_require_crl = yes
ssl_verify_client_cert = yes
verbose_ssl = no

Time to try it out. I imported a user certificate into Thunderbird and set Authentication method: TLS Certificate. But when I try to connect, I get the following error message:

The IMAP Server user@example.com does not support the selected authentication method. Please change the 'Authentication method' in the 'Account Settings | Server Settings'.

Note: The password authentication works (of course over TLS secured connection).

We're close.

Daniel Iancu
  • 171
  • 1
  • 5

2 Answers2

5

The Dovecot wiki seems to have an error, or maybe the name of the ssl_username_from_cert setting has changed. On my Ubuntu host with Dovecot 2.2.9, in /etc/dovecot/conf.d/10-auth.conf, I have:

# Take the username from client's SSL certificate, using 
# X509_NAME_get_text_by_NID() which returns the subject's DN's
# CommonName. 
#auth_ssl_username_from_cert = no

So it seems that you need to replace ssl_username_from_cert by auth_ssl_username_from_cert, and the wiki needs to be corrected.

Andrew Schulman
  • 8,561
  • 21
  • 31
  • 47
  • 2
    Good start point is the `doveconf -a | grep ssl` that show actual names of configuration parameters. – Kondybas Aug 27 '14 at 09:04
  • Good point @Kondybas. I also tried to change the Dovecot Wiki, but I couldn't get pass the spam test. I sent an email to the mentioned address, but I haven't received anything back. – Daniel Iancu Aug 28 '14 at 20:31
  • 1
    Same problem here about the spam test. – Andrew Schulman Aug 28 '14 at 22:44
  • 1
    The dovecot wiki spam test is a text box: "I'm tired of too too much wiki spam. How do you definitely get rid of them?" which pops up if you try to edit the Dovecot MoinMoin based wiki. In the empty field next to the question simply enter the word "moderate" which should allow you to edit the wiki. – jeremiah May 25 '15 at 19:26
2

I had exactly the same problem.

I managed to get this working after reading though the specifications and examining rawlog output.

You need to enable external authentication method by listing it in the value of the auth_mechanisms variable.

S: * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE STARTTLS LOGINDISABLED] Dovecot ready.
C: 1 STARTTLS
S: 1 OK Begin TLS negotiation now.
C: 2 capability
S: CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=EXTERNAL
S: 2 OK Pre-login capabilities listed, post-login capabilities have more.

If Dovecot does not respond with an AUTH=EXTERNAL capability (either inside the greeting when over IMAPS port or after CAPABILITY request from the client as shown above), Thunderbird will shut down the connection and give you an error message that the server does not support logging with a certificate.

Otherwise, it proceeds with the authentication.

C: 3 authenticate EXTERNAL bm9ib2R5QGV4YW1wbGUuY29t

Also, be sure to include the username in the user database.

Yumiko
  • 21
  • 3