How to set up SMTP AUTH

Last Update March 30, 2004

What is this?

This is a simple "how to." This is for anyone out there who has ever wanted to simply add authentication to sendmail. All this page will do is show you one way to configure sendmail and Cyrus SASL libraries to set up a mail server that requires client authentication to send e-mail. This is not a detailed tutorial of either sendmail or Cyrus SASL. For more detailed sendmail help, I strongly recommend going to the Official Sendmail Website or the comp.mail.sendmail newsgroup. For more in-depth discussion of SMTP AUTH with sendmail, try http://www.sendmail.org/~ca/email/auth.html.

It's somewhat ironic that I recommend that latter site (http://www.sendmail.org/~ca/email/auth.html). It was because of this site that I decided to write the site you are reading now. Anyone I talked to about SMTP AUTH referred me to this previously mentioned site. I mean absolutely no disrespect to Claus Aßmann, but I read and re-read this site many times. It was only marginally helpful.

To Claus' credit, I ascribe the reason that it was only marginally helpful to the fact that I was unfamiliar with Cyrus SASL and only at a beginner-to-intermediate level with sendmail. Claus is clearly a sendmail guru of highest degree. This page is submitted as an SMTP AUTH Guide for the Rest of Us. At the simplest level, this is simply "What I Did."

So,... what are you assuming?

If this is just about what I did, I used the following ingredients:

Wait a minute! What happened to the instructions for using Cyrus-SASL 1.x?!?

Calm down. Popular demand and natural version progression brought about this revised page. However, if you still want to use Cyrus-SASL 1.x versions, the last revision of the original site resides here. Don't plan on any future revisions on this site, though. I've moved on. Chances are, you should, too.

Get to the point, will ya?!

Okay, okay! What I set out to do was to set up sendmail to use SMTP authentication to allow users to relay mail on my server. I run a family server, and my family is spread out over several ISPs. Allowing relays based on IP addresses wasn't really practical (especially since most of them were dial-up). For simplicity, I wanted to use the same username and password accounts that my family uses to access their mail (via POP3). These accounts are just the standard /etc/passwd and /etc/shadow logon accounts (using, say, useradd to have created them). I didn't want to try anything fancy (say, SSL, or anything like that). I wanted simple.

This is how I did it:

Step 1 - Check to see what's already installed

At this point, I had already installed SuSE Linux 7.3 (and updated the kernel to 2.6.3 kernel) on the machine I was working on. While I believe that this process will work with many different kernel versions, for posterity's sake, I wanted to make sure you knew what base operating system and kernel I used in my process.

I'm not going to go into the process I took to install either the operating system or the kernel, but you'll notice that the next two steps go over how I installed the latest versions of the Berkeley DB and the GCC. Here again, I don't think these particular versions were fundamental to my success, but I can promise you that they do work. Likewise, I'm not certain that these particular packages must be installed. It's quite possible that the latest RPM packages will suffice. Again, this is included, because it is what I did.

Step 2 - Build the GCC

Download the source for the latest version of the GCC from http://gcc.gnu.org/mirrors.html. I recommend downloading the gcc-core and the gcc-g++ packages. You can download the whole thing (gcc), but the source is pretty big, compiling will take a while, and it will likely give you far more than you need.

I moved both source packages into the /usr/local/src directory and extracted the archives like so:

tar xzvf gcc-core-3.3.3.tar.gz
tar xzvf gcc-g++-3.3.3.tar.gz


I then created a gcc folder, moved the extracted archive into the created folder, and ran the configure script:

mkdir gcc
mv gcc-3.3.3 gcc
cd gcc
./gcc-3.3.3/configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --host=powerpc-suse-linux


For those of you who may not have installed the GCC from source before, this may seem like a strange way to do it. It is, but this is the way the developers want you to do it. I simply followed the instructions in the Install documentation as best I could.

At this point, I should point out that I chose those configure settings because the directory structure and host settings would most closely match my operating system. My goal was to overwrite the files that were installed earlier by the RPM install (for gcc-2.95.3). This is not necessary. In fact, I'm confident that you could safely strip all flags from the command, and you would do just fine. In particular, the --host=powerpc-suse-linux setting is unique to my system. The configure script usually guesses the platform, and I imagine it probably does quite well for most. But for some reason, I've never been able to get it to guess my platform correctly, so I fed it manually. If you would like to feed your platform manually, but you're not sure what your platform name is, check the /usr/lib/gcc-lib directory (if the gcc was previously installed).

Now, we finish up the install simply by typing:

make
make install

Step 3 - Build the Berkeley DB

You may be wondering why I bothered to compile the newest version of the GCC. Well, I attempted to install the newest version of the Berkeley DB, and I came across an error while compiling. It turned out to be a compiler error due to the old version of the GCC I was using (2.95.3), so I updated the GCC.

If you'd like to try installing the Berkeley DB using RPMs, I recommend that you install a 4.x version. Also, be sure to install both db and db-devel RPMs.

For a source install (what I did), download the latest version from Sleepycat Software. Then, move the downloaded archive to the /usr/local/src directory, and extract the package:

mv db-4.2.52.tar.gz /usr/local/src
cd /usr/local/src
tar xzvf db-4.2.52.tar.gz


Now, change to the archive directory. You'll also need to move into the build_unix subdirectory:

cd db-4.2.52/build_unix

Here, you can issue your configure command. Oddly enough, despite the fact that the script is in a different directory, you must run the configure script from the build_unix directory:

../dist/configure --prefix=/usr --sysconfdir=/etc --mandir=/usr/share/man --infodir=/usr/share/info --build=powerpc-suse-linux

Here again, every flag following the configure command is optional. This was simply my way of overwriting the previously installed RPM version of the program. When this finishes, simply type:

make
make install

Step 4 - Build the Cyrus SASL libraries

Download the source for the last version of the Cyrus SASL 2.x libraries. This can be done at ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/

Again, I put the cyrus-sasl-2.1.17.tar.gz file in /usr/local/src. I then extracted the archive by typing tar xzvf cyrus-sasl-2.1.17.tar.gz

I entered the archive - cd /usr/local/src/cyrus-sasl-2.1.17 - and I followed the steps specified in the INSTALL file. The important element here is that AUTH LOGIN functionality is not enabled by default (A big thank you goes to Ken Murchison from the comp.mail.sendmail newsgroup for pointing this fact out to me). This is important because Microsoft Outlook and Entourage cannot use AUTH PLAIN or any of the other default methods. I configured it with this command:

./configure --prefix=/usr --sysconfdir=/etc --infodir=/usr/share/info --mandir=/usr/share/man --enable-login --build=powerpc-suse-linux

The important flag here is --enable-login. The other flags are completely optional. I chose them so that it would install the libraries in /usr/lib/sasl2 (which is where SuSE normally installs them). I originally tried using an RPM from SuSE to install the Cyrus SASL libraries, but again, the RPM's compilation does not support AUTH LOGIN either.

I finished the compilation by typing these two commands:

make
make install

Step 5 - Configure and start SASL

Here, you need to create a configuration file for SASL. This is just a text file that you can create with whatever editor you like (vi, pico, emacs, etc.). This file needs to be named Sendmail.conf (notice the capital 'S'; that's deliberate), and it must be placed in your SASL libraries directory. In my compile, this directory was /usr/lib/sasl2. If you didn't specify a prefix when you compiled SASL, they are likely to have been put in /usr/local/lib/sasl2.

The Sendmail.conf only needs one line:

pwcheck_method: saslauthd

The big difference with SASL 2.x (as opposed to 1.x) is that instead of passively being called, it now runs as a daemon. To start the saslauthd, I recommend issuing this (as root):

saslauthd -a shadow

There are other options you can add as well. Check the man page for saslauthd. The -a flag tells saslauthd that you wish to authenticate using your local /etc/shadow passwords. There are other options to use, but I've never gotten them to work. To be fair, I never gave it a great effort either, as the shadow method is all I want to use.

Now, you'll want to get the saslauthd to start at boot time as well. There are many different ways you can do this. Most distributions have a boot.local or rc.local file that is located somewhere in the subfolders of the /etc directory. You can simply add the command line listed above (although use the full path to saslauthd) to the end of the file, and you're done.

For myself, I'm a big fan of init.d scripts. Rather than create my own, I actually copied one from another machine running SuSE 9.0 (on Intel). If you'd like to use or modify this script, you can download it here. To get this script to work as it is, I also needed to create an /etc/sysconfig/saslauthd file with the line - SASLAUTHD_AUTHMECH=shadow - in it. Lastly, I used the following statements (after putting the previously-mentioned saslauthd startup script in the /etc/init.d/ directory) to get the operating system to start it (and stop it accordingly) when reaching its usual run-levels:

cd /etc/init.d/rc3.d
ln -s ../saslauthd K12saslauthd
ln -s ../saslauthd S09saslauthd
cd /etc/init.d/rc5.d
ln -s ../saslauthd K12saslauthd
ln -s ../saslauthd S09saslauthd


If you are using later versions of SuSE, RedHat, or what-have-you, the chances are that you could install an RPM (or dpkg, or tar, etc.) of the Cyrus SASL 2.x libraries, and that would set up your operating system with startup scripts and everything for you. The point to emphasize is, as of this writing, I still have not found any RPM or prepackaged distributions of SASL that enable AUTH LOGIN by default. If you're going to install an RPM (for the sake of the startup scripts), you're still going to need to compile your own version from the source that will enable AUTH LOGIN (again, because this is the only protocol Outlook and others can use). If you use this method, be sure that you use the same directory structure in your configure command that your operating system uses, so that you will overwrite what it installed. I actually use this method frequently. It works pretty well.

However you choose to do it, make sure that the saslauthd daemon is up and running before your proceed.

Step 6 - Set up sendmail

Download the source for the latest version of sendmail. This can easily be done via ftp at ftp://ftp.sendmail.org/pub/sendmail/.

I put the sendmail.8.12.11.tar.gz file in /usr/local/src. I then extracted the archive by typing tar xzvf sendmail.8.12.11.tar.gz

I entered the archive - cd /usr/local/src/sendmail-8.12.11 - and I followed the steps specified in the INSTALL file.

First you need to create a site.config.m4 file. Once again, Use your favorite text editor. With whatever you put in there, you will at the very least need to add these lines:

APPENDDEF(`conf_sendmail_ENVDEF', `-DSASL=2')
APPENDDEF(`conf_sendmail_LIBS', `-lsasl2')


Notice the strange way that the quotes are used. They are single quotes, but there are actually open (`) and close (') quotes. The open quote is to the left of the "1" key on most keyboards. The close quote is to the right of the ":" key on most keyboards.

If you plan to use the Berkeley DB functionality with sendmail (and if you're following these instructions, you do), you will need to also add this line to the site.config.m4 file:

APPENDDEF(`confMAPDEF', `-DNEWDB')

I saved this file in /usr/local/src/sendmail-8.12.11/devtools/Site/

Second, you need to build sendmail. I did this by typing:

cd /usr/local/src/sendmail-8.12.11/sendmail
sh Build


Remember, if you're rebuilding sendmail, type sh Build -c

Third, I created a sendmail.mc file. I'll let you read up at sendmail.org as far as what should be added to this file, but you must have these three lines in there:

define(`confAUTH_OPTIONS', `A')dnl
define(`confAUTH_MECHANISMS', `LOGIN PLAIN')dnl
TRUST_AUTH_MECH(`LOGIN PLAIN')dnl


Fourth, I built the sendmail config files by typing:

cd ../cf/cf
sh Build sendmail.cf


Fifth, I installed the sendmail config files by typing sh Build install-cf

Lastly, I installed sendmail by typing:

cd /usr/local/src/sendmail-8.12.11/sendmail
sh Build install

Step 7 - Try it out

If you haven't already, start (or restart) sendmail. You're now ready to try authenticating to send mail. I typically used my e-mail clients in my situation. Both Outlook Express and Entourage allow you to set up SMTP authentication by choosing Accounts from the Tools menu. In the Accounts window, double-click on the account you wish to change. In the Edit Account window at the bottom is the Sending mail section. You will have already entered your mail server's name or IP address in the SMTP server: field. Click on the "button" that says Click here for advanced sending options.

In the sub-window that appears, click on the check box entitled "SMTP server requires authentication." For convenience, click on the radio button that says "Use same settings as receiving mail server." Then, click back in the Edit Account window, and click "OK" to save your changes. Feel free to close the Accounts window at this point.

Now, send a message from your client. If it reaches its destination, life is good. If it doesn't, check your logs (for me, it is /var/log/mail).

You can also try to test it manually. Here is a dialog from my system (properly garbled for security reasons). The green text is what you would type. The blue text is what the server displays.

> telnet localhost 25
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 something.fake ESMTP Sendmail 8.12.11/8.12.11/SuSE Linux 0.6; Wed, 2 Apr 2003 15:13:01 -0700

EHLO localhost
250-something.fake Hello localhost [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH LOGIN PLAIN
250-DELIVERBY
250 HELP

AUTH LOGIN
334 VXNlcm5hbWU6
a4msl9ux
334 UGFzc3dvcmQ6
ZvVx9G1hcg==
235 2.0.0 OK Authenticated
MAIL FROM: [email protected]
250 2.1.0 [email protected]... Sender ok
RCPT TO: [email protected]
250 2.1.5 [email protected]... Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
This is a test
.

250 2.0.0 h12MD1qV026715 Message accepted for delivery
QUIT
221 2.0.0 something.fake closing connection
Connection closed by foreign host.


The line a4msl9ux is a user name encoded in Base64. Likewise, the line ZvVx9G1hcg== is the password to that account also encoded in Base64. As most people don't know their usernames or passwords encoded in Base64 off the top of their heads, you can use the Base64 Encoder and Decoder web page and use their interface (Major thanks go to Bryan Halvorson for finding this information for me, and for not giving up on me).

If you really want to just use your client, though, you can watch this same output by stopping sendmail and starting it using these tags:

sendmail -O LogLevel=14 -bd -X /tmp/output.log

(A grand round of applause is due to Claus Aßmann for giving me this information)

If you use this method, you'll want to stop sendmail after you've tried to send from your client (and start it up again the way you normally would, if you want). This generates a log file located at /tmp/output.log and it should show a very similar output to the manual example I gave earlier.

Final thoughts

If you still need help, feel free to e-mail me. Personally, I don't feel that I would be nearly as big a help as the comp.mail.sendmail newsgroup, but I would be happy to help where I can.

If you notice any spelling or grammatical errors, please e-mail me. I'm fairly anal about such things, and would like to keep this looking good.

If you notice any technical errors in my data, please e-mail me, but keep in mind that I never intended this to be an all-encompassing tutorial. These may not be appropriate instructions for someone running, say, Solaris 2.5 and sendmail 8.8. I specified precisely what I used, and it works. That's the only certification you get.

I don't want any lectures about features that are available that I didn't talk about. I didn't talk about them for a reason. I either don't know how to use them or don't care to know how to use them.

I don't want any lectures about security. AUTH LOGIN uses Base64 encoding to transfer the username and password. Is this as secure as, say, SSL? Absolutely not. Is it better than setting up sendmail as an open relay? Absolutely! Besides, as I alluded earlier, my users also use POP3 to retrieve their e-mail which, of course, sends their username and password information in clear text, so the security of the Base64 encoding for my SMTP AUTH is the least of my concerns.

I don't want any religious lectures (e.g., sendmail vs. postfix, MacOS vs. Windows, SuSE vs. RedHat vs. YellowDog, etc.). You may think that you can convince me of the "errors of my ways," but the fact that you should keep in mind is: I don't care. Save your rants for your website.

Lastly, I sincerely hope that this helps people to lock down their sendmail servers. I am a great loather of spam, and I will do anything that I can to help eliminate the proliferation of such garbage. I hope that there is at least one person who found this useful, and that this saves someone the month-long struggle that I endured.


Copyright © Jon Fullmer