Qmail: SMTP & POP3 via SSL

New: This document has been updated to be compliant with version 4+ of stunnel.

This document describes in brief how to set up Qmail providing SMTP and POP3 through SSL, the latter of which is implemented by stunnel, which, in turn, is based upon OpenSSL to provide the basic SSL-framework. What happens is the conventional services being tunneled by stunnel using OpenSSL. Thus, none of the former has to be altered or modified. SMTP/S and POP3/S may run exclusively as well as additionally to regular SMTP- and POP3-services.

The setup procedure is simple and straight forward. You need the following packages:

This document refers to a SMTP-AUTH-aware Qmail configuration, but differs only slightly from the stock Qmail setup. In case you prefer the former, you will also need the respective Qmail patches.

All you have to do is to

  1. install Qmail according to the documents included in its package.

  2. install OpenSSL according to the documents included in its package.

  3. install stunnel according to the documents included in its package.

    The following configuration assumes that its configuration dependent files reside below /etc/stunnel/ instead of the default /usr/local/etc/ which requires at least --sysconfdir=/etc. As always, it is also recommended to specify --localstatedir=/var and --sharedstatedir=/var instead of using the defaults below /usr/local/var/.

  4. create a stunnel configuration file, say /etc/stunnel/smtp.conf, for SMTPS. The following lines suffice:

    # /etc/stunnel/smtp.conf
    exec = /var/qmail/bin/qmail-smtpd
    execargs = qmail-smtpd mail.sub.domain /bin/cmd5checkpw /bin/true
    

    You have to replace mail.sub.domain by your own mail server's domain or IP-address. It may also be replaced by 0 to make Qmail listen to any available address. If you use a stock Qmail setup instead of a SMTP-AUTH-patched version, omit both parameters after the domain name which are used to specify the authentification commands for the SMTP AUTH environment.

  5. create a stunnel configuration file, say /etc/stunnel/pop3.conf, for POP3S. The following lines suffice:

    # /etc/stunnel/pop3.conf
    exec = /var/qmail/bin/qmail-popup
    execargs = qmail-popup mail.sub.domain checkpassword qmail-pop3d Maildir
    

    Again, replace the dummy domain name accordingly.

  6. provide a SSL-certificate for stunnel in PEM-format. stunnel provides an easy method to build a self-signed certificate using
    make cert
    
    Using the environment circumscribed above, stunnel will look for it at /etc/stunnel/stunnel.pem. If stunnel's confdir is set to an other directory, the certificate has to be put there, accordingly. If the certificate is to reside somewhere completely different, stunnel's directive
    cert=filename
    
    can be employed in either configuration above. The same certificate may be used for SMTPS and POP3S, of course.
  7. provide a start-up script for all necessary services. The following sample makes extensive use of Qmail's tcpserver.

    #! /bin/sh
    #
    # Qmail-init-script
    #
    # chkconfig: 2345 90 10
    # description: Qmail, the low-impact mail server.
    
    PATH="/var/qmail/bin:/usr/local/sbin:/usr/local/bin:$PATH"
    export PATH
    mailhost=mail.sub.domain
    qmaild=`id -u qmaild`
    nofiles=`id -g qmaild`
    smtpconf=/etc/stunnel/smtp.conf
    pop3conf=/etc/stunnel/pop3.conf
    pop3=yes
    pop3ssl=yes
    smtpssl=yes
    
    [ -n "$mailhost" ] || mailhost=`hostname -f`
    
    case "$1" in
    	restart)
    		$0 stop
    		$0 start
    	;;
    	start)
    		if test -f /var/run/qmail.pid ; then
    			echo Qmail is already running.
    	    		exit 1
    		fi
    		echo "Starting Qmail MTA:"
    		echo -n "  sender: "
    		qmail-start ./Maildir/ splogger qmail >/dev/null 2>&1 &
    		pid=`ps ax | grep qmail-send | grep -v grep | \
    			sed -e 's/^ *//' | cut -d' ' -f1`
    		if [ -n "$pid" ] ; then
    			echo $pid >/var/run/qmail.pid
    			echo "ok."
    		else
    			echo "failed!"
    			exit 1
    		fi
    
    		echo -n "  receiver: "
    		tcpserver -R -u$qmaild -g$nofiles $mailhost smtp qmail-smtpd \
    			$mailhost /bin/cmd5checkpw /bin/true 2>&1 \
    			| splogger smtp &
    		if [ "$?" != "0" ] ; then
    			exit "failed!"
    			exit 1
    		else
    			echo "ok."
    		fi
    
    		if [ -n "$pop3" ] ; then
    			echo -n "  POP3-server: "
    			tcpserver -v -p -R $mailhost 110 qmail-popup $mailhost \
    				checkpassword qmail-pop3d Maildir 2>&1 \
    				| splogger pop3 &
    			if [ "$?" != "0" ] ; then
    				exit "failed!"
    				exit 1
    			else
    				echo "ok."
    			fi
    		fi
    
    		if [ -n "$smtpssl" ] ; then
    			echo -n "  SMTP/SSL-wrapper: "
    			tcpserver -R -u$qmaild -g$nofiles $mailhost 465 \
    				stunnel $smtpconf 2>&1 | \
    				splogger smtp &
    			if [ "$?" != "0" ] ; then
    				exit "failed!"
    				exit 1
    			else
    				echo "ok."
    			fi
    		fi
    
    		if [ -n "$pop3ssl" ] ; then
    			echo -n "  POP3/SSL-wrapper: "
    			tcpserver -v -p -R $mailhost 995 \
    				stunnel $pop3conf 2>&1 | \
    				splogger pop3 &
    			if [ "$?" != "0" ] ; then
    				exit "failed!"
    				exit 1
    			else
    				echo "ok."
    			fi
    		fi
    	;;
    	stop)
    		test -f /var/run/qmail.pid || exit 0
    		echo -n "Stopping Qmail MTA: "
    		killall tcpserver
    		kill `cat /var/run/qmail.pid`
    		if [ "$?" = "0" ] ; then
    			rm -f /var/run/qmail.pid
    			echo "done."
    		else
    			echo "failed!"
    			exit 1
    		fi
    	;;
    	*)
    		echo "Usage: $0 {start|stop|restart}"
    		exit 1
    	;;
    esac
    

    This script uses the default ports for SMTPS and POP3S, 465 and 995, respectively.

    Again, set the dummy mail.sub.domain accordingly or leave it out altogether to be determined by hostname -f. You may have to adapt qmaild and nofiles as well. They represent the UID for the local user qmaild and the GID for nofiles or nobody, respectively.

    Set pop3, smtpssl and pop3ssl accordingly. Unsetting these values excludes these services from being started. Administrators of standard Qmail installations without the SMTP AUTH patch will have to remove the last two statements from the qmail-smtpd command, once more.

  8. execute the script and put it into your system startup directory.
    ps ax
    
    should display qmail-send, its spawned sub processes as well as various instances of tcpserver.
  9. test and debug your SSL-setup with

    openssl s_client -connect mail.sub.domain:995 -state
    and
    openssl s_client -connect mail.sub.domain:465 -state

    OpenSSL's s_client-option connects to the SSL-wrapped SMTP- and POP3-services of the host.

  10. Inform your users to use SMTPS and POP3S instead of SMTP and POP3 and help them to configure their MUAs.

Last modified at 2002-11-28.