10/14/2010

Spam Control For Postfix

Spam is a major problem for anyone with a mail server. Many times, spam goes to email addresses that don't exist. But, it still is hitting your server even if it isn't delivered. Other times, a users inbox will be overflowing with annoying messages about Viagra, hookers, free software, and whatever else.

Below is a solution. It's an ongoing accumulation of my efforts to stop spam to the best of my abilities. So far, it has a 97% success rate with over 20,000 emails (spam and ham, alike) processed.

Follow the instructions. I will update/modify as necessary if things seem unclear. Feel free to ask.

1) Install Postgrey, RRD, a log parser, and Graphing tools.
apt-get install postgrey rrdtool mailgraph pflogsumm

2) Restart the Postgrey server.
/etc/init.d/postgrey restart

3) Edit the Postfix main.cf.
We will be adding several things including the Postgrey configuration.
# See /usr/share/postfix/main.cf.dist for a commented, more complete version


# Debian specific: Specifying a file name will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = /usr/share/doc/postfix

# TLS parameters
smtpd_tls_cert_file = /etc/postfix/smtpd.cert
smtpd_tls_key_file = /etc/postfix/smtpd.key
smtpd_use_tls = yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.

myhostname = my.derekgordon.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = my.derekgordon.com, localhost, localhost.localdomain
relayhost =
mynetworks = 127.0.0.0/8 [::1]/128 66.118.142.78
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
html_directory = /usr/share/doc/postfix/html
virtual_alias_domains =
virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, mysql:/etc/postfix/mysql-virtual_email2email.cf
virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf
virtual_mailbox_base = /var/vmail
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_authenticated_header = yes
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, check_recipient_access mysql:/etc/postfix/mysql-virtual_recipient.cf, reject_unauth_destination, check_policy_service inet:127.0.0.1:60000, reject_rbl_client zen.spamhaus.org, reject_rbl_client smtp.dnsbl.sorbs.net, reject_rbl_client bl.spamcop.net, reject_rbl_client combined.rbl.msrbl.net, reject_rbl_client multihop.dsbl.org, check_recipient_access regexp:/etc/postfix/spamtrap, permit
smtpd_tls_security_level = may
transport_maps = proxy:mysql:/etc/postfix/mysql-virtual_transports.cf
relay_domains = mysql:/etc/postfix/mysql-virtual_relaydomains.cf
relay_recipient_maps = mysql:/etc/postfix/mysql-virtual_relayrecipientmaps.cf
virtual_create_maildirsize = yes
virtual_maildir_extended = yes
virtual_mailbox_limit_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override = yes
virtual_maildir_limit_message = "The user you are trying to reach is over quota."
virtual_overquota_bounce = yes
proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps
smtpd_sender_restrictions = check_sender_access mysql:/etc/postfix/mysql-virtual_sender.cf
smtpd_client_restrictions = check_client_access mysql:/etc/postfix/mysql-virtual_client.cf
maildrop_destination_concurrency_limit = 1
maildrop_destination_recipient_limit = 1
virtual_transport = maildrop
header_checks = regexp:/etc/postfix/header_checks
mime_header_checks = regexp:/etc/postfix/mime_header_checks
nested_header_checks = regexp:/etc/postfix/nested_header_checks
body_checks = regexp:/etc/postfix/body_checks
content_filter = amavis:[127.0.0.1]:10024
receive_override_options = no_address_mappings
message_size_limit = 0

disable_vrfy_command = yes
smtpd_helo_required = yes
smtpd_helo_restrictions = permit_mynetworks, reject_invalid_hostname, permit

4) Create a file named "spamtrap" in the /etc/postfix/ directory.
This serves as a filter. If spam is emailed to this address and other addresses on your machine, it will drop that email so that it doesn't get to any other mailboxes.

spamtrap file looks like this:
/emailcontrol.*@derekgordon\.com/ DISCARD
5) Open up local.cf for SpamAssassin and add the following bit.
It will be an extra filter designed to work with SA more than it is with general Postfix.

nano /etc/spamassassin/local.cf
Add the following to the bottom:
urirhssub URIBL_BLACK multi.uribl.com. A 2
body URIBL_BLACK eval:check_uridnsbl('URIBL_BLACK')
describe URIBL_BLACK Contains an URL listed in the URIBL blacklist
tflags URIBL_BLACK net
score URIBL_BLACK 3.0


6) Restart Postfix and Spamassassin
/etc/init.d/postfix restart
/etc/init.d/spamassassin restart

7) Copy the mailgraph CGI script to your websites CGI-BIN:
cp -p /usr/lib/cgi-bin/mailgraph.cgi /var/www/www.example.com/cgi-bin

8) Create and CHMOD the postfix_report.sh script:
nano /usr/local/sbin/postfix_report.sh

Paste the following into the script:
#!/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

pflogsumm /var/log/mail.log | formail -c -I"Subject: Mail Statistics" -I"From: maillog@example.com" -I"To: youremail@yourdomain.com" -I"Received: from www.example.com ([ 127.0.0.1])" | sendmail youremail@yourdomain.com

##gzip /var/log/mail.log.0
exit 0

chmod 755 /usr/local/sbin/postfix_report.sh

9) Edit the RSYSLOG file so that your mail.log rotates daily and to set up an automatic email with postfix statistics:
nano /etc/logrotate.d/rsyslog

Delete the line that says /var/log/mail.log and add this at the VERY bottom of the file:

/var/log/mail.log
{
rotate 7
daily
missingok
notifempty
delaycompress
compress
prerotate
/usr/local/sbin/postfix_report.sh > /dev/null
endscript
postrotate
invoke-rc.d rsyslog reload > /dev/null
endscript

No comments:

Post a Comment