I’ve got a CentOS 4 system running Postfix. I need to add SMTP
authentication. Fun part: I have to authenticate off of an Active
Directory server.
There may be multiple ways to go about this:
- Authenticate via LDAP
- Authenticate via Kerberos
- Authenticate via pam_smb_auth
Of course, I have reasons why (I think) all of these are unacceptable:
- I don’t have a user/password to bind to the LDAP server with, and I
have read in multiple places that AD doesn’t support anonymous
binds. Plus the server doesn’t have an SSL certificate, apparently,
and thus won’t talk LDAP-over-SSL to me (amusingly, the
ldaps port
accepts the connection and immediately disconnects).
- Can’t do Kerberos because I have no host principle, and I don’t have
the Administrator password for the domain so I can create one. Did
I mention this has to be done by morning?
- No pam_smb_auth because I can’t join the domain; see above, no
Administrator password. Now, technically, this might not be a
problem, I’m really not sure. (For example, smbclient can
“authenticate” me just fine, even tough the machine I’m coming from
isn’t joined to the domain.) How does pam_smb_auth work, anyway?
I have the feeling it does NTLM, even when talking to an AD server.
SASL actually has an NTLM method itself, which I really didn’t look in
to. No, instead I found… the IMAP (rimap) method.
/etc/sysconfig/saslauthd:
# Directory in which to place saslauthd's listening socket, pid file, and so
# on. This directory must already exist.
SOCKETDIR=/var/run/saslauthd
# Mechanism to use when checking passwords. Run "saslauthd -v" to get a list
# of which mechanism your installation was compiled to use.
MECH=rimap
# Additional flags to pass to saslauthd on the command line. See saslauthd(8)
# for the list of accepted flags.
FLAGS="-O my.imap.server.ip"
chkconfig saslauthd on; service saslauthd start. You can use
testsaslauthd to make sure it authenticates you. Next, make
/usr/lib/sasl2/smtpd.conf (comes with the Postfix RPM) look
something like:
pwcheck_method: saslauthd
mech_list: plain login
The mech_list is actually the only option I had to add. You can
only use methods that take the password in plaintext with saslauthd;
hence plain and login.
Now hold on: we’re passing passwords in plaintext? That sounds bad.
Let us at least use (offer) SSL (or TLS) on SMTP.
Create a certificate for your mail server. As root, cd &&
/usr/share/ssl/misc/CA -newca and answer the questions. This creates
/root/demoCA. Try something like openssl req -newreq -nodes -out
newreq.pem -keyout newkey.pem -days 730, and answer some more
questions. Then try /usr/share/ssl/misc/CA -sign. This should
create newcert.pem. install -o 0 -g 0 -m 750 /etc/postfix/tls &&
install -o 0 -g 0 -m 640 new{key,cert}.pem /etc/postfix/tls/ to
install these files. You can delete newreq.pem as far as I know.
(Note: I think there should be some slightly less arcane
commands/scripts to create keys. For example, the suite that comes
with OpenVPN is nice, though it might do a thing or two that is
specific to OpenVPN. Does someone know of a nicer front end for
running your own CA? Needs to be command line, since a lot of boxes
don’t have—and don’t want—web.)
Finally, we can tell Postfix about TLS and SASL authentication. Here’s
the end of my /etc/postfix/main.cf:
smtpd_tls_key_file = /etc/postfix/tls/host-key.pem
smtpd_tls_cert_file = /etc/postfix/tls/host-cert.pem
smtpd_tls_CAfile = /etc/postfix/tls/ca-cert.pem
smtpd_use_tls = yes
smtpd_sasl_auth_enable = yes
#smtpd_tls_auth_only = yes
Note that I’ve commented out smtpd_tls_auth_only there. If you
uncomment that line, smtpd will only announce SMTP authentication if
a connection using TLS. Note I say announce: I found out that smtpd
still happily accepts AUTH LOGIN. Anyway, if you can, I’d turn this
on. Really, I’d go through the TLS patch documentation
(/usr/share/doc/postfix-*/TLS/, or on the web I’m sure) and read
about how to make a separate SMTP port that requires SSL. Then make
all your clients do that.
You can test SSL with something like openssl s_client -starttls smtp
-connect localhost:25. You can then test SMTP by having a
conversation something like:
220 your.host.name ESMTP Postfix
EHLO foo.com
250-your.host.name
250-PIPELINING
250-SIZE 140000000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH LOGIN PLAIN
250 8BITMIME
AUTH LOGIN
334 VXNlcm5hbWU6
aGFoYQ==
334 UGFzc3dvcmQ6
c3Vja2Vy
235 Authentication successful
Those two crazy strings I typed after AUTH LOGIN are just base64
encoded. You can make them with Perl:
[root@host ~]# perl -MMIME::Base64 -e 'print encode_base64("username")'
dXNlcm5hbWU=
By the way:
>>> decodestring("VXNlcm5hbWU6")
'Username:'
>>> decodestring("UGFzc3dvcmQ6")
'Password:'
All done. One thing I do not like is that authentication fails
too quickly: there is no barrier to someone trying a whole bunch of
passwords very quickly via SMTP authentication, as near as I can
tell. One solution for this might be using something like pam_imap
and pointing saslauthd at PAM.
I did refer to http://www.metaconsultancy.com/whitepapers/smtp.htm a
bit, as well as the aforementioned TLS docs installed on the system. I
also looked at an install of this I did a while back.
BTW, if you want to activate SSL on an AD server for LDAP (and maybe
IMAP automatically?),
http://support.microsoft.com/default.aspx?scid=kb;en-us;321051 looks
useful.