As I’ve noted before, we still have a major problem with sites generating bounce/backscatter storms in response to forged mail — whether deliberately targeted, as a “Joe-Job”, or as a side-effect of attempts to evade over-simplistic sender address verification as seen in spam, viruses, and so on.
Sites sending these bounces have a broken mail configuration, but there are thousands remaining out there — it’s very hard to fix an old mail setup to avoid this issue. As a result, even if your mail server is set up correctly and can handle the incoming spam load just fine, a single spam run sent to other people can amplify the volume of response bounces in a Smurf-attack-style volume multiplication, acting as a denial of service. I’ve regularly had serious load problems and backlogs on my MX, due solely to these bounces.
However, I think I’ve now solved it, with only a little loss of functionality. Here’s how I did it, using Postfix and SpamAssassin.
(UPDATE: if you use the algorithm described below, you’ll block mail from people using Sender Address Verification! Use this updated version instead.)
Firstly, note that if you adopt this, you will lose functionality. Third party sites will not be able to generate bounces which are sent back to senders via your MX — except during the SMTP transaction.
However, if a message delivery attempt is run from your MX, and it is bounced by the host during that SMTP transaction, this bounce message will still be preserved. This is good, since this is basically the only bounce scenario that can be recommended, or expected to work, in modern SMTP.
Also, a small subset of third-party bounce messages will still get past, and be delivered — the ones that are not in the RFC-3464 bounce format generated by modern MTAs, but that include your outbound relays in the quoted header. The idea here is that “good bounces”, such as messages from mailing lists warning that your mails were moderated, will still be safe.
OK, the details:
In Postfix
Ideally, we could do this entirely outside Postfix — but in my experience, the volume (amplified by the Smurf attack effects) is such that these need to be rejected as soon as possible, during the SMTP transaction.
Update: I’ve now changed this technique: see this blog post for the current details, and skip this section entirely!
(If you’re curious, though, here’s what I used to recommend:)
In my Postfix configuration, on the machine that acts as MX for my domains — edit ‘/etc/postfix/header_checks’, and add these lines:/^Return-Path: <>/ REJECT no third-party DSNs /^From:.*MAILER-DAEMON/ REJECT no third-party DSNsEdit ‘/etc/postfix/null_sender’, and add:<> 550 no third-party DSNsEdit ‘/etc/postfix/main.cf’, and ensure it contains these lines:header_checks = regexp:/etc/postfix/header_checks smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/null_sender(If you already have an ‘smtpd_sender_restrictions’ line, just add ‘check_sender_access hash:/etc/postfix/null_sender’ to the end.) Finally, run:sudo postmap /etc/postfix/null_sender sudo /etc/init.d/postfix restartThis catches most of the bounces — RFC-3464-format Delivery-Status-Notification messages from other mail servers.
In SpamAssassin
Install the Virus-bounce ruleset. This will catch challenge-response mails, “out of office” noise, “virus scanner detected blah” crap, and bounce mails generated by really broken groupware MTAs — the stuff that gets past the Postfix front-line.
Once you’ve done these two things, that deals with almost all the forged-bounce load, at what I think is a reasonable cost. Comments welcome…
15 Comments
My technique for dealing with blow-back from third-party hosts is to check that the To: header of the bounce matches one of the envelope return paths I use when sending email. This isn’t a particularly scalable check (by which I mean I couldn’t apply it to all of my users’ email) but it works well for competent individuals.
Why not just use a check_sender_access
check_sender_access hash:/etc/postfix/null_sender
where /etc/postfix/null_sender contains
<> 550 Joejob victim
Header checks are far more expensive than sender checks in terms of resources used.
uh, yeah, probably — I’m not much of a Postfix wiz ;) let me try that out…
Also http://www.postfix.org/BACKSCATTER_README.html looks pretty sound.
http://www.postfix.org/BACKSCATTER_README.html actually scared me off — it starts off with some good basic advice, but quickly gets very complex! The latter half actually recreates a fair bit of the VBounce ruleset, but in Postfix (where it’s a good deal riskier and hairier.) Best to avoid it, I think.
Devdas — your tip looks good; rejecting most bounces at RCPT now. for what it’s worth, here’s the cut-and-paste log — I’ll probably move this into the main post soonish:
Devdas: thanks for the tip, seems to be working nicely. I’ve updated the main post to reflect that.
Hmmm, I recommend putting all your restrictions in smtpd_recipient_restrictions. The default is to delay evaluation till the RCPT stage, and life is made much simpler by keeping all your restrictions in one place.
http://jimsun.linxnet.com/misc/postfix-anti-UCE.txt is probably one of the best places to start with (slightly dated, but still valid).
The Return-Path header is added by the local delivery agent (local(8), virtual(8) or pipe(8)), so looking for that in incoming SMTP traffic isn’t going to be useful.
Two things:
1.) “Sites sending these bounces have a broken mail configuration,”
No, sites sending these bounces are complying with RFC2821, section 3.7, which states:
” If an SMTP server has accepted the task of relaying the mail and later finds that the destination is incorrect or that the mail cannot be delivered for some other reason, then it MUST construct an “undeliverable mail” notification message and send it to the originator of the undeliverable mail (as indicated by the reverse- path). Formats specified for non-delivery reports by other standards (see, for example, [24, 25]) SHOULD be used if possible.”
The relaying server is required by the RFC to deliver a bounce to the address in the reverse-path. If you feel this requirement is in error, feel free to propose a replacement for the SMTP specification.
2.) I’m not a postfix guy, but it looks like you are disabling your ability to receive bounces of any kind, which is very rude to systems your users may have legitimately e-mailed and generated bounce messages at. It’s your system and you’re welcome to do that, but that’s a first-class ticket into http://www.rfc-ignorant.org, as RFC2821 and RFC1123 both point out the requirement of sites to accept bounce messages, and not reject messages simply because they have a null-envelope.
Derek, a very large percentage of blowback/backscatter is generated by hosts which do not do proper recipient validation in the SMTP transaction. Yes, your users might not get a legitimate bounce, but the cost of processing all the other bounces is just too high.
And rejecting bounces while you are being joe-jobbed is a perfectly valid response. I believe that not even rfc-i will list in case a valid reason for rejection is provided.
“Whoever fights monsters should see to it that in the process he does not become a monster.” Friedrich Nietzsche, from Beyond Good and Evil
I fully agree with Derek.
Just found this, so please bear with me posting a late comment.
Nietzsche was a nice guy, but not everything he said applies everywhere. Face it, SMTP is broken. It’s lacking accountability, and it’s really good at it. An SMTP server rarely ever knows who it’s talking to, and then there is no guarantee at all that the information is valid. This and a ton of other design decisions turned out very bad by now, so breaking the standard is the only way to keep using it.
A server can only be (moderately) assured that it’s not being conned into something as long as the original incoming TCP connection lasts, so that is the only window of opportunity for proper error handling, and it’s the only valid path as well. Assuming that incoming data is benign is a fallacy, because in 80-99%, it’s not! A lot of the RFCs the protocol is based on assume a safe internet. Kiss that illusion goodbye.
smtp is not broken. It is a tool. If it doesn’t do the job, use another tool.
The problem with your “trick” here is that it interferes with your ability to send mail to anyone who (like me) is using postfix Sender Verify. A friend of mine mysteriously stopped being able to send me mail — it turned out his ISP had adopted your hack.
hi Perry —
I know. I revisited this back in May to fix that bug. I guess that ISP didn’t read that bit :(
I’ll update this story to point to the May post, too.
Tony — about your “sanity check” for backscatter… Some spammers are trying to defeat some checks that are similar. Take a look at what I discovered here: http://profs.logti.etsmtl.ca/cfuhrman/backscatter/