How to switch

Incoming SMTP

For opportunistically encrypted incoming SMTP over the network on port 25, using privilege-separated SSL running as the ucspissl user:

#!/bin/sh

exec 2>&1
exec env                                       \
    UCSPITLS=''                                \
    SSL_UID=$(id -u ucspissl)                  \
    SSL_GID=$(id -g ucspissl)                  \
    CERTFILE=/var/qmail/control/servercert.pem \
    sslserver -ne -vRl0                        \
    -u $(id -u qmaild) -g $(id -g qmaild)      \
    0 25                                       \
    rblsmtpd -r zen.spamhaus.org               \
    fixsmtpio                                  \
    qmail-smtpd

(This works equally well whether you’ve patched qmail-smtpd or not.)

Alternatively, s6-networking’s s6-tcpserver and s6-ucspitlsd can be configured similarly to sslserver -n.

To mark incoming messages with a Received: header indicating the TLS protocol version and cipher (if any) negotiated by the two servers, install rejectutils and list qmail-qfilter-addtlsheader in control/smtpfilters.

Submission

For encrypted, authenticated SMTP submission over the network on port 587, using privilege-separated SSL running as the ucspissl user:

#!/bin/sh

exec 2>&1
exec env                                       \
    RELAYCLIENT=''                             \
    UCSPITLS='!'                               \
    SSL_UID=$(id -u ucspissl)                  \
    SSL_GID=$(id -g ucspissl)                  \
    CERTFILE=/var/qmail/control/servercert.pem \
    sslserver -ne -vRl0                        \
    0 587                                      \
    authup smtp                                \
    checkpassword                              \
    checknotroot                               \
    fixsmtpio                                  \
    ofmipd

Alternatively, s6-networking’s s6-tcpserver and s6-ucspitlsd can be configured similarly to sslserver -n.

As described in authup(8), create control/smtpcapabilities with the available SMTP capabilities of ofmipd:

# echo EHLO                                \
    | ofmipd                               \
    | sed -e '1,2d' -e 's|^....||'         \
    | egrep -v '^(STARTTLS|AUTH)'          \
    > /var/qmail/control/smtpcapabilities

As described in fixsmtpio(8), create control/fixsmtpio with the needed rules for filtering ofmipd’s I/O and exit codes. Here’s a typical set of filter rules (download):

### For all users, authenticated or not:

# Prepend acceptutils link to HELP message, so problems go to fixsmtpio author
:help::*::&fixsmtpio_fixup

# Replace hostname in initial greeting
:greeting::2*::&fixsmtpio_fixup

# Replace hostname in HELO/EHLO response
:helo::2*::&fixsmtpio_fixup
:ehlo::2*::&fixsmtpio_fixup

# Replace hostname in QUIT response
:quit::2*::&fixsmtpio_fixup

# Adjust greylisting-spp messages to look more qmail-ish
:rcpt::451 GL - temporary*::451 greylisted, retry later (#4.7.1)
:data::451 GL - temporary*::451 greylisted, retry later (#4.7.1)

# Remove greeting for child process restarted after upgrading to STARTTLS
FIXSMTPIOTLS:greeting::2*::

########################################################################

### For users authenticated via authup(8):

# Replace greeting for child process started after authenticating
AUTHUP_USER:greeting::2*::235 ok, go ahead (#2.0.0)

# If client closes connection, tell authup the session succeeded
AUTHUP_USER:clienteof::*:0:

# If server greets us unhappily, preserve message, and tell authup to stop trying
AUTHUP_USER:greeting::4*:14:&fixsmtpio_noop
AUTHUP_USER:greeting::5*:15:&fixsmtpio_noop

# If server times out, hide message, and tell authup to stop trying
AUTHUP_USER:timeout::*:16:

# Don't permit server to advertise or respond to further AUTH
AUTHUP_USER:ehlo::250?AUTH*::
AUTHUP_USER:auth:NOOP :*::502 unimplemented (#5.5.1)

(This works equally well whether you’ve patched ofmipd or not.)

To mark submitted messages with a Received: header indicating the TLS protocol version and cipher (if any) negotiated by the client and server, install rejectutils and list qmail-qfilter-addtlsheader in control/ofmipfilters.

From another SMTP AUTH or TLS patch

If you rely on port 25 for both incoming SMTP and authenticated submission, or if you rely on CRAM-MD5 for authentication, please tell me more about your use case, and maybe you’ll be able to switch to acceptutils later.

Assuming SMTP and submission are distinct services and CRAM-MD5 is not in use:

  1. Stop your existing SMTP service.
  2. Start SMTP as above.
  3. Stop your existing submission service.
  4. Start submission as above.

Once you’re satisfied with acceptutils:

  1. Remove your previous SMTP AUTH and TLS patches, rebuild, reinstall. (Exceptions: if you rely on AUTH or TLS support in qmail-remote, keep your other patches. acceptutils does not provide this functionality.)
  2. Remove env RELAYCLIENT='' from your authenticated submission service. (Exception: if you use qmail-smtpd rather than ofmipd for submission, keep it.)
  3. Remove the setuid bit from /bin/checkpassword.

From spamdyke

If you rely on spamdyke only for SMTP AUTH, and not for any of its other features, remove it from your submission service and see “From another SMTP AUTH patch” above.

If you rely on spamdyke for other features, insert fixsmtpio before spamdyke, not after.

From qmail-popup

If you rely on APOP for authentication, please tell me more about your use case, and maybe you’ll be able to switch to acceptutils later.

Assuming APOP is not in use:

  1. As described in authup(8), create control/pop3capabilities with the available POP3 capabilities of qmail-pop3d.
  2. Replace qmail-popup host.name with authup pop3 to leave stderr available, in case you ever want to write to the log from a qmail-pop3d wrapper.
  3. Replace checkpassword with checkpassword checknotroot to prevent qmail-pop3d from ever running as root and to prevent network users from abusing your POP3 service to guess your root password.
  4. Replace tcpserver with sslserver -n to make it possible for authup to offer TLS.
  5. Set UCSPITLS=! in authup’s environment to require TLS before authentication.