SRS integration with qmail


The purpose of this project is to prevent being "spammed" by bounce messages. That is, I should not have to read any alleged bounce messages which aren't actually responses to messages that I have sent out. Ideally, this will avoid wasting my time reading both spam that is sent with an empty envelope sender in the first place, and also bounces which are sent to me by innocent joe-jobbed MTAs which are not yet SPF-enabled, when a spammer forges my address as the envelope sender.


This document makes liberal use of acronyms and jargon which experienced mail administrators should understand. If you need a primer on basic mail server administration concepts, try this tutorial first.

First, we must understand exactly what the problem is. SMTP specifies that bounce messages (responses to the sender of undeliverable mail) should be sent with an empty envelope sender, to avoid bounce loops. This means that "spam" (unsolicited bulk/commercial e-mail) can be sent this way:


There's no way for the MTA at to know whether this is a legitimate bounce message (a reply to a previous outgoing message). Schemes like SPF which validate the envelope sender address can't be used here either, because there is no sender address to validate. (Note: I've been informed that SPF may be able to make a judgment based on the SMTP HELO which is sent before the envelope. This does not invalidate the technique of using variable envelope sender addresses as a form of bounce signature.)

The Sender Rewriting Scheme (SRS) allows me to work around this. By changing my own envelope sender address on all of my outgoing messages, I can reject (or filter) any incoming bounce messages which are not legitimate responses. The criteria are simply: any incoming messages with an empty envelope sender which go to my main e-mail address,, must be spam. Real bounces will go to an SRS address instead, and will then be forwarded to my real address. For example:

legitimate bounce
| Run SRS validation on the address.
V Hash HHHHHHHH must be valid, and timestamp TT must be recent.
Forward to

| Empty envelope sender!
Drop it in the spam folder.

This scheme does not rely on any external cooperation whatsoever. I can do it simply on my own mail system(s), and it works immediately.


This implementation is done in small pieces. I will describe each one in turn. Alternate implementations are of course also possible; in particular, patching qmail to include "native" SRS support would make this a more efficient operation. However, this implementation works right now.

First, I installed the Mail::SRS software (also available as a perl module from CPAN). I had safecat installed already (which provides the maildir command).

Next, I set up a virtual domain called which will handle all of the incoming messages with SRS addresses. This requires an MX record in DNS, and the following configuration in qmail on my mail server:

Notes on the script above:

That takes care of getting valid SRS bounces to me, and puts a valid envelope sender on them ( The next piece "discards" all other bounces to my real address (

Notes on the preceding script:

Finally, I needed a way to change my envelope sender on a per-outgoing-message basis. I'm using mutt as my MUA, so this was easy using mutt's advanced flexibility. Users of other MUAs will have to find their own way to achieve the same thing. I did this:

Note that the HashLength and the secret used here must match the ones used on the qmail side, so that the SRS addresses will validate properly. As you can see, I'm also using QMAILSUSER and QMAILSHOST here, so of course this means that I'm running qmail on the box where mutt runs. If your client-side MTA is not qmail, then this will have to be adjusted as well.

Bugs, open questions, etc.

Some people have asked whether a scheme of this nature will have any adverse effects when used for real-life Internet e-mail. Specifically, there is some concern that white- and black-listing schemes which rely on the envelope sender address (instead of the inner From: header) may generate false results when evaluating the variable sender address. There is no definitive answer to this question yet; so, as with anything else, you use this scheme at your own risk.


This technique was inspired by Brian Candler's message to the SPF mailing list, entitled A couple of thoughts.

Meng Weng Wong and Shevek deserve full credit for the great perl implementation of SRS. Shevek also gets special mention for convincing me to rewrite some crappy quoting-hell shell scripts in perl. It's much cleaner now.

Meng Wong and the SPF project made SRS a necessity in the first place. Without that, none of this would be here.

Greg Wooledge <>