After much wrangling, I’ve managed to get the first step in my email setup working (well, I can logon to it, at least!)
The challenge here was getting Dovecot to talk to my OpenLDAP service. Ostensibly a fairly simple thing, made far more complicated in the end due to the lack of good LDAP management tools and, as usual, flawed answers on the Internet.
The tricky thing is allowing clients to authenticate via LDAP. in order to do that, Dovecot needs to bind to an account on the LDAP server which can see the users’ passwords. The Ubuntu page on OpenLDAP explains how the LDAP ACLs can be listed, and then suggests this page for more information on LDAP ACLs. And that page is completely out of date. It talks about the /etc/ldap/slapd.conf file and how the ACLs are listed and can be edited there.
There are, as part of the standard openldap installation, ACLs in /etc/ldap/slapd.conf. They just don’t do anything. They are there in the configuration file, but they do nothing.
The actual method to change the ACLs is to write an LDIF file listing the full set of ACLs you want to have applied (you can’t change just one rule), like this:
change_acl.ldif:
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to attrs=userPassword by self write by anonymous auth by dn="cn=dovecot,dc=example,dc=com" read by * none
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to * by * read
And then apply the new set of rules:
sudo ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f change_acl.ldif
You also need to create that entry in your database with a different ldif file:
add_dovecot_account.ldif:
dn: cn=dovecot,dc=example,dc=com
changetype: add
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: dovecot
description: IMAP Mail server account
userPassword: somecomplicatedpasswordgoeshere
And apply that change with:
ldapadd -x -D cn=admin,dc=example,dc=com -W -f add_dovecot_account.ldif
And then in /etc/dovecot/dovecot-ldap.conf.ext change this section suitably:
# Space separated list of LDAP hosts to use. host:port is allowed too.
hosts = ldap-server-name-in-ssl-cert
# LDAP URIs to use. You can use this instead of hosts list. Note that this
# setting isn't supported by all LDAP libraries.
#uris =
# Distinguished Name - the username used to login to the LDAP server.
# Leave it commented out to bind anonymously (useful with auth_bind=yes).
dn = cn=dovecot,dc=example,dc=com
# Password for LDAP server, if dn is specified.
dnpass = somecomplicatedpasswordgoeshere
You really need to be using SSL for your LDAP server here, as otherwise, that password is being sent in unencrypted LAN traffic.
There is an alternative way of doing things, where instead of binding to a privileged account to lookup passwords, you just let the user authenticate themselves via LDAP, but getting the password encryption settings right was giving me grief. I’m really not sure what is best from a security perspective, but this is a home system where I really don’t have to worry about internal attackers overly much.
next step: Postfix!