My hovercraft is full of eels.

Sunday, 28 June 2009

Recently I've been seeing an awful lot more bounced mail addressed to my domains, to the extent that I now wonder whether they are deliberate "attacks".

Over the past four or five years I'd expect to receive one joe-job attack every six months. Over the past two that's risen to once every two months. For the past two months its been once a week.

I run several domains on my Xen guest, and most of those domains rarely have mail received, so there are only a few localparts. (A "localpart" is the bit before the @ sign in an email address.)

My main domain is and unfortunately this was historically setup with "catchall" behaviour. I used that wildcard expansion pretty seriously so I had localparts such as "", "", etc. Over time I've stopped making up new addresses and just stuck with "steve".

Still I'd never quite gotten round to enumerating all valid localparts, instead I tried to mitigate against these rare bounce storms with various simple hacks. For example the following procmail recipe to file away bounces:

#  Bounces

However this doesn't work as well as it used to - too many idiots people are using challenge/response systems so I'll receive a reply to a mail I didn't send which doesn't look like a bounce (ie. There is a real envelope sender.)

In short blocking bounces by detecting an empty envelope sender is not a complete strategy these days. I started down the heuristic path blocking mail to "unlikely" localparts via patterns such as:

[0-9]@        DENY  Localparts never end in digits
,             DENY  Localparts never contain a comma
|             DENY  Localparts never contain PIPES.
^([^a-zA-Z])  DENY  Localparts start with a-z/A-Z
"             DENY  Quotes are never used in accounts on this system:
'             DENY  Quotes are never used in accounts on this system:

That was actually a simple change to make, via the addition of a new QPSMTPD plugin and it managed to block a lot of the bounceback spam - regardless of the envelope sender. For example:

IP:    sender:<>
IP: sender:<>

Blocking "unlikely" localparts wasn't perfect, but without implementing BATV or enumerating valid localparts there wasn't too much else that I could do. In terms of numbers yesterday I blocked just over 18,500 messages with these six rules.

I also wrote a couple of cronjobs to look at the contents of the Automated.bonces folder so that I could add per-user rejections on the specific addresses being received - with some whitelisting.

(For example if I received 20+ bounces to within the space of ten minutes I'd drop further mails to that address automatically.)

Anyway enough is enough. Today I woke up to just over 40,000 replies to mails I didn't send. I've now scanned my mail directories for all the email addresses I've ever used and will now only accept mail destined to those localparts.

Thankfully it turned out that since 1999 (when was registered) I've only used about 150 distinct localparts, and many of those are now obsolete. So hopefully I'll now have less of a problem.

It seems to be paying off already:  <>  virtual_rcpt_ok
    901     mail to not accepted here (#5.1.1)    <>  virtual_rcpt_ok
     901     mail to not accepted here (#5.1.1)   <>   virtual_rcpt_ok
     901     mail to not accepted here (#5.1.1)

In the future this means I could still get flooded with bounces, but there will be two outcomes:

  • The bounces will not hit valid localparts and will be dropped easily, quickly, and cheaply.
  • The bounces will hit valid localparts:
    • Real bounces will end up in Automated.bounces/
    • Challenge/Response things will still reach me. Sigh.

Still this is progress and I can steal some ideas from this great spam filtering service (ahem) to improve the handling of those! (I explicitly chose to use a similar but different system for my personal mails. Even though my support system is on another box I want to avoid problems where failures requiring human intervention are swallowed in the same way that the original one was. Those kind of reasons mandate a similar system but different implementation.)

I guess I could publish some of the qpsmtpd plugins I use locally virtual_rcpt_ok, virtual_badusers, rcpt_pattern_test, etc. Then again most people who do funky things with qpsmtpd will have plenty of choice already.

ObFilm: Monty Python's Flying Circus. (OK technically not a film. Sums up my mood though.)



Comments On This Entry

[gravitar] Dale King

Submitted at 13:32:50 on 28 june 2009

Why not create an SPF record for your domain? I've found that since doing so the number of joe-jobs against my domains have decreased.

I guess for a spammer if you are going to randomly pick a domain why would you go with the odd one that actually does use SPF?

[gravitar] Matt Zimmerman

Submitted at 13:55:50 on 28 june 2009

For some time now, I've used two rules to help cut down on backscatter and spam:

1. Any email delivered to me which is neither addressed to a mailing list, nor any known address of mine, gets filed into a separate folder

2. Any bounce messages which match #1 are discarded with prejudice

I don't throw away unknown localparts because I add them constantly, using distinct addresses for various web registrations. I sweep the junk folder regularly, which takes very little time.

[author] Steve Kemp

Submitted at 14:17:43 on 28 june 2009

Dale: At one point I did have valid (strict) SPF records setup for my domains, but I removed them during some migrations. They reduced the influx of bounce messages by 2-5% at the most. (And that is being very optimstic).

Matt I like the idea of allowing all local-parts and filing "unknown" ones away. I guess I could do that easily enough since my procmail rules are very much of the form:


(i.e. I have a rule for each per-site address. That would allow a fall-though easily to "Unknown" or similar. But when you're talking of 10,000-50,000 messages in a given bounce-storm it becomes difficult to find legitimate messages in such a folder.)

[gravitar] Warren

Submitted at 15:39:39 on 28 june 2009

Take a look at MailScanner's "watermarking" feature, designed to eliminate this very problem. I think a similar scheme is implemented by IronPort devices also.

In a nutshell, bounce/error messages (ie, return path <>) without the watermark (a hash added to every legitimate message sent) are treated as invalid and marked as spam. If the message didn't originate from your system/network, it won't have the watermark, and it won't make it to your inbox.

Whether this breaks mail to networks using greylisting techniques as you describe, I'm not sure. Such mail systems are fundamentally broken so it wouldn't surprise me.

[author] Steve Kemp

Submitted at 16:10:36 on 28 june 2009

Warren - That idea of signing/watermarking outgoing messages is precisely what BATV is.

I could sign all outgoing messages, but it would be a pain to handle on all satellite machines which legitimately send mail for the domain. (Some relay via it, others use ISP mailservers.)

It does seem like it might be the way to go in the future, but right now the pain of implementing it makes me wary.


Comments are closed on posts which are more than ten days old.

Recent Posts

Recent Tags