While I was cleaning up my Ubuntu Email server configuration, I consolidated my login security. My SMTP server is Exim and my IMAP server is Dovecot. Mail User Agents (MUAs) use authentication over TLS encrypted connections to access IMAP and SMTP. Both programs had their own password configuration.
Exim includes Dovecot in its supported authentication mechanisms. This enables one authentication mechanism to be used for both SMTP and IMAP (or POP3). This post also includes configuration details for forced authentication over the Submission port.
Configuring Dovecot
The configuration for Dovecot supports the inclusion of directory contents. This makes adding local modifications simpler as the main configuration file does not need to be modified.
I had already enabled TLS in dovecot. Both IMAP and IMAPS are enabled, with plain text passwords being disabled on unsecured connections. Connections from localhost are considered secure. Otherwise, IMAP connections must use STARTTLS before authenticating. The relevant lines from /etc/dovecot/conf.d/local.conf
are:
protocols = imap imaps disable_plaintext_auth = yes ssl_cert_file = /etc/ssl/certs/mail.example.com-cert.pem ssl_key_file = /etc/ssl/private/mail.example.com-key.pem
The main configuration file supports the use of pam for the user database and passwords. On my mail server, most users have their password disabled, so I need to provide a password database. If you are only using pam, you do NOT need to configure a passdb. I also provide for a secondary passdb with an alternate password for use in Internet cafes, and similar locations. Configuration of the authentication mechanism and the password files is done with the file /etc/dovecot/auth.d/passwd.auth
. It contains:
mechanisms = plain passdb passwd-file { args = /etc/dovecot/passwd.dovecot } # Extra passwords for Internet cafes (only the first match in each file is used). passdb passwd-file { args = /etc/dovecot/passwd.secondary }
To enable Exim to authenticate against the Dovecot database a socket is required. I configured this with the file /etc/dovecot/auth.d/socket.auth
. It contains:
socket listen { client { path = /var/run/dovecot/auth-client mode = 0660 group = Debian-exim } }
Passwords in the file can be encrypted using any supported mechanism. They can be encoded in either base64 or hex. The password file is a simple two-field file consisting of a user-id and a password. The encryption mechanism can be included with the password using the standard mechanism in curly brackets prefix, “{mechanism}”. I chose to use the salted SHA256 mechanism so my lines look like this:
userid:{SSHA256}Pmgys//aeb4kBPbf0DIksxAWlNc+zwYr7qFTZL0AsI1CDSom
Once these files have been created and Dovecot restarted, other programs can use the Dovecot auth-client
socket to authenticate.
Configuring Exim
I use a split configuration for Exim as this retains my modifications across upgrades. It also helps isolate local modifications. Like Dovecot I had already configured TLS and authentication. All three protocols (SMTP, SMTPS, and Submission) are enabled. The relevant lines from /etc/exim4/conf.d/main/00_localmacros
are:
# Enable smtps and submission ports; require tls for auth auth_advertise_hosts = ${if eq{$tls_cipher}{}{}{*}} daemon_smtp_ports = 25 : 465 : 587 tls_on_connect_ports = 465 # Enable TLS; only on submission port MAIN_TLS_ENABLE = true MAIN_TLS_ADVERTISE_HOSTS = ${if eq {$interface_port}{587}{*}{}} MAIN_TLS_CERTIFICATE = /etc/ssl/certs/mail.example.com-cert.pem MAIN_TLS_PRIVATEKEY = /etc/ssl/private/mail.example.com-key.pem hosts_require_auth = ${if eq {$interface_port}{587}{*}{}}
A couple of ACL changes are appropriate if you are using the Submission port. To ensure authentication, a simple deny rule should be added to the top of the Mail ACL If you are not using the Mail ACL, it can be added to the top of the Recipient ACL. This is the condition I use:
deny message = Authentication required before MAIL command !authenticated = * condition = ${if eq {$interface_port}{587}{true}}
The second change is to treat an authenticated connection is equivalent to a local connection. This is done in the recipient ACL. Find the accept rule which has the condition “hosts = +relay_from_hosts
“. Duplicate it replacing the hosts
condition with “authenticated = *
“. My accept rule (which is adapted for DKIM) reads as follows:
accept authenticated = * control = submission/sender_retain control = dkim_disable_verify
Exim’s authentication configuration is stored in the /etc/exim4/conf.d/auth
directory. I removed the previous client authentications and created a new file 10_local-dovecot
. This contains a single plain-text authentication mechanism. As with Dovecot authentication is only available on encrypted (secured) connections. This file contains:
### auth/10_local-dovecot ################################# dovecot_plain: driver = dovecot public_name = PLAIN server_socket = /var/run/dovecot/auth-client server_set_id = $auth1
After these configuration changes have been done and Exim restarted, Dovecot and Exim will be using the same authentication mechanisms.
Notes
As always, you will need to edit the files as appropriate for your configuration. In this case, only the names of the TLS files should need to change.
If you are using a password file, you will need to populate it and secure it appropriately. Only root and any password change utility need the file.
Changing passwords
I did not provide a mechanism for maintaining the user database and their passwords. The simplest mechanism may be to configure dovecot-sql. A minimal web application could then be developed to maintain the table. This would be a good test project for learning Spring or some other framework.
If you are using a dovecot database as a userdb, you have an option for configuring Exim.
- Configure a router and transport as documented in http://wiki.dovecot.org/HowTo/VirtualhostingWithExim. This may require manual creation of the user’s directory. If the home directories are locally or via NFS, then they may already exist.
- Configure a router and transport that access the database for the required data. This configuration could allow the automatic creation of the user’s directory.
TLS Issues
If you have problems with either program accessing the TLS certificate add their user id to the SSL-cert group. The certificate should be made readable by this group if it is not already.
I use self-signed TLS certificates, so users need to permanently accept the certificate the first time they connect with a client. As I use tinyCA as my certificate authority, an optional solution is to install the certificate authorities certificate in the relevant store(s) on the client.