Email

From Smop.co.uk

Jump to: navigation, search

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
Personal tools