FreeBSD as a Secure Mail Server Using sendmail and
imap-uw
Building a simple sendmail server that supports auth-based
relaying as well as SSL/TLS encryption while using FreeBSD is fairly
straightforward. FreeBSD's base sendmail is very flexible
and lends itself well to this type of setup.
The goal is to have working sendmail, ipop3d and
imapd (using imap-uw) that play nice with Microsoft
e-mail clients, don't require any extra password maintenance, uses
FreeBSD's included sendmail---or sendmail installed from the
Ports Collection; please see 'Update 20130801!' below--- and uses applications from
FreeBSD's ports system.
Update 20130801! Since the introduction of the freebsd-update
utility (described at FreeBSD
Update, using this guide with the base-system sendmail complicates
the updating process for the base system. freebsd-update will happily
overwrite your custom-built sendmail when freebsd-update updates
the base system, which means your sendmail will not have SASL support
when the machine reboots after freebsd-update. In order to simplify the
updating process, moving to sendmail built from Ports is advised. If
base-system sendmail is desired, sendmail must be rebuilt
as in step four of the 'Sendmail setup' section of this guide after
every reboot following an update of the base system via freebsd-update.
In order to avoid this extra work, please consider Switching to Ports-installed sendmail,
skipping steps one through four of the 'Sendmail setup' section of this
guide and proceed from step five on. Afterward, sendmail will be
managed by the Ports Collection, which will allow you to update
sendmail separately from the base system.
Make sure your ports tree is updated (using cvsup or portsnap)
to what's current. Also, if you're planning on doing an update of the base system soon it would be a
good idea to make the sendmail build changes at that point
so you don't have to do it separately. It may also be a good time
to change sendmail's LDA to
procmail during the sendmail setup.
Installing imap-uw
- Install mail/cclient from the FreeBSD ports system.
Don't forget to add "-DWITH_SSL_AND_PLAINTEXT" to make to enable
LOGIN and PLAIN auth support if you wish to support non-SSL-capable IMAP
clients:
cd /usr/ports/mail/cclient
make -DWITH_SSL_AND_PLAINTEXT install
- Install mail/imap-uw from the FreeBSD ports system.
Again, don't forget the "-DWITH_SSL_AND_PLAINTEXT" to turn on
support for both SSL-encrypted and plain-text IMAP support if you
plan on allowing access from non-SSL-enabled IMAP clients:
cd /usr/ports/mail/imap-uw
make -DWITH_SSL_AND_PLAINTEXT install
- Install an OpenSSL certificate. When you install the
mail/imap-uw port you should see a message about "make cert" to
generate a certificate for imapd and ipop3d to use.
make cert
Be sure you use the FQDN for your mail server when it asks for
"Common Name."
- Edit /etc/inetd.conf to enable imapd and ipop3d
on their respective secure ports. You can also turn on the standard
(non-encrypted) versions if you want. The lines in your /etc/inetd.conf
should look like this:
imaps stream tcp nowait root /usr/local/libexec/imapd imapd
pop3s stream tcp nowait root /usr/local/libexec/ipop3d ipop3d
- Restart inetd. You can kill and restart inetd
completely, but just sending inetd the HUP signal will result
in inetd re-reading /etc/inetd.conf and applying the new
values. Just "kill -HUP" the PID of inetd.
- Test it out! Point your favorite e-mail client (that does SSL/TLS
encryption) at the machine, make sure everything is configured to
play nicely with SSL, set the auth type to PLAIN or LOGIN (if given
a choice) and see if you can retrieve your mail. If you can't check
your mail make sure you're using the right account name and password,
your client supports SSL-encrypted IMAP or POP3 on the right ports
(993 and 995, respectively), make sure the client supports LOGIN
or PLAIN auth types, make sure the mail server is able to accept
connections on the right ports (check firewall rules, tcpwrappers
config, etc.). If all else fails, start retracing your steps. Did
you build things right? Did you generate an OpenSSL certificate?
Did you set up /etc/inetd.conf correctly? Is your client configuration
right?
Sendmail setup
- Install security/cyrus-sasl2-saslauthd from the FreeBSD
ports system. Installing security/cyrus-sasl2-saslauthd will also
build and install security/cyrus-sasl2 as a dependancy.
cd /usr/ports/security/cyrus-sasl2-saslauthd
make install
- Saslauthd can be started by /usr/local/etc/rc.d/saslauthd.sh
now if you want. Starting saslauthd manually will be necessary
if you're going to rebuild sendmail outside of a buildworld
and not reboot afterwards. Be certain to add the line
saslauthd_enable="YES"
to /etc/rc.conf because the rc script that starts saslauthd
checks the value of this variable to determine whether or not
saslauthd should be started.
- Change sendmail build options in /etc/make.conf. FreeBSD's
SENDMAIL_* variables in /etc/make.conf are functionally equivalent
to creating a site.config.m4 file in the sendmail/devtools/Site
directory in a "virgin" sendmail source tree. We need to use
the build options to enable cyrus-sasl2 support along with
enabling the sendmail server to run on the smtps port (465)
as well as on the regular smtp port (25). The lines in /etc/make.conf
should look like this:
# SASL (cyrus-sasl v2) sendmail build flags...
SENDMAIL_CFLAGS=-I/usr/local/include -DSASL=2
SENDMAIL_LDFLAGS=-L/usr/local/lib
SENDMAIL_LDADD=-lsasl2
# Adding to enable alternate port (smtps) for sendmail...
SENDMAIL_CFLAGS+= -D_FFR_SMTP_SSL
- Rebuild sendmail. You can do this the next time you rebuild the world or you can rebuild sendmail
independently. To rebuild sendmail and associated programs
separate from the rest of the FreeBSD world you need to do the
following:
cd /usr/src/usr.sbin/sendmail
make clean
make depend
make
make install
- Obtain and install an SSL certificate. You can generate an
OpenSSL certificate yourself:
mkdir /etc/mail/certs
cd /etc/mail/certs
openssl dsaparam 1024 -out dsa1024.pem
openssl req -x509 -nodes -newkey dsa:dsa1024.pem -out mycert.pem -keyout mykey.pem
rm dsa1024.pem
chmod -R 600 /etc/mail/certs/*
- Make sure sendmail is using saslauthd for
autentication. /usr/local/lib/sasl2/Sendmail.conf controls which
password authentication mechanism sasl uses against the local
system password database when sendmail requests authentication
against a user's password. /usr/local/lib/sasl2/Sendmail.conf needs
to be changed to use saslauthd, so the line in the file
should look like this:
pwcheck_method: saslauthd
- Edit sendmail's mc file. The mc file should be the
machine's fully-qualified domain name with .mc after it. If it's
not, do a "make all" to generate an mc file with this name. Make
changes to that file, not the original freebsd.mc. We need to allow
auth types of PLAIN and LOGIN, specify PLAIN and LOGIN auth types
as trusted auth mechanisms to allow relaying from hosts that use
those auth methods, point sendmail at our SSL certificate
and tell sendmail to listen on the smtps port:
define(`confAUTH_MECHANISMS',`PLAIN LOGIN')dnl
TRUST_AUTH_MECH(`PLAIN LOGIN')dnl
define(`CERT_DIR', `/etc/mail/certs')dnl
define(`confCACERT_PATH', `CERT_DIR')dnl
define(`confCACERT', `CERT_DIR/mycert.pem')dnl
define(`confSERVER_CERT', `CERT_DIR/mycert.pem')dnl
define(`confSERVER_KEY', `CERT_DIR/mykey.pem')dnl
define(`confCLIENT_CERT', `CERT_DIR/mycert.pem')dnl
define(`confCLIENT_KEY', `CERT_DIR/mykey.pem')dnl
DAEMON_OPTIONS(`Port=smtp, Name=MTA')dnl
DAEMON_OPTIONS(`Port=smtps, Name=TLSMTA, M=s')dnl
Note that only mail clients that support raw TLS connections will
be able to play nice with the smtps port cause of the "M=s" in the
smtps port line in the mc file. If you want a "regular" smtp port
listening at the smtps port just remove the M=s part.
- Rebuild cf files. From /etc/mail:
make all install restart
- Try it out! Point your mailer at the mail server, configure the
mailer appropriately to use SSL/TLS and auth and give it a shot.
If things don't work it's time to start checking your work. If
everything looks right bump the LogLevel to 25 in sendmail.cf and
watch /var/log/maillog to see where the problem is.
Pitfalls and problems
- Make sure your mail clients are pointed at the FQDN of the mail
server, not just the TLD of the mail server if it happens to have
the TLD pointed at it.
- Make sure your OpenSSL certificates are signed for the FQDN of
your mail server, not the TLD of your server. Some clients don't
mind certificates signed for a different name than what your mail
server has (Outlook and Outlook Express), but some clients (Eudora)
will complain.
- Clients can auth without SSL/TLS encryption to imapd,
ipop3d and sendmail even if the client connects on
the "secure" port (except for sendmail's secure port, but
auth without SSL/TLS can take place on the regular smtp port). Since
clients will be using LOGIN or PLAIN types of auth this presents a
security problem. Make a point to enforce the use of SSL/TLS when
connecting (you can check message headers to see if SSL was used
and check /var/log/maillog to see if an SSL connection was established)
to the mail server.
Notes about mail clients
- Outlook and Outlook Express work fine as long as you
make sure they talk SSL to the smtp port (25), not smtps (465). I
personally find Outlook and Outlook Express to both have problems
maintaining connections to my IMAPS server if I don't do anything
with the clients for a while. None of the other Windows clients
seem to have this problem.
- Eudora
does not currently work with newer versions of OpenSSL. This
problem is documented in Eudora's support
pages. I did not feel inclined to disable what needs to be disabled
to fix support for Eudora and neither should you. Hopefully Eudora
will put pressure on Certicom to fix the problem with Certicom's
SSL libraries. Eudora is more well-behaved with IMAP than Microsoft
mail clients.
- Mozilla's
mail client (Netscape Mail should work, too) works
well (version 1.3 has been tested), but it has to begin with a
plain-text connection and initiate a TLS session manually, just
like Outlook and OE do. That means Mozilla doesn't play nice with
the smtps port when the port initially requires a raw TLS connection.
Mozilla is also fairly polite with IMAP and isn't as noisy as
Outlook/Outlook Express are when you turn the "Maximum number of
server connections" setting down to one or two.
- Mulberry rocks. By far the most IMAP-friendly
mail client for Windows, Mulberry is also the most flexible as far
as communications with the server are concerned. Mulberry is a nice
e-mail client and would be a nice Eudora replacement.
- Many mail clients on free, UNIX-like OSes play very nice with
a mail server set up like above. KMail has been reported to work.
Why no CRAM-MD5 or DIGEST-MD5 support?
Adding support for CRAM-MD5 and DIGEST-MD5 complicates
password-management greatly. CRAM-MD5 and DIGEST-MD5 can not
authenticate against the regular password system, be it saslauthd
talking to PAM (the default system the above setup uses for
sendmail) or straight from local system passwords. Keeping
plain-text passwords in files is just a Bad Thing, plus password
synchronization becomes a problem when you have to maintain three
separate passwords.
Sendmail talks to saslauthd, which in turn
authenticates users based on varying password methods. CRAM-MD5 and
DIGEST-MD5 auth require a separate password database to be maintained
and saslauthd has to use that password database (type sasldb,
a flat file in Berkeley database format) for authentication. That
requires somehow changing user passwords in both databases. I suppose
one could hack up the passwd script to change the sasldb
password using the saslpasswd2 program but it would be
kludgy.
Along the same vein, imap-uw requires a separate flat
file of users and plain-text passwords for CRAM-MD5 and DIGEST-MD5
authentication. Again, that complicates the password update procedure
and generally makes synchronization of passwords a real pain.
Credits
- Gregory
Neil Shapiro cleared up some confusion I had in regards to
FreeBSD's sendmail build process
- Lots of web pages (most notably this page)
- The folks in #sendmail on irc.freenode.net and others on IRC in general
- Hajimu
Umemoto for contacting me about this page to inform me that
security/cyrus-sasl2-saslauthd had been broken out in to a separate
port from security/cyrus-sasl2. Mr. Umemoto is the cyrus-sasl2 port
maintainer and does a fine job.
- Chris
Boyd for also notifying me of the port shake-up and going
as far as to provide instructions to use the new port, which really
cut down on my testing time this go-around. :)
- Joe Auty and Glen Hasselman for pointing
out that -DWITH_SSL_AND_PLAINTEXT=yes was not the same as
-DWITH_SSL_AND_PLAINTEXT.
- Andreas Wideroe
Andersen for pointing out that the sasl_saslauthd_enable
rc.conf variable was pretty outdated and should be changed to
saslauthd_enable.
Page created 20030406 00:23 CDT.
Page modified 20130801 02:13 CDT.
Comments? Suggestions? Send them to hemi@puresimplicity.net.
© 2003 Josh Tolbert. This page may not be duplicated without permission.