Postfix work-in-progress


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

ALPACA attack defense

[Last update: August 2021]

ALPACA is a confusion attack where a web client wants to talk to https://example.com but is tricked into talking to an SMTP, FTP, IMAP, or other non-web server that also has TLS a certificate for example.com. The client could then give sensitive information to the wrong service.

Postfix cannot be used in such attacks, because by default the Postfix SMTP server drops a connection when a client sends CONNECT, GET, POST, or anything that looks like a header. The list of bad commands is configurable with smtpd_forbidden_commands. That feature was added in 2004 after someone's SMTP server was flooded with requests from open proxies. Previously, the Postfix command parser blocked only CONNECT and a hard-coded list of headers that appear in email messages.

SOPHOS did a nice writeup that illustrates how Postfix blocks ALPACA attacks: https://nakedsecurity.sophos.com/2021/06/11/alpaca-the-wacky-tls-security-vulnerability-with-a-funky-name/

Trickle attack defense

[Last update: August 2021]

Trickle attacks are old, but have received attention 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, 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-request time limits in the Postfix SMTP server and client is now part of the Postfix 3.7 release. This limits the combined time to send or receive one complete SMTP command or reply. To make this solution complete, the Postfix SMTP server and client can also enforce a minimum (plaintext) data transfer rate, so that a large email message will not run into a per-request time limit.

The whole thing is implemented in very little code in the lowest-layer Postfix routines. With per-request time limits and minimum data rates, Postfix behaves as before, except when someone trickles the bytes.

This defense is more complete than the per-record time limits that were implemented in 2012, because those could not enforce minimum data transfer rates.

References:
smtpd_per_request_deadline, smtpd_min_data_rate,
smtp_per_request_deadline, smtp_min_data_rate.

Advanced master.cf query/update support

[Last update: November 2013]

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

The idea is to make all Postfix master.cf 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 master.cf 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 master.cf 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 master.cf. 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:

Create:

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

Remove:

    $ postconf -PX submission/inet/parametername

Finally, adding master.cf entries is possible, but currently this does not yet have "advanced" support. It can only be done at the level of the traditional master.cf 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 main.cf, and they now also work work for entire master.cf entries:

Remove main.cf or master.cf entry:

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

Comment out main.cf or master.cf 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.

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:

http://www.porcupine.org/postfix-mirror/smtp-renegotiate.pdf

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.