Postfix Spamfiltering
- Angelo Schalley
- Oct, 05, 2009
- Linux
- No Comments
Introduction
After experimenting with basic anti-spam techniques within postfix I found out that those were not sufficient. Although it was dropping a lot of spam, I was also still receiving a lot. The reason for which I didn’t wat to install a spamfilter was because the are memory and CPU consuming. I actualy don’t want to waste any CPU cycles on those spamming bastards. I don’t even want to waste bandbwidth on them….
I then figured there was no way to remove all spam without a spamfilter. But, I just wanted to drop most of the spam as soon as possible. When mail enters the server the first tests should be very minimal in resources, but get rid of a lot of spam. The further the mail gets processed, the more intense the check may get, or less intense if the mail is definitly HAM instead of SPAM.
[edit] Non intensive tests
The easiest tests are those that postfix can do for you. These are the tests that are done during the initial 3 smtp command (HELO/EHLO ,MAIL_FROM:, RCPT_TO:) before the DATA command. They are configured in ‘main.cf’. Below is the relevant part of my main.cf
main.cf:
smtpd_helo_required = yes disable_vrfy_command = yes smtpd_recipient_restrictions = permit_mynetworks, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_invalid_hostname, reject_unauth_destination, reject_unauth_pipelining, reject_unknown_sender_domain, permit
A quick explanation:
- The smtpd_helo_required command makes sure *everyone* must start the connection with the HELO or EHLO command. Which is usefull in the smtpd_recipient_restrictions.
- The disable_vrfy_command is used to stop simple e-mail address harvesting. Spammers could use this command to verify what mailboxes exist on a server.
- reject_non_fqdn_[sender|recipient|hostname] rejects hostnames that are not in the correct domain.tld form.
- reject_invalid_hostname will block servers that give an incorrect hostname during HELO/EHLO.
- reject_unauth_destination will stop relaying.
- reject_unauth_pipelinging disables pipelining.
- reject_unknown_sender_domain will drop mails with a non-existing domain name.
The ‘permit’ at the end is actualy not needed. It’s there so it’s obvious that mail gets permited after this.
The above changes in my postfix config did block a lot of spam. I think it cut back about 50%. I think this is a lot because these tests have very minimal CPU and bandwidth consumtion. Which is ofcourse what we want right? 😉
[edit] Using greylisting
Greylisting is a technique to reject mail with a 450 error message. Most of the time machines used to send spam are low on resources and need to dump as much mail as possible in a very limited time frame. Because of this those machines most likely wil not retry. Normal mailserver will just retry after some minutes or hours.
Because I think greylisting everyone is a cruel thing to do, I will just greylist ip-addresses that are in some blacklists. Why not just use the blacklist to drop those mails? Because it is possible that ip addresses are in blacklists by accident. And if you receive lots of mail the chance gets much bigger you will drop HAM. This is a bad thing to do if you have lots of users.
I use whitelister and postgrey to implement greylisting. To add whitelister and postgrey to your postfix config you need to add them at the end of smtpd_recipient_restrictions in your main.conf. The reason you put it a the end is if whitelister thinks a mail is clean it will skip al other checks. This is bad if you want to do more spam check with smtpd_recipient_restrictions. In worst case your server will become an open relay.
First of al configure whitelister.
whitelister.conf:
sock: 127.0.0.1:10000 rbl: dsnbl.sorbs.net rbl: sbl-xbl.spamhaus.org rbl: bl.spamcop.net rbl: list.dsbl.org rbl: relays.ordb.org rbl: combined.njabl.org rbl: psbl.surriel.com
In my config whitelister runs on port 10000 and postgrey on port 60000 on localhost. I check 7 RBL’s if the sender IP is known by them. If that’s the case the mail will be passed through. If not, the mail wil get accepted in the queue. Postgrey doesn’t need any configuration. At least not on Debian GNU/Linux. It only needs to be started.
To let postfix use the postgrey system you must change smtpd_recipient_restrictions in main.cf to:
main.cf:
smtpd_recipient_restrictions = permit_mynetworks, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_invalid_hostname, reject_unauth_destination, reject_unauth_pipelining, reject_unknown_sender_domain, check_policy_service inet:127.0.0.1:10000 check_policy_service inet:127.0.0.1:60000 permit
The idea is to replace whitelister and postgrey with ACL Policy Daemon (apolicy) as soon as it get the ability to greylist. That way I only have to run one daemon and I get better control on how to score mail.
After implementing the above, the amount of spam dropped to about 25 mails a day. Which is nothing compared to the amount of spam I was receiving without these changes, but still too much. So…. what’s next… 😉
[edit] Adding amavisd-new, Spamassassin and ClamAV
So, to stop the last couple of spam mails I need to have some kind of filter. Googling around got me straight to amavisd-new with spamassassin and clamav. This is quite easy to install. On debian I just typed ‘apt-get install amavisd-new clamav spamassassin razor’. This will install all the necesary tools for you.
Make sure you do a ‘adduser clamav amavis’ to add the clamav user to the amavis group else your e-mail won’t get scanned for virusses.
To start using amavis I put the following in my config files:
main.cf:
content_filter = smtp-amavis:[127.0.0.1]:10024 smtp-amavis_destination_concurrency_limit = 10
master.cf:
smtp-amavis unix - - - - - smtp -o smtp_data_done_timeout=1200 -o smtp_send_xforward_command=yes -o disable_dns_lookups=yes -o max_use=20 127.0.0.1:10025 inet n - - - - smtpd -o content_filter= -o local_recipient_maps= -o relay_recipient_maps= -o smtpd_restriction_classes= -o smtpd_delay_reject=no -o smtpd_client_restrictions=permit_mynetworks,reject -o smtpd_helo_restrictions= -o smtpd_sender_restrictions= -o smtpd_recipient_restrictions=permit_mynetworks,reject -o mynetworks_style=host -o mynetworks=127.0.0.0/8 -o strict_rfc821_envelopes=yes -o smtpd_error_sleep_time=0 -o smtpd_soft_error_limit=1001 -o smtpd_hard_error_limit=1000 -o smtpd_client_connection_count_limit=0 -o smtpd_client_connection_rate_limit=0 -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks
Please read the amavis documentation if you want to understand what all options mean. It’s a bit too mucht to explain here.
Also, make sure you edit your /etc/amavis/conf.d/15-content_filter_mode to enable virus and spam scanning.