Anti-SPAM Adventures with Postfix

You may remember that 2004 and 2005 were the years of the email virus. 2007 and 2008 are definitely the years of SPAM email.

I run a small home server with Postfix. It just does email for my self and immediate family members - about 12 or so accounts. It gets about 400 SPAM emails a day. This takes some filtering. What's interesting is how SPAM is changing.

Initially we had direct SPAM - a server would send out thousands (or millions of emails. These were easily blocked by IP address. Then we had open relay SPAM - an internet search would see what mail servers were mis-configured for relaying and emails would be directed through that server. Again reasonably easy to block, even so some legitimate emails might have been blocked.

Now we have zombie SPAM - virus infected computers are transformed into mail senders. You will see today that an IP will just send SPAM once and then you'll never see it again (presumably the owner sees his PC melting down and gets it fixed). So you can't block by IP because it's different all the time.

Email programs like Outlook and others try to filter SPAM on content (what the email actually says) or the sender email address. These are becoming more ineffective because the sender email address is made up and different every time, and content is so simple it's hard to filter (e.g. how do you filter something like: "she will feel better".

Fortunately much of the current type of SPAM can be filtered by a mail server (or more correctly an MTA) such as Postfix. However you need to know a bit about the email protocol (SMTP) and how it works.

Simply put, a sending computer (a client) sends an IP request to a mail server. After the IP conversation is started, the client should introduce itself with a HELO (or EHLO) command and it's name. It then identifies who the email sender is (e.g. MAIL FROM fred@fred.com) and who is to get the email (RCPT TO sue@sue.com).

The sending computer can be any random infected PC trying to act like a mail server, but it still has an IP address. This IP address can be looked up using reverse DNS to resolve a host name. Often the name will come up something like 211-34-56-78.dhcp.domain.com. Now a proper mail server will not have a name with "dhcp" in it. Proper email servers are unlikely to have host names with "cable" or "ppp" or "cpe" or "dynamic" or "adsl" in them. So if the ISP has configured reverse DNS correctly for his clients, such fake hosts can be pretty quickly filtered out.

If the DNS is not configured directly, a reverse DNS lookup will come up "unknown". Some significant companies (e.g. Commonwealth Bank in Australia) send email from servers with incorrect reverse DNS settings. In this case you can use Postfix access to allow IPs from email senders you know are genuine, and block others that are "unknown".

You can also block on the name announced in the HELO command. If an email uses HELO fred.com, Postfix can look up to see if fred.com actually really exists. About half the SPAM uses incorrect HELO statements that are easily filtered.

My next filtering stage is a custom filter (written in bash) with a whitelist of sender names and then a list of bad words and phrases. The whitelist of senders allows the badlist of words to be quite brutal because whitelisted senders will not have their emails filtered. Only unlisted senders are subjected to this filter. For instance, a badword is "Megadick". An email containing this word will be filtered if the sender is not on the whitelist. However if auntie jones sent an email with that word in it, that email will get through because auntie.jones@mydomain.com is in my whitelist.

All in all I have 7 stages of SPAM filtering - client checks, HELO checks, sender checks, postfix header checks, postfix body checks, postfix mime header checks, and my own filter script. The occasional SPAM email will still get through. But not for long. I'm on a mission !!!!!

For those that are interested - from /etc/postfix/main.cf:


# Following works on IP and resolved host
smtpd_client_restrictions = permit_mynetworks,
check_client_access hash:/etc/postfix/access,
check_client_access regexp:/etc/postfix/client_helo_checks.regexp,
reject_unknown_client,
permit

# Following works on string received in HELO
smtpd_helo_required = yes
smtpd_helo_restrictions = permit_mynetworks,
reject_non_fqdn_hostname,
check_helo_access regexp:/etc/postfix/client_helo_checks.regexp,
reject_invalid_hostname,
reject_unknown_hostname,
permit

# Following works on MAIL FROM
smtpd_sender_restrictions = permit_mynetworks,
check_sender_access hash:/etc/postfix/access,
check_sender_access regexp:/etc/postfix/sender_checks.regexp,
reject_non_fqdn_sender,
reject_unknown_sender_domain,
permit


header_checks = regexp:/etc/postfix/header_checks.regexp

mime_header_checks = regexp:/etc/postfix/mime_header_checks.regexp

body_checks = regexp:/etc/postfix/body_checks.regexp

Cheers,

Comments

Popular posts from this blog

Microsoft and Apple should really get together (Where is Steve Jobs when they need him)

My Reflection on the Voice To Parliament Referendum 2023