<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Yaal Coop - Debian</title><link href="https://yaal.coop/en/" rel="alternate"/><link href="https://yaal.coop/en/blog/feeds/tag-debian.atom.xml" rel="self"/><id>https://yaal.coop/en/</id><updated>2019-12-27T00:00:00+01:00</updated><entry><title>How to plug OpenSMTPD with OpenLDAP on Debian Buster</title><link href="https://yaal.coop/en/blog/how-to-plug-opensmtpd-with-openldap-on-debian-buster" rel="alternate"/><published>2019-12-27T00:00:00+01:00</published><updated>2019-12-27T00:00:00+01:00</updated><author><name>Éloi Rivard &lt;eloi@yaal.coop&gt;</name></author><id>tag:yaal.coop,2019-12-27:/en/blog/how-to-plug-opensmtpd-with-openldap-on-debian-buster</id><summary type="html">&lt;p&gt;This should be easy to do; it is not.&lt;/p&gt;</summary><content type="html">&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;In this guide I used OpenSMTPD 6.6.1 on Debian Buster.&lt;/p&gt;
&lt;p&gt;Lets start by blindly copy-pasting this snippet to install the dependencies we
will need:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;opensmtpd&lt;span class="w"&gt; &lt;/span&gt;libpam-ldap&lt;span class="w"&gt; &lt;/span&gt;libnss-ldap
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1&gt;OpenSMTPD&lt;/h1&gt;
&lt;p&gt;OpenSMTPD has some LDAP support with the &lt;code&gt;opensmtpd-extras&lt;/code&gt; package, but not
enough for LDAP authentication. Someone opened a &lt;a href="https://github.com/OpenSMTPD/OpenSMTPD/issues/812"&gt;bug
report&lt;/a&gt; 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
&lt;a href="http://man7.org/linux/man-pages/man3/crypt.3.html"&gt;crypt&lt;/a&gt;, so there is a good
chance that comparing hashed passwords won't work. Later, an OpenSMTPD
developer
&lt;a href="https://github.com/OpenSMTPD/OpenSMTPD/issues/812#issuecomment-458482184"&gt;confirmed&lt;/a&gt;
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:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[...] 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.&lt;/p&gt;
&lt;p&gt;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).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here is an example of a &lt;code&gt;/etc/smtpd.conf&lt;/code&gt; file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;pki&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mydomain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tld&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/path/to/fullchain.pem&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;pki&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mydomain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tld&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/path/to/privkey.pem&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;pki&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mydomain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tld&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dhe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;auto&lt;/span&gt;

&lt;span class="n"&gt;public_addr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;xxx.xxx.xxx.xxx&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;public_addr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;465&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;smtps&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pki&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mydomain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tld&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;
&lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;public_addr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;587&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tls&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pki&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mydomain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tld&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;

&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ldap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ldap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mail&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ldap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;

&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dovecot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lmtp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/var/run/dovecot/lmtp&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;userbase&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ldap&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;relay&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;relay&lt;/span&gt;

&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;mydomain.tld&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;dovecot&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;relay&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that the &lt;code&gt;userbase&lt;/code&gt; parameter is not directly linked with user authentication.
It actually defines the list of available recipients. Here is an example of
&lt;code&gt;/etc/mail/ldap.conf&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;url                     ldap://ldap.mydomain.tld
username                cn=admin,dc=mydomain,dc=tld
password                MyAmazingPassword
basedn                  ou=Users,dc=mydomain,dc=tld

userinfo_filter         (&amp;amp;(objectClass=posixAccount)(uid=%s))
userinfo_attributes     uidNumber,gidNumber,homeDirectory
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Without further configuration, the &lt;code&gt;auth&lt;/code&gt; keyword in &lt;code&gt;smtpd.conf&lt;/code&gt; tells OpenSMTPD
to use PAM authentication. So this is what we should now configure.&lt;/p&gt;
&lt;h1&gt;PAM&lt;/h1&gt;
&lt;p&gt;According to its man page, &lt;em&gt;PAM is a system of libraries that handle the
authentication tasks of applications (services) on the system.&lt;/em&gt; In Debian, it
mainly consists of a collection of configuration files in &lt;code&gt;/etc/pam.d&lt;/code&gt; 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
&lt;code&gt;pam_foobar.so&lt;/code&gt; 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 &lt;code&gt;/etc/pam.d/smtpd&lt;/code&gt;
file for its rules, so this is where we want to write some configuration. The
&lt;code&gt;pam_ldap.so&lt;/code&gt; module we are interested in is provided by the &lt;code&gt;libpam-ldap&lt;/code&gt;
package.&lt;/p&gt;
&lt;p&gt;Here is an example of a &lt;code&gt;/etc/pam.d/smtpd&lt;/code&gt; file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gh"&gt;#&lt;/span&gt;%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
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Basically, this configuration tells PAM to rely on &lt;code&gt;pam_ldap.so&lt;/code&gt; to manage user
accounts and authentication. As you can see, there is not a lot of information
in this file. The &lt;a href="https://wiki.debian.org/LDAP/PAM"&gt;Debian documentation&lt;/a&gt;
explains that this is because &lt;code&gt;pam_ldap.so&lt;/code&gt; delegates everything to &lt;a href="https://wiki.debian.org/LDAP/NSS"&gt;Name
Service Switch&lt;/a&gt;. The &lt;code&gt;debug&lt;/code&gt; keywords are
used for verbosity, and can safely be removed.&lt;/p&gt;
&lt;h1&gt;NSS&lt;/h1&gt;
&lt;p&gt;The NSS is provided by the &lt;code&gt;libnss-ldap&lt;/code&gt; package. It is a daemon that holds the
LDAP configuration and caches the requests to the LDAP.&lt;/p&gt;
&lt;p&gt;You can configure your ldap URI, your search DN and your bind credentials in
&lt;code&gt;/etc/nslcd.conf&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;...
uri ldap://ldap.mydomain.tld

base ou=Users,dc=mydomain,dc=tld

binddn cn=admin,dc=mydomain,dc=tld
bindpw MyVerySecretPassphrase
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1&gt;SSHD&lt;/h1&gt;
&lt;p&gt;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 &lt;code&gt;UsePAM&lt;/code&gt; to &lt;code&gt;no&lt;/code&gt; in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;Debug your installation&lt;/h1&gt;
&lt;p&gt;To debug this installation, let's launch all those services manually and make
them verbose:&lt;/p&gt;
&lt;p&gt;Check the system authentication logs:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;tail&lt;span class="w"&gt; &lt;/span&gt;--follow&lt;span class="w"&gt; &lt;/span&gt;/var/log/auth.log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;pam_ldap
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Launch opensmtpd in verbose mode:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;stop&lt;span class="w"&gt; &lt;/span&gt;opensmtpd
sudo&lt;span class="w"&gt; &lt;/span&gt;/usr/sbin/smtpd&lt;span class="w"&gt; &lt;/span&gt;-dv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Launch the NSS daemon in verbose mode:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;stop&lt;span class="w"&gt; &lt;/span&gt;nslcd
sudo&lt;span class="w"&gt; &lt;/span&gt;nslcd&lt;span class="w"&gt; &lt;/span&gt;--debug
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Check what is going on with your LDAP server:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;tail&lt;span class="w"&gt; &lt;/span&gt;--follow&lt;span class="w"&gt; &lt;/span&gt;/var/log/syslog&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;slapd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Mail"/><category term="OpenSMTP"/><category term="FOSS"/><category term="Debian"/><category term="Buster"/><category term="Linux"/></entry></feed>