Search:
[Title Bar]

The Goal: Remote Mail via imap and relaying via smpt-auth

I just got a new (virtual) server to use for mail, web (not streetcar), and such. As I've said before, I'm a high-tech luddite, I actually use /bin/mail (or Berkeley mail) as my primary mail reader. But I figured I should enter this millenia and at least see what other mail programs are like, things like alpine (the new version of pine), mutt, and thunderbird. (Aside: while I haven't used them enough to hate them, my reaction is "ehhhh" and that it really doesn't provide much in the ways of benefits, and makes things more complex.)

And I wanted to set these programs up so I could run them on my laptop and connect to the remote server, uh, remotely. I decided to use imap instead of pop3 to read mail (based on what I read, it seems to be a little more flexible and powerful) and sendmail to, uh, send mail.

It took about 2 weeks to get everything set up and was a general pain in the ass. My friend Timothy recommended I write up the trail I blazed so someone else might benefit from it. Of course the problem is there is no appropriate place to put it, so I'll bury it here in my web site and just hope that Google and friends happen to index it on the right words. This is a horrible way to do things, but at the moment, the alternative is to write nothing and let everyone else figure it out on their own. Apologies, but I've got only so many things I can fight at once.

And note that while many of these steps work in general, the details of what needs to be installed, the paths where some of the commands are located, and what is and is not installed is specific to my system. It's a CENTOS 5 Linux system (which is RedHat based), is running on a virtualized server (which may or may not affect anything) and has many things installed, but not everything, and not completely. This became apparent as I got deeper into this.

openssl

The first thing I did (well, technically, it's not the first thing, but I'll skip the dead ends), was to install openssl. I used openssl-0.9.8g from www.openssl.org. I believe that installed surprisingly easy.

I then needed to create a certificate for imapd to use. I did:

cd /usr/local/ssl/certs
openssl req -new -x509 -nodes -out imapd.pem -keyout imapd.pem -days 365

imapd

Next up was installing imapd itself. I downloaded the full alpine-1.10 distribution, which includes imapd, from the University of Washington here.

The imapd makefile is totally nonstandard and a pain in the ass. For CENTOS (which is a RedHat variant), after cd'ing into the imapd/ directory, I used the command:

make lnp

to make imapd. Note that openssl had to be on the system. I think it already was on my system, but something was missing, and RPM refused to install it, so that's why I had to compile and install it (in /usr/local) from scratch. But eventually it worked.

I installed imapd in /usr/local/bin.

Configuring xinted

Then I created /etc/xinetd.d/imap which contained:
service imap
{
        socket_type     = stream
        disable         = no
        protocol        = tcp
        wait            = no
        user            = root
        server          = /usr/local/bin/imapd
}

And restarted xinetd, via:

/etc/rc.d/init.d/xinted restart

Adding pam.d/imap

After that, I added the file /etc/pam.d/imap which contained:
#%PAM-1.0
auth       required     /lib/security/pam_listfile.so item=user sense=deny file=
/etc/ftpusers onerr=succeed
auth       required     /lib/security/pam_unix.so shadow nullok
account    required     /lib/security/pam_unix.so
session    required     /lib/security/pam_unix.so
#auth       include      system-auth
#account    include      system-auth
#session required        pam_unix.so
#password   include      system-auth

At this point, I could read mail remotely. imap supports the STARTTLS command which encrypts the session. Only after STARTTLS are you allowed to authenticate via a "plaintext" password (because it's not sent across the Ineternet as unencrypted plaintext. For all the gory details as well as the command for imap version 4, see RFC 3501. It's helpful to use a few commands to test that the basics of imapd are working.

Next up: sendmail

sendmail

The system I'm using has sendmail 8.13.8 installed. I have also compiled sendmail-8.14.3, but eventually decided the current sendmail that was installed would work. Eventually I'll upgrade it.

Note that initially when trying to send mail via a remote client, I could (properly) get the following error message:

reject=550 5.7.1 <xyz@somemail.com>... Relaying denied. Proper authentication required.
This is actually good, it means you are NOT running an open relay and being a source of the world's junkmail. The trick is configuring it so that it will allow relaying if the user is authenticated via some user name and password. A related issue is that you don't want to send passwords in plaintext across the Internet, so you'll need encryption, and to do that, you'll need certificates, and for those, they'll need to be signed by a certificate authority, so for that you need to create one.

Creating Certificate Authority and Certificates

First up I needed to create a Certificate Authority (CA) and some certificates (signed by the CA). Any mail program will detect that these aren't "legitimate" certificates, since they're not signed by a top level, globally trusted CA. However, most programs will warn you and allow you to accept the certificate anyway, and if it's your own mail program that's running here, you can decide to trust your own certificates.

The infomration in: http://www.aet.tu-cottbus.de/personen/jaenicke/pfixtls/doc/myownca.html was helpful. The CA.pl program was in /etc/pki/tls/misc/ on my system. I ran the command:

CA.pl -newca
and then edited the file CA.pl to insert "-nodes" in two of the system lines (the URL above gives a context diff(1), but essentially you're adding "-nodes" to the system() command in "-newcert" and "-newreq" so they look like:
system ("$REQ -new -x509 -nodes -keyout newreq.pem -out newreq.pem $DAYS");
system ("$REQ -new -nodes -keyout newreq.pem -out newreq.pem $DAYS");

Then I created a certificate by running:
CA.pl -newcert
and after that signed it via:
CA.pl -sign
The "-nodes" lines makes it so that the key is not encrypted. Otherwise sendmail won't be able to read the key when it starts (and will require operator intervention whenever it restarts).

The above creates two files, newkey.pam and newcert.pem and they must be readable only by root, so:

chmod 400 newkey.pem newcert.pem
I did not bother to create a client certificate, since I'm not interested in having my sendmail server act as a trusted client for another server.

Creating a Certificate Revocation List (CRL File)

Finally, I created a (null) certificate revocation list (CRL). (Again, this happened later in the process. It took a while to track down the appropriate error message in /var/log/maillog which said
 STARTTLS: CRLFile missing
indicating it wanted the CRL file. The CRL file is created with the command:
openssl ca -gencrl -keyfile /CA/private/cakey.pem -cert /CA/cacert.pem  -out crl.pem -crldays 365
Note that the CA.pl script created the CA directory in /CA. I had moved it but that caused too many problems, so I just left it there in root (/).

Modifying sendmail.mc to enable authentication

I kept the newcert.pem, newkey.pem and newreq.pem files in the /etc/mail/ directory. The file sendmail.mc is also in this directory.

I added, modified, or uncommented the following lines in sendmail.mc to add support for smtp auth.

define(`confAUTH_OPTIONS', `A p')dnl
TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN') dnl
define(`confCACERT_PATH', `/CA')dnl
define(`confCRL', `/CA/crl/crl.pem')dnl
define(`confCACERT', `/CA/cacert.pem')dnl
define(`confSERVER_CERT', `/etc/mail/newcert.pem')dnl
define(`confSERVER_KEY', `/etc/mail/newkey.pem')dnl
And then ran make in that directory. And after restarting sendmail via
/etc/rc.d/init.d/sendmail restart
I noticed that when I telnet'ed to the server and gave an EHLO localhost command, it did not respond by listing "auth" as one of the extended options ( 250-auth login plain). That required a bit of digging.

The command:

openssl s_client -starttls smtp -connect localhost:25
was very helpful for debugging the auth problems once the encryption was working. This command will connect to the sendmail daemon, run the STARTLS command and, negotiate the encyrption, and then give you an unencrpted connection to sendmail via standard input and standard output. This is extremely helpful. From there, you can once again issue the "EHLO localhost" command, see what sort of results it gives, and then attemtp to execute an "auth login" command to see if you can authenticate with plain (this requires a base64 encoded string; you can either compute it and cut and paste it, or if it gets that far, a mail client can authenticate for you).

SASL

It turns out that the SASL (Simple Authentication and Security Layer) authication daemon on my system was installed but not all the libraries were installed. Looking at /usr/lib/sasl2/, there were files like libanonymous.{la,so} and similar, as well as Sendmail.conf, but nothing like libplain.{la,so}, libcrammd5.{la,so}, libgssapiv2.{la,so}, and the like. That was why those forms of authentication were not available.

There is supposed to be some RPM file that has SASL server libraries, but I haven't had the best of luck with that stuff. So I downloaded the SASL libraries from CMU. I got the cyrus-sasl-2.1.22 version.

Surprisingly, it compiled and installed without a problem. No, wait, it didn't. I had to edit saslauthd/saslauthd.h and change

#define PATH_SASLAUTHD_RUNDIR "/var/state/saslauthd" */
to
#define PATH_SASLAUTHD_RUNDIR "/var/run/saslauthd"
as on my system, the saslauthd unix domain socket was stored in a different path. I forgot, that was a pain too.

Anyway, it put its files under the /usr/local/ subtree. Rather than get rid of something that might work, I renamed /usr/lib/sasl2 to /usr/lib/sasl2.orig and then created a symbolic link that points /usr/lib/sasl2 to /usr/local/lib/sasl2. I also copied the file Sendmail.conf into /usr/local/lib/sasl2. The file has only 1 line:

pwcheck_method:saslauthd

Even though I installed newer versions of saslauthd in /usr/local, it turns out the one that was installed and running out of /usr/sbin worked fine. It was invoked in the /etc/rc.d/init.d/saslauthd file as:

/usr/sbin/saslauthd -m /var/run/saslauthd -a pam -n 2
This starts two instances of the saslauthd process running and it uses PAM authentication, which is the usual login credentials of account name and password, which is what I wanted.

After that, and restarting the sendmail daemon (I did this many times), sendmail finally let me connect to the server via a laptop and send mail to a third site.

So I think it all works now.

I'll probably just stick with /bin/mail, since it's worked the whole time without having to go through all this crap.


This page last modified Jun 28, 2009.
Home
RSS Feed
feed