Postfix work-in-progress

Advanced query/update support | Trickle attack defense | Postscreen zombie defense | TLS (SSL) renegotiation attacks

Advanced query/update support

[Last update: November 2013]

Support for advanced query and update operations is implemented primarily to support automated system management tools.

The idea is to make all Postfix details accessible as a list of "name=value" pairs, where the names are organized into structured name spaces. This allows other programs to query information or request updates, without having to worry about the exact layout of files.

First, an example that shows the smtp/inet service in the traditional form:

    $ postconf -M smtp/inet
    smtp       inet  n       -       n       -       -       smtpd

Different variants of this command show different amounts of output. For example, "postconf -M smtp" enumerates all services that have a name "smtp" and any service type ("inet", "unix", etc.), and "postconf -M" enumerates all services.

General rule: each name component that is not present becomes a "*" wildcard.

Coming back to the above example, the postconf -F option can now enumerate the smtp/inet service fields as follows:

    $ postconf -F smtp/inet
    smtp/inet/service = smtp
    smtp/inet/type = inet
    smtp/inet/private = n
    smtp/inet/unprivileged = -
    smtp/inet/chroot = n

This form makes it very easy to change one field in For example to turn on chroot on the smtp/inet service you use:

    $ postconf -F smtp/inet/chroot=y

Moreover, with "-F" you can specify "*" for service name or service type to get a wild-card match. For example, to turn off chroot on all Postfix daemons, use this:

    $ postconf -F '*/*/chroot=n'

For a second example, let's look at the submission service. This service typically has multiple "-o parameter=value" overrides. First the traditional view:

    $ postconf -Mf submission
    submission inet  n       -       n       -       -       smtpd
        -o smtpd_tls_security_level=encrypt
        -o smtpd_sasl_auth_enable=yes

The postconf -P option can now enumerate these parameters as follows:

    $ postconf -P submission
    submission/inet/smtpd_sasl_auth_enable = yes
    submission/inet/smtpd_tls_security_level = encrypt

Again, this form makes it very easy to modify one parameter setting, for example to change the smtpd_tls_security_level setting for the submission/inet service:

    $ postconf -P 'submission/inet/smtpd_tls_security_level=may'

You can create or remove a parametername=parametervalue setting:


    $ postconf -P 'submission/inet/parametername=parametervalue'


    $ postconf -PX submission/inet/parametername

Finally, adding entries is possible, but currently this does not yet have "advanced" support. It can only be done at the level of the traditional file format.

For example, to clone the smtp/unix service settings and create a new delay/unix service you would enumerate the smtp/unix service like this:

    $ postconf -M smtp/unix
    smtp      unix  -       -       n       -       -       smtp

Then you would copy those fields (except the first field) to update or create the delay/unix service:

    $ postconf -M delay/unix="delay   unix   -   -   n   -   -   smtp"

To combine the above in one command:

    $ postconf -M delay/unix="`postconf -M smtp/unix|awk '{$1 = "delay"}'`"

This is perhaps not super-convenient for manual cloning, but it should be sufficient for programmatic configuration management.

The -X (delete entry) and -# (comment out entry) options already exist for, and they now also work work for entire entries:

Remove or entry:

    $ postconf -X parametername
    $ postconf -MX delay/unix

Comment out or entry:

    $ postconf -# parametername
    $ postconf -M# delay/unix

Support to manipulate other daemon options (-v, -D) and non-option arguments is not yet implemented. For now, use the "postconf -M" traditional view.

Trickle attack defense

[Last update: January 2012]

Trickle attacks are old, but have received attention recently in the context of web servers. The idea is that an attacker sends a request slowly, for example, one byte at a time. Since many servers implement per-read time limits, instead of per-transaction time limits, an attacker can keep a connection busy for a very long time. Namely, the maximum number of seconds before a read operation times out, multiplied by the maximum number of bytes per transaction, multiplied by the number of transactions per session.

The postscreen daemon, available with Postfix 2.8 and later, already implements time limits to receive one complete SMTP command line. Postscreen uses a default time limit of 300s for RFC compliance, but it will switch to a 10s limit under overload conditions. Postscreen limits the number of commands per session and never receives mail, so this is a complete solution.

Support for per-line time limits in the Postfix SMTP server and client is now part of the stable Postfix 2.9 release. This solves most of the problem; it limits the time to send or receive one complete SMTP command or reply, but it does not yet limit the total amount of time to receive or transmit the content of an email message. In the SMTP server, use the existing Postfix mechanisms to reject mail before the SMTP "DATA" command, and to limit the number of sessions and MAIL transactions per client.

The whole thing is implemented in very little code in the lowest-layer Postfix routines. With per-line time limits, Postfix behaves exactly in the same way as before, except when someone trickles the bytes.

Postscreen zombie defense

[Last update: November 2010]

Postscreen is the code name for a new daemon that sits in front of Postfix and that does connection-level filtering. The program is currently part of the Postfix 2.8 experimental release.

The major goals of the program are:

Early results for several weeks of spam were presented at the 2010 LISA conference in San Jose:

Data were collected with help by Ralf Hildebrandt. In an earlier pilot experiment in 2009, Ralf reported that by dropping all pregreeter connections to one server, he reduced the frequency of the "all server ports busy" condition from several times a day to once a week.

There is a lengthy history of prior work in this field. For example, OpenBSD spamd, MailChannels TrafficControl, and work by Michael Tokarev in the early 2000s.

TLS (SSL) renegotiation attacks

[Last update: November 2009]

Early November 2009 there was big news about a security hole in the TLS protocol that allows a man-in-the-middle to prepend data to a fully-secure TLS session. That is, the server certificate verifies, and therefore no-one can read or modify the network traffic. Or so we thought. The initial discussions were focused on the impact on HTTP applications.

While looking at the impact of this for SMTP mail, Wietse came up with an attack that redirects and modifies SMTP mail that is sent over a fully-secure TLS connection; Victor came up with an attack that changes the first command in a TLS session. You can find a preliminary analysis at:

This writeup comes with a little tutorial on SMTP over TLS, and on TLS renegotiation attacks.

The impact of TLS-based attacks on SMTP should not be over-stated. Presently, most SMTP clients don't verify the TLS certificates of SMTP servers. Such clients are already vulnerable to ordinary man-in-the-middle attacks, and TLS renegotiation introduces no new threats for them.

The Postfix SMTP server with OpenSSL is not affected by the TLS renegotiation attack that redirects and modifies SMTP mail, due to accidental details of the Postfix and OpenSSL implementations. Other SMTP server implementations may be affected (my report describes some of the requirements). There may of course be other attacks that I wasn't aware of when I wrote the analysis.

Most SMTP client implementations, including Postfix, will not detect the SMTP-level after-effects from a TLS renegotiation attack. Victor and Wietse have looked into a number of workarounds that can be implemented in the SMTP client, pending a bugfix in the TLS protocol and in TLS implementations. Some of these workarounds may end up in Postfix.