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
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
developer
confirmed
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 /etc/smtpd.conf
file.
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
/etc/mail/ldap.conf
:
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.
PAM
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 /etc/pam.d
for
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 /etc/pam.d/smtpd
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 libpam-ldap
package.
Here is an example of a /etc/pam.d/smtpd
file.
#%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.
NSS
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
/etc/nslcd.conf
:
...
uri ldap://ldap.mydomain.tld
base ou=Users,dc=mydomain,dc=tld
binddn cn=admin,dc=mydomain,dc=tld
bindpw MyVerySecretPassphrase
...
SSHD
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 UsePAM
to no
in /etc/ssh/sshd_config
.
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