So you want to host your own mail server with opensmtpd, but you don't have time to understand everything going on? Here is an expeditious guide for doing just that.
In this guide I used OpenSMTPD 6.6.1 on Debian Buster.
Lets start by blindly copy-pasting this snippet to install the dependencies we will need:
sudo apt install opensmtpd libpam-ldap libnss-ldap
OpenSMTPD has some LDAP support with the
opensmtpd-extras package, but not
enough for LDAP authentication. Someone opened a bug
report stating that you can
request some fields from the LDAP server, giving you access to the hashed user
password, but that's it. You do not know which hash algorithm was used, and
even if you did, OpenSMTPD will only use the one provided by
crypt, so there is a good
chance that comparing hashed passwords won't work. Later, an OpenSMTPD
that there was no such thing as LDAP authentication in OpenSMTPD, but that one
should rely on standard authentication mechanisms such as PAM or bsd_auth:
[...] OpenSMTPD authenticate using crypt(3) by default, which indeed will require credentials to be adapted for that function, but it does so through bsd_auth(3) on OpenBSD and may be configured to use pam(3) on other systems, so you may just delegate authentication to an ldap layer if you actually don't want the system's auth to take place.
This seems like the right approach to tackle this issue to me, if I were to authenticate against ldap, I'd use an ldap authenticator for bsd_auth(3) or pam(3).
Here is an example of a
pki mail.mydomain.tld cert "/path/to/fullchain.pem" pki mail.mydomain.tld key "/path/to/privkey.pem" pki mail.mydomain.tld dhe auto public_addr = "xxx.xxx.xxx.xxx" listen on $public_addr port 465 smtps pki mail.mydomain.tld auth listen on $public_addr port 587 tls-require pki mail.mydomain.tld auth table ldap ldap:/etc/mail/ldap.conf action dovecot lmtp "/var/run/dovecot/lmtp" userbase <ldap> action "relay" relay match from any for domain "mydomain.tld" action "dovecot" match from any action "relay"
Note that the
userbase parameter is not directly linked with user authentication.
It actually defines the list of available recipients. Here is an example of
url ldap://ldap.mydomain.tld username cn=admin,dc=mydomain,dc=tld password MyAmazingPassword basedn ou=Users,dc=mydomain,dc=tld userinfo_filter (&(objectClass=posixAccount)(uid=%s)) userinfo_attributes uidNumber,gidNumber,homeDirectory
Without further configuration, the
auth keyword in
smtpd.conf tells OpenSMTPD
to use PAM authentication. So this is what we should now configure.
According to its man page, PAM is a system of libraries that handle the
authentication tasks of applications (services) on the system. In Debian, it
mainly consists of a collection of configuration files in
programs that need a generic way to handle authentication, session management,
etc. Each file is a set of rules for one program. Those rules generally use a
pam_foobar.so file depending on the method used (unix, ldap etc.). The idea
is to chain rules to define an authentication policy (e.g. try to authenticate
against the unix backend, if that fails try against LDAP, then if that fails
reject the user). By default, OpenSMTPD will look into the
file for its rules, so this is where we want to write some configuration. The
pam_ldap.so module we are interested in is provided by the
Here is an example of a
#%PAM-1.0 account [default=bad success=ok user_unknown=ignore] pam_ldap.so debug auth sufficient pam_ldap.so debug auth required pam_deny.so
Basically, this configuration tells PAM to rely on
pam_ldap.so to manage user
accounts and authentication. As you can see, there is not a lot of information
in this file. The Debian documentation
explains that this is because
pam_ldap.so delegates everything to Name
Service Switch. The
debug keywords are
used for verbosity, and can safely be removed.
The NSS is provided by the
libnss-ldap package. It is a daemon that holds the
LDAP configuration and caches the requests to the LDAP.
You can configure your ldap URI, your search DN and your bind credentials in
... uri ldap://ldap.mydomain.tld base ou=Users,dc=mydomain,dc=tld binddn cn=admin,dc=mydomain,dc=tld bindpw MyVerySecretPassphrase ...
On debian Buster, enabling LDAP on it has a side effect: SSH sessions will try to authenticate against the LDAP via PAM, unless you switch
Debug your installation
To debug this installation, let's launch all those services manually and make them verbose:
Check the system authentication logs:
sudo tail --follow /var/log/auth.log | grep pam_ldap
Launch opensmtpd in verbose mode:
sudo systemctl stop opensmtpd sudo /usr/sbin/smtpd -dv
Launch the NSS daemon in verbose mode:
sudo systemctl stop nslcd sudo nslcd --debug
Check what is going on with your LDAP server:
sudo tail --follow /var/log/syslog | grep slapd