UCSPI-TLS is a protocol for adding "delayed encryption" to Dan Bernstein's Unix Client/Server Program Interface protocol. "Delayed encryption" means a session starts off in plaintext, then a command is issued to turn on encryption, encryption is negotiated, and the session restart. This has become a very common way to handle encryption, because it simplifies client configuration and requires only one TCP port.
These are the goals of UCSPI-TLS:
In particular, I believe the privilege separation feature increases your system's security significantly. It creates a dedicated process to handle each encrypted connection, and this process can change its root directory and switch to a low-privilege user and group. Because of its complexity, OpenSSL has had its share of security bugs. Doing encryption in a low-privilege process ensures that the impact of any security bugs is minimized.
Here are more details on doing this with netqmail version 1.05.
wget http://www.superscript.com/ucspi-ssl/ucspi-ssl-0.70.tar.gz gunzip -cd ucspi-ssl-0.70.tar.gz |tar xf - cd host/superscript.com/net/ucspi-ssl-0.70
wget http://www.suspectclass.com/~sgifford/ucspi-tls/files/ucspi-ssl-0.70-ucspitls-0.1.patch patch -p1 <ucspi-ssl-0.70-ucspitls-0.1.patch
You now have a patched copy of sslserver in /usr/local/bin/sslserver. Congratulations!package/compile base package/install base
wget http://www.suspectclass.com/~sgifford/ucspi-tls/files/netqmail-1.05-ucspitls-0.3.patch patch -p2 < netqmail-1.05-ucspitls-0.3.patch
You now have a copy of qmail-smtpd and qmail-popup with TLS supportmake setup check
mkdir /var/qmail/ssl chown root /var/qmail/ssl chmod 700 /var/qmail/ssl cd /var/qmail/ssl
You'll have to decide whether you want to use an unsigned certificate or a certificate signed by a Certificate Authority (CA). If you hire a CA to verify your identity and sign your certificate, clients are more likely to accept this certificate without prompting the user. If you use your own unsigned certificate, clients may have to confirm that they trust your certificate.
If you'd like to use a signed certificate, choose a CA, and follow their directions to obtain a signed certificate. Save the certificate in a file called cert, and the key in a file called key. If you just have one file containing both of these, see the beginning of this step for suggestions on how to split it up.
If you'd like to use an unsigned certificate, follow these steps:
Answer the questions you're asked. Your password is temporary, so it doesn't matter what it is as long as you remember it for a few minutes; you can even write it down. Make sure you use the server's host name, as clients will be configured to connect to it, as the "Common Name" for the certificate. Note that this certificate will expire in 360 days, and you'll have to create a new one before then.openssl req -new -x509 -keyout key.enc -out cert -days 360
You'll now have a file called key.enc containing your encrypted key, and a file called cert containing your certificate.
Enter the password you chose above, and you'll have a file called key containing an unencrypted copy of your key.openssl rsa -in key.enc -out key
to generate a 1024-bit Diffie-Hellman parameter file.openssl dhparam -out dhparam 1024
If you can't figure out any OS-specific commands, edit the /etc/group and /etc/passwd files directly, using the file format described in the system manpages for group(5) and passwd(5).groupadd ssl useradd -g ssl -d /var/qmail ssl
# Set these three SSL_USER=ssl SSL_GROUP=ssl SSL_DIR=/var/qmail/ssl # Enable UCSPI-TLS UCSPITLS=1 # The rest are set based on the above three SSL_CHROOT="$SSL_DIR" CERTFILE="$SSL_DIR/cert" KEYFILE="$SSL_DIR/key" DHFILE="$SSL_DIR/dhparam" SSL_UID=`id -u "$SSL_USER"` if [ $? -ne 0 ]; then echo "No such user '$SSL_USER'" >&2; exit; fi SSL_GID=`id -g "$SSL_GROUP"` if [ $? -ne 0 ]; then echo "No such group '$SSL_GROUP'" >&2; exit; fi # Export the variables used by other scripts export SSL_CHROOT SSL_UID SSL_GID UCSPITLS CERTFILE KEYFILE DHFILE
exec /usr/local/bin/softlimit -m 12000000 \
/usr/local/bin/sslserver -e -n -v -R -l "$LOCAL" -x /etc/tcp.smtp.cdb -c "$MAXSMTPD" \
You should see something like this:tail /var/log/qmail/smtpd/current
@40000000431fb29d10e09c2c sslserver: cafile 32655 @40000000431fb29d10e120fc sslserver: ccafile 32655 @40000000431fb29d10e14bf4 sslserver: cadir 32655 /usr/local/ssl/certs @40000000431fb29d10e176ec sslserver: cert 32655 /var/qmail/ssl/cert @40000000431fb29d10e1a9b4 sslserver: key 32655 /var/qmail/ssl/key @40000000431fb29d10e1d4ac sslserver: param 32655 /var/qmail/ssl/dh 512 @40000000431fb29d10e226b4 sslserver: status: 0/20
* telnet localhost 25 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 host.example.com ESMTP * EHLO there 250-host.example.com 250-PIPELINING 250-8BITMIME 250 STARTTLS * QUIT 221 host.example.comThe line that says STARTTLS after you type EHLO means that the server has TLS configured.
- Now test with a client to make sure things basically work. First start watching the logfile for errors:tail --follow=name /var/qmail/supervise/qmail-smtpd/log/main/current
Unfortunately the client included with sslserver doesn't support TLS. If you have a copy of stunnel version 3 lying around, you can do something like this:Otherwise, just skip this test and try the test in the next step.stunnel -r localhost:25 -f -c -n smtp -D debug -P none
- Finally, try turning on TLS in the mail clients you'll be using and sending a test message. Make sure there are no errors from the client or in the logs, and that the messages arrives successfully.
If this step works, you've set everything up correctly. Congratulations!
Set up qmail-pop3dIf you want to run a POP3 server, make sure you've set up qmail-pop3d as described in Life with qmail, then continue to follow these steps. If you're not running a POP3 server, you can skip this entire section.
- Edit the qmail-pop3d run file, in /var/qmail/supervise/qmail-pop3d/run. There are three changes required:
- Near the top of the file, between the #!/bin/sh line and the line that begins with exec, include the SSL environment variable script we created above, using the shell's "dot" command, typed as a single period:. /var/qmail/ssl/env
- On the line that contains softlimit, add 10MB (10,000,000) the number after the -m flag. This allows qmail-smtpd to use the extra memory required for SSL. For example, if it's currently 2000000, you would have for that line:exec /usr/local/bin/softlimit -m 12000000 \
- On the line that contains tcpserver, change tcpserver to sslserver -e -n, leaving all of the other flags in place. The line will now look something like:/usr/local/bin/sslserver -e -n -v -R -H -l 0 0 110 /var/qmail/bin/qmail-popup \
- Restart qmail to use the new configuration:/var/qmail/bin/qmailctl restart
- Now we'll try a few tests to make sure everything works. If any of these steps fails, double-check the steps above, look for errors in the error logs, and use your common sense to see what's going wrong. Look in the logs to see if there are any errors:You should see something like this:tail /var/log/qmail/pop3d/current@40000000431fb29d10e09c2c sslserver: cafile 32655 @40000000431fb29d10e120fc sslserver: ccafile 32655 @40000000431fb29d10e14bf4 sslserver: cadir 32655 /usr/local/ssl/certs @40000000431fb29d10e176ec sslserver: cert 32655 /var/qmail/ssl/cert @40000000431fb29d10e1a9b4 sslserver: key 32655 /var/qmail/ssl/key @40000000431fb29d10e1d4ac sslserver: param 32655 /var/qmail/ssl/dh 512 @40000000431fb29d10e226b4 sslserver: status: 0/20
- Make sure the server is now offering TLS. To test this, you can connect to the server on port 110, then ask for a list of its capabilities. To do this, start at a shell, and type in the lines marked below with *:* telnet localhost 110 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. +OK * CAPA +OK capability list follows STLS . * QUIT +OK Connection closed by foreign host.
The STLS line after you type CAPA indicates that the server supports TLS.
- Now test with a client to make sure things basically work. First start watching the logfile for errors:tail --follow=name /var/qmail/supervise/qmail-pop3d/log/main/current
Unfortunately the client included with sslserver doesn't support TLS. If you have a copy of stunnel version 3 lying around, you can do something like this:Otherwise, just skip this test and try the test in the next step.stunnel -r localhost:110 -f -c -n pop3 -D debug -P none
- Finally, try turning on TLS in the mail clients you'll be using and receiving some test messages. Make sure there are no errors from the client or in the logs, and that the messages arrives successfully.
If this step works, you've set everything up correctly. Congratulations!
These steps will help you create an SSL service from a TLS service. The instructions are for qmail-smtpd; they will work for qmail-pop3d if you simply replace smtpd with pop3d everywhere.
mkdir -p qmail-smtpd-ssl/log
cp qmail-smtpd/run qmail-smtpd-ssl/ chmod 755 qmail-smtpd-ssl/run
mkdir /var/log/qmail/smtpd-ssl chown qmaill /var/log/qmail/smtpd-ssl
Make sure the script is executable:#!/bin/sh exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t \ /var/log/qmail/smtpd-ssl
chmod 755 qmail-smtpd-ssl/log/run
ln -s /var/qmail/supervise/qmail-smtpd-ssl /service
if svok /service/qmail-smtpd-ssl ; then svc -u /service/qmail-smtpd-ssl /service/qmail-smtpd-ssl/log else echo qmail-smtpd-ssl supervise not running fi
echo " qmail-smtpd-ssl" svc -d /service/qmail-smtpd-ssl /service/qmail-smtpd-ssl/log
svstat /service/qmail-smtpd-ssl svstat /service/qmail-smtpd-ssl/log
echo "Pausing qmail-smtpd-ssl" svc -p /service/qmail-smtpd-ssl
echo "Continuing qmail-smtpd-ssl" svc -c /service/qmail-smtpd-ssl
echo "* Restarting qmail-smtpd-ssl." svc -t /service/qmail-smtpd-ssl /service/qmail-smtpd-ssl/log
stunnel -r localhost:smtps -f -c -D debug -P none