From Smop.co.uk
Contents |
Basic MTA
I chose postfix as the MTA since I prefer the configuration to that of Exim - it's more modular and a better security model (and track record).
- install postfix and maildrop
- edit main.cf:
myhostname = mail.smop.co.uk
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = smop.co.uk, localhost, localhost.localdomain, localhost
relayhost =
mynetworks = 127.0.0.0/8 192.168.100.0/23
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
sender_canonical_maps = hash:/etc/postfix/sender_canonical
mailbox_command = /usr/bin/maildrop -d ${USER}
# change foo.smop.co.uk into smop.co.uk
masquerade_domains = smop.co.uk
# for recipients as well as senders
masquerade_classes = envelope_sender, envelope_recipient,
header_sender, header_recipient
# required since we are behind NAT
proxy_interfaces = 81.5.177.201
# use Maildir (ends in "/")
home_mailbox = Maildir/
Anti spam
Misc lockdown
Some additional lockdown in /etc/postfix/main.cf:
# this rule is too stringent to use # strict_rfc821_envelopes = yes # try to stop email address harvesters disable_vrfy_command = yes
HELO verification
- in /etc/postfix/main.cf:
# HELO restrictons smtpd_delay_reject = yes smtpd_helo_required = yes smtpd_helo_restrictions = permit_mynetworks, # reject people pretending to be us check_helo_access regexp:/etc/postfix/helo_regexp, reject_non_fqdn_hostname, reject_invalid_hostname, permit # reject_unknown_hostname (no A or MX record)
- /etc/postfix/helo_regexp:
# reject people claiming to be me #/whitlisted/ OK /smop\.co\.uk$/ 550 you are not me /^\[?127\./ 550 bad helo (localhost) /^\[?81\.5\.177\.201\]?/ 550 bad helo
- run "postmap /etc/postfix/helo_regexp" after altering this file
GLD
Much though I don't like the delay, greylisting (where you reject any new connections with a temporary error) is an effective anti-spam technique - most bots do not retry.
There is so much information out there, I spent most of my time figuring out which programs to use! There is some useful information in this comparison
- postfix-smtpguard - old and is for throttling
- postfix-policyd - seems old, but powerful
- postgrey - written in perl
- postfix-gld - more flexible than postgrey, written in C
- policyd-weight - er, um. postfix-gld seems more widely used
To setup postfix-gld:
- install postfix-gld
- /etc/defaults/gld
- ENABLED=1
- /etc/gld.conf (only changes listed):
ERRACCEPT=0 SQLHOST=localhost SQLUSER=.... SQLPASSWD=.... SQLDB=gld
- setup mysql
- /etc/init.d/gld start
- we will use this later in /etc/postfix/main.cf
- look for the "check_policy_service inet:127.0.0.1:2525" line
Sender restrictions
We block bad sender in /etc/postfix/main.cf:
# sender restrictions smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_non_fqdn_sender, reject_unknown_sender_domain, permit
/etc/postfix/sender_access contains this:
# mynetworks and sasl have already been accepted # by the time we reach this file, so this is a forgery smop.co.uk REJECT 554 forgery detected
Ensure you run "postmap /etc/postfix/sender_access" after editing the file.
Recipient restrictions
We reject unknown and bad recipients as well in /etc/postfix/main.cf (as well as ensuring that we are not an open relay):
# recipient restrictions smtpd_recipient_restrictions = reject_unknown_recipient_domain, permit_mynetworks, # reject clients which do not wait for responses reject_unauth_pipelining, # allow non-fqdn from mynetworks (by ensuring that is listed first) reject_non_fqdn_recipient, permit_sasl_authenticated, # stops us from being an open relay reject_unauth_destination, check_sender_access hash:/etc/postfix/sender_access, check_recipient_access hash:/etc/postfix/recipient_access, # reject unknown (local) recipients before expensive filters reject_unverified_recipient, # reject_rbl_client list.dsbl.org, # reject_rbl_client sbl-xbl.spamhaus.org, #check_policy_service unix:private/spfpolicy, check_policy_service inet:127.0.0.1:2525
/etc/postfix/recipient_access is actually empty ATM, however you still need to run "postmap /etc/postfix/recipient_access"
"check_policy_service" call the greylisting daemon we setup earlier.
Amavisd-new
There are two main ways to despam email in postfix:
- pre-queue (postfix does content filter, then accepts email)
- nice - you can reject the email during SMTP conversation (no bounces)
- but you must be able to do this _quickly_
- "smtpd_proxy_filter" is main keyword
- post-queue (postfix accepts email, then content filters)
- "content_filter" is the main keyword
- you can only scan outgoing email by replacing "content_filter" with "permit_mynetworks, check_client_access regexp:outgoing_filter", where /etc/postfix/outgoing_filter is "FILTER scan:localhost:100024"
In both cases, email comes into postfix on port 25, then to amavisd-new on 10024 then back into postfix on port 10025. Packages to install are: clamav, amavisd-new spamassassin, clamav-daemon libmail-spf-query-perl pyzor razor dcc-client spamc
Local processes uses "pickup" not "smptd" daemon and thus skip this processing.
Postqueue
I am not currently using post-queue processing, but did initially set it up.
In /etc/postfix/main.cf:
# send to amavisd-new (which listens on 10024) content_filter = scan:localhost:10024 # no aliases or mapping - so filter sees original addresses # the postfix listening on port 10025 will _not_ have this set receive_override_options = no_address_mappings
Then add to /etc/postfix/master.cf:
# for post-queue filtering
# allow ten scans at once - must not be larger than daemons on port 10026
scan unix - - n - 10 smtp
# try to ensure original IPs are kept
-o smtp_send_xforward_command=yes
# just incase filters mangle 8BITMIME
-o disable_mime_output_conversion=yes
# avoid rewriting with generic(5) maps (when email is sent)
-o smtp_generic_maps=
Prequeue processing
This is currently technique I am using. Note that we must start more postfix instances listening on port 10025 than we have talking to amavisd (aka smtpd_proxy_filter). We also increase the timeout to the smtpd_proxy from the default 100secs to 300sec (otherwise the sender will see a "451: queue file write" error.
In /etc/postfix/master.cf, change the "smtp" definition and add a new "localhost:10025" definition as follows:
smtp inet n - - - 10 smtpd
# send email to a pre-queue filter (amavisd-new)
-o smtpd_proxy_filter=127.0.0.1:10024
# prevent one client from using all 10 connections
-o smtpd_client_connection_limit=5
# increase timeout (100s default) to prevent 451: queue file write errors
-o smtpd_proxy_timeout=300s
# second postfix instance to accept replies from filter
127.0.0.1:10025 inet n - - - 10 smtpd
# skip checks which have already been done
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks,no_milters
-o smtpd_helo_restrictions=
-o smtpd_client_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
ClamAV
- add "AllowSupplementaryGroups true" to /etc/clamav/clamd.conf if not present
- "adduser clamav amavis"
- uncomment bypass_spam_checks_maps line in /etc/amavis/conf.d/15-content_filter_mode
- TODO: /var/lib/amavis/virusmails needs cleaning from time to time
ClamAV anti-spam. Downloaded script4 from http://www.sanesecurity.co.uk/clamav/usage.htm and added to cron.daily. On my "low scoring spam and missed spam" folder clam detected 13/600 emails before running this script, afterwards it was 334/600. Two things need altering in the script:
- clamd_dbdir=/var/lib/clamav
- comment out script_not_configured=1
SpamAssassin
- setting "bayes_auto_expire = 0;" will stop the database growing too large (not done)
- uncomment bypass_virus_checks_maps line in /etc/amavis/conf.d/15-content_filter_mode
- edit /etc/amavis/conf.d/50-user:
# See /usr/share/doc/amavisd-new/ for documentation and examples of
# the directives you can use in this file
# add X-Spam-Score, X-Spam-Status, X-Spam-Level above this:
#$sa_tag_level_deflt = -999;
$sa_tag_level_deflt = undef;
# adds X-Spam-Flag, X-Spam-Report above this:
$sa_tag2_level_deflt = 6.31;
# string to prepend to Subject header field when message exceeds tag2 level
$sa_spam_subject_tag = "SPAM: ";
# multi-line headers with explanations (X-Spam-Report) (only if >= tag2)
# $sa_spam_report_header = 1;
# char for X-Spam-Level: header, defaults to '*';
$sa_spam_level_char = '*';
# NB: @local_domains_acl never get tagged (or scanned)
@local_domains_acl = (".smop.co.uk");
# I use fetchmail for my dads email, so I tell fetchmail to deliver to the private 192.168.x.x IP
# and add only 127.0.0.1 to exclude list (rather than the whole 192.168.* too)
@mynetworks = qw( 127.0.0.0/8 [::1]);
@mynetworks_maps = (\@mynetworks);
# override default spam from D_BOUNCE to D_PASS (or D_DISCARD (quarantine))
$final_spam_destiny = D_PASS;
#------------ Do not modify anything below this line -------------
1; # insure a defined return
IMAP(S)
There were three contenders for the IMAP server:
- bincimap (last updated 2005)
- courier (lots of negative comments re courier vs dovecot - speed, security)
- dovecot
So I went with Dovecot:
- apt-get install dovecot-imapd
- edit /etc/dovecot/dovecot.conf:
- protocols = imap imaps pop3 pop3s
- mail_location = maildir:~/Mail
- maildir_copy_with_hardlinks=yes
- # TODO: disable_plaintext_auth = yes
Mailbox conversion
I used to store my email in Mailbox format so I needed to convert into MailDir format (faster, safer). Download mb2bd:
- to change /var/spool/mail/adrian into ~/Maildir/(cur|new|tmp)
- mb2md -m
- to change /home/adrian/oldmbox into ~/Maildir/.thing/(cur|new|tmp)
- md2md -s /home/adrian/oldmbox -R
