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

  1. 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

  2. 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

  3. 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."
  4. 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
  5. 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.
  6. 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

  1. 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

  2. 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.
  3. 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
  4. 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

  5. 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/*

  6. 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

  7. 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.
  8. Rebuild cf files. From /etc/mail:

    make all install restart

  9. 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

Notes about mail clients

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


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.