qpsmtpd Wiki


You are here: start » config » smtps


You are currently not logged in! Enter your authentication credentials below to log in. You need to have cookies enabled to log in.


You don't have an account yet? Just get one: Register

Forgotten your password? Get a new one: Set new password


General information: See “tls” plugin for a modern version. Unfortunately, this plugin (which is bundled with the qpsmtpd source) has no wiki page; there's a POD documentation, though. Try $ cd <qpsmtpd dir>/plugins; perldoc ./tls or pod2man tls | man -l - in the same directory.


Until such time as qpsmtpd can listen to multiple ports simultaneously, you can proxy traffic via SSL and stunnel from port 465 to your existing Qpsmtpd instance.


You can also use sslserver, a variant of tcpserver, and run a separate instance of qpsmtpd similar to the submission solution described elsewhere on this wiki.

Method 1

1 - Copy your /service/qpsmtpd (or whatever) run directory:

  cp -a /service/qpsmtpd/ /tmp/qpsmtpd-ssl/
  touch /tmp/qpsmtpd-ssl/down
  mv /tmp/qpsmtpd-ssl /service

2 - Install stunnel, version 3 (not 4, which uses a different syntax! stunnel v4 should come with a perl wrapper called “stunnel3” which works fine)

3 - Patch your new smtpd-ssl/run file like so (note, yours will probably look quite different. The important bit is the last line, where we change the service port to ssmtp (465) and add the stunnel magic. The path to your .pem file will almost certainly differ.

QMAILDUID=`id -u smtpd`
NOFILESGID=`id -g smtpd`

-echo "starting smtp service with tcpserver and qpsmtpd basedir '$BASEDIR'"
+echo "starting smtp-ssl service with tcpserver and qpsmtpd basedir '$BASEDIR'"
 exec /usr/local/bin/softlimit -m 25000000 \
        /usr/local/bin/tcpserver -c 50 -v -R -p \
        -H -x/etc/tcp.smtp.cdb \
        -u $QMAILDUID -g $NOFILESGID `head -1 $BASEDIR/qpsmtpd/config/IP`
-       smtp $BASEDIR/qpsmtpd 2>&1
+       ssmtp /usr/sbin/stunnel -f -p /etc/courier/mail.pem -l $BASEDIR/qpsmtpd 2>&1

4 - You will probably want to make sure your plugins, lib, and probably config directories are the same for ssl and non-ssl connections. To accomplish this (using sh/bash):

  cd /service/qpsmtpd-ssl
  for i in plugins lib config ; do
    rm -rf "$i"
    ln -s /service/qpsmtpd/$i"

5 - Test your new /service/qpsmtpd-ssl directory with svc. When everything works to your liking, remove the down file.

Note that $ENV{TCPREMOTEIP} is preserved with this setup, so any plugins that make decisions based on IP address should properly without modification, and incoming mail from remote hosts will work without difficulty (unlike the method described below). Further, in your plugins you can now check if your connection is SSL or not by testing $ENV{TCPLOCALPORT} == 465. For example, in an auth plugin, you might want to only allow plaintext authentication on connections over SSL like so:

  $self->register_hook("auth-cram-md5", "authuserdb");
  if(($ENV{TCPLOCALPORT} == 465) || ($ENV{TCPREMOTEIP} eq '')) {
    $self->register_hook("auth-plain", "authuserdb");
    $self->register_hook("auth-login", "authuserdb");

I assumed that you alread had a valid .pem file from some other service on the system (in my case, courier's mail.pem). If you don't have such a file, you will need to make it. See ssh-keygen for details.

Method 2

This method is deprecated compared to the above, as it loses the ability to filter hosts via IP address in plugins. It is left here only for reference.

Here's the steps (assuming you use supervise):

1. Get TLS working (this will mean you have certs already);

2. Install stunnel (duh);

3. Create a management directory, e.g. /var/qmail/service/qpsmtpds;

4. Create a run file:

stunnel /var/qmail/service/qpsmtpds/etc/stunnel.conf

5. Create an appropriate log/run;

6. Create the stunnel.conf file:

# stunnel configuration file for smtp
foreground = yes
setuid = your_qpsmtd_user
setgid = your_qpsmtd_group
pid =
debug = debug
output = /dev/stdout



7. stunnel requires both the key and the cert (in that order) in a single file, so just cat the qpsmtpd-server.key and qpsmtpd-server.crt (to use the default filenames) into the qpsmtpd-stunnel.crt file;

8. stunnel also requires the CAfile and cert be owned by the setuid/gid user and group and have rights 600 (which qpsmtpd will not care about if the same user is used in qpsmtpd and stunnel);

9. Open a hole in your firewall for SMTPS (port 465);

10. Test (when it works, you might want to lower the logging level from debug).

You are strongly encouraged to require SMTP AUTH (since as far as qpsmtpd is concerned, this connection is coming from a local address). You can use this trivial plugin to do this:

# This should be configured to be run _AFTER_ check_relay
# and before other RCPT hooks!
sub hook_rcpt {
  if ( shift->qp->connection->relay_client ) {
    return (OK);
  else {
    return (DENY);

because either the host is already in your relay_clients file or AUTH has set relay_client() to be true.

Won't this break normal connections for incoming e-mail from unknown servers? tyskjohan