A simple exim4 trick for preventing catch-all abuse.
Posted by forrest on Wed 25 May 2005 at 03:49
As soon as spammers learned about my domain, though, having a catch-all address sucked. I got all sorts of spam to the weirdest made-up users at my domain, not to mention the mailer-daemon messages sent to addresses spammers had forged using my domain.
I still wanted to be able to make up addresses easily, and keep track of who had my address. So I decided to set up my mailserver so that messages to users starting with a certain prefix (in my case, fc_) would get forwarded to me. I could still make up addresses, but all the spam would get bounced (unless it happened by chance to begin with the magic prefix, and that hasn't happened yet).
So, how do you set this up on a debian box with exim4?
I took the debian default of having my exim4 configuration in multiple files under /etc/exim4/conf.d; if you have one big file, you'll have to find the appropriate place to insert this snippet.
I had to insert a special router in conf.d/router to handle my prefix. Because exim4 goes through the routers in order until it finds one to handle the message, I had to insert my router after the standard rewrites had occured, but before any of the routers which actually deliver the message. I decided to create a file starting with 450, which would put it right after 400_exim4-config_system_aliases, the router which handles /etc/aliases. I called my file 450_local-not_so_smart. I recommend using _local for anything you add yourself, to keep it straight from the debian config files, which all have _exim4. As for the rest of the filename, well, I wasn't sure it was a good idea when I set it up, but now I'm convinced it's great.
The contents of /etc/exim4/conf.d/router/450_local-not_so_smart look like this:
not_so_smart: debug_print = "R: not_so_smart for $local_part@$domain" driver = redirect local_part_prefix = fc_ data = forrest@example.com retry_use_local_part(I changed my real domain to example.com in the above, to keep from giving the spambots one more place to pick off my address.)
I hope someone else finds this useful; I think it really works wonders.
You might consider using greylisting for exim. I do it for my postfix MTA (postgrey), there are many solutions for exim too.
Lukasz Nowak
[ Parent | Reply to this comment ]
Almost all spam that gets through spamassassin (I reject anything above 7.5) is caught by the baysean filter in mozilla mail.
That keeps me from seeing spam, but my mailserver still has to process it all. I suppose greylisting would save me a little in that department.
[ Parent | Reply to this comment ]
But greylisting is less system loading task (=less resources, that's my english, sorry). I've used it on low-end machine, which was overloaded with anti-virus/spam check, and greylisting lowered its load to acceptable values.
Lukasz Nowak
[ Parent | Reply to this comment ]
local_part_suffix = +* local_part_suffix_optionalin my local_user: definition so that mail addressed to USER+foo@example.com gets delivered to USER, it's a pretty common setup I think.
[ Parent | Reply to this comment ]
TMDA used this extensively to store the encoded part of the email address on the end of a base address. When creating email addresses that can only be used by one sender, or date limited email addresses etc. (TMDA isn't just challenge response).
Convention dictates that people use "-" as the recipient delimited ("+" is also suggested in some places but Lotus Notes doesn't like it, and LN is still common enough to matter alas).
sendmail/postfix/qmail all do this 'out of the box' as far as I know, although I've probably broken it with all my weird virtual user tables in Postfix.
I'm experimenting with greylisting, and blacklists in Postfix and so far the result are pretty good, but I worry it will get less good with time.
[ Parent | Reply to this comment ]
local_user: debug_print = "R: local_user for $local_part@$domain" driver = accept domains = +local_domains check_local_user local_parts = ! root transport = LOCAL_DELIVERY
Modified it to
local_user: debug_print = "R: local_user for $local_part@$domain" driver = accept domains = +local_domains local_part_suffix = +* local_part_suffix_optional check_local_user local_parts = ! root transport = LOCAL_DELIVERY
But - mail to reallocaluser+foo@virtualhost gets sent to the catchall set in the virtual host list for the given virtualhost instead of to reallocaluser.
Should this work with virtual hosts (configured as per Steve's article here on d-a.org)?
[ Parent | Reply to this comment ]
I have exactly the same as you, (except I added the local_part* at the end) although don't use virtual hosting (I do handle mail for multiple domains but the user part is the same for each case...). But I can't remember if I changed anything else or not -- I don't think I did!
The exim config system made me quite confused about what I had to do to make exim actually pickup on the changes -- I guess you are sure of this bit.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]