the djb way

secure socket solutions


poppin' with SSL: qmail-pop3sd

Recall in the original setup of qmail's POP3 service, qmail-pop3d, we noted that account passwords are transmitted over the network in the clear. This makes a standard POP3 service readily susceptible to packet sniffers, and we recommended the use of tcprules to limit access to the service only to hosts from within the local network.

Even with this minimal precaution, passwords still travel in the clear on the local network. An internal user may get other passwords in this way, and secretly be monitoring the CEO's mailbox. (Hopefully POP3 passwords are at least limited to email access, and are not also used for login accounts on the server!)

One alternative to consider is APOP, as the qmail-popup utility does have hooks for APOP authentication. This allows you to drop in an APOP-enabled replacement for /bin/checkpassword, to take MD5-encrypted challenge/responses over the network rather than plain-text. This is a reasonable alternative to the cleartext password problem --except for one thing: The most widely-installed email client doesn't do APOP.

Enter SSL. With our ucspi-ssl wrapper, we can encrypt all traffic between client and server, including the authentication dialogue. This protects not only against packet sniffers and cleartext passwords, but also protects the message content itself with encryption during transmission. The only downside is some additional bandwidth overhead, due to the SSL connection dialogue and traffic encryption.

We say: let's do it!

First, create a self-signed certificate for the service:

# cd /etc/ssl
# openssl req -new -x509 -nodes -days 730 \
> -newkey rsa:1024 \
> -keyout private/pop3s.key \
> -out pop3s.cert

When you run the command, you will be prompted with a dialogue to input values for the certificate, something like this (our input is in bold):

# openssl req -new -x509 -nodes -days 730 \
> -newkey rsa:1024 -keyout private/pop3s.key -out pop3s.cert
Generating a 1024 bit RSA private key
............................++++++
.....................++++++
writing new private key to 'private/pop3s.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:UG
State or Province Name (full name) []:Uganda
Locality Name (eg, city) []:Kampala
Organization Name (eg, company) []:Example Org
Organizational Unit Name (eg, section) []:email
Common Name (eg, fully qualified host name) []:mailhub.example.org
Email Address []:postmaster@example.org

Make whatever entries are relevant for your own service. Note that, for best results, the entry you make for the "Common Name" should match the FQDN used by clients to access the service. As shown here we will expect clients to reach the service at "mailhub.example.org".

The openssl command will generate two files:

We'll see these used in a moment. Now for the qmail-pop3sd service. First create the local service directories:

# mkdir -p /var/svc.d/qmail-pop3sd/{log,env}

Copy this "run" script into /var/svc.d/qmail-pop3sd/run:


#!/bin/sh
# qmail-pop3sd/run
# daemontools run script for qmail pop3s service
# ** ucspi-ssl: ssl enabled **
# ===
CONLIMIT=31
POPDIR="./MAILDIR.POP/"
POPHOST="mailhub.example.org"

exec 2>&1
echo "*** Starting qmail-pop3sd (ssl)..."
echo "*** >> configured for maildir: ${POPDIR}"
exec env -i PATH="/var/qmail/bin:$PATH" \
  envdir ./env softlimit -m 5000000 \
    sslserver -v -HR -l0 \
    -c ${CONLIMIT} \
    -x /etc/tcprules/pop3s.cdb \
    0 995 \
      qmail-popup ${POPHOST} \
        /bin/checkpassword \
          qmail-pop3d ${POPDIR}

### that's all, folks!

Make the file executable with chmod 755. This script is almost identical to the one we installed for the original qmail-pop3d service, with these differences:

We use envdir to set the environmental variables used by sslserver to tell it where to find our keys and certificates. These are setup like so:

# cd /var/svc.d/qmail-pop3sd
# echo "/etc/ssl/pop3s.cert" > env/CERTFILE
# echo "/etc/ssl/private/pop3s.key" > env/KEYFILE

Also, if your ucspi-ssl build configuration (entries in the conf-* files) doesn't match the actual OpenSSL installation on your host, you should specify the actual locations now:

# echo "/etc/ssl/dh1024.pem" > /env/DHFILE

Set up the multilog-er for the service as usual, with this run script in /var/svc.d/qmail-pop3sd/log/run:


#!/bin/sh
# qmail-pop3sd/log/run
# multilogger for qmail-pop3sd service
# ===
exec setuidgid multilog multilog t /var/multilog/qmail-pop3sd


Make the script executable, chmod 755, then setup the log directory:

# mkdir /var/multilog/qmail-pop3sd
# chown multilog /var/multilog/qmail-pop3sd

Now decide what tcprules you want to restrict access to this service, and install them in /etc/tcprules/pop3s.rules:


# pop3s.rules
127.:allow
10.0.:allow
:deny

These happen to be the same rules as our original POP3 service. Open these up as necessary if you want to permit access from outside your local network. Then compile the rules:

# (cd /etc/tcprules; make pop3s.cdb)

Starting the service:

# ln -s /var/svc.d/qmail-pop3sd /service/qmail-pop3sd

Follow the log in another terminal, to check that the service started correctly:

$ cd /var/multilog/qmail-pop3sd
$ tail -f current | tai64nlocal

If you see any problems, you may need to do more than the usual daemontools trouble-shooting:

Otherwise, if the log looks okay, test the service with an SSL-enabled email client. You can also use the ucspi-ssl utility, sslconnect:

$ sslconnect mailhub.example.org 995 -a /etc/ssl/pop3s.cert
+OK <23715.1076057396@mailhub.example.org>
user britney
+OK
pass wallybally
+OK
list
+OK
.
quit
+OK

The sslconnect utility is the analogue of the ucspi-tcp mconnect utility. Here we need to feed it the location of the self-signed certificate with the -a option, to use as the certificate authority for the server's certificate.

Once the service is tested and working properly, get your users to reconfigure their email clients to use SSL. Then take down the original qmail-pop3d service and keep it down:

# cd /service
# svc -d qmail-pop3d
# touch qmail-pop3d/down

Now you're poppin', with ucspi-ssl!


Copyright © 2004, Wayne Marshall.
All rights reserved.

Last edit 2004.02.09, wcm.