Tags

Postfix Spam Protection Improvements

Overview

Implemented multi-layer spam protection for mail server at mail.keisanki.net.

1. Fixed SpamAssassin Milter Socket

Problem: SpamAssassin milter socket path was incorrect, causing spam filtering to fail.

Solution: Created proper systemd service and fixed socket path.

File: /etc/systemd/system/spamass-milter.service

[Unit]
Description=SpamAssassin Milter
After=network.target spamd.service

[Service]
Type=simple
ExecStart=/usr/sbin/spamass-milter -u spamass-milter -i 127.0.0.1 -r 15 -p /var/spool/postfix/spamass/spamass.sock
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

File: /etc/postfix/main.cf

smtpd_milters = unix:/var/spool/postfix/spamass/spamass.sock, unix:/var/spool/postfix/opendkim/opendkim.sock

File: /etc/postfix/master.cf (submission port)

submission inet n       -       y       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_milters=
  -o non_smtpd_milters=

2. Enabled Postscreen

Purpose: Early connection screening before SMTP handshake.

File: /etc/postfix/master.cf

smtp      inet  n       -       y       -       1       postscreen
smtpd     pass  -       -       y       -       -       smtpd
dnsblog   unix  -       -       y       -       0       dnsblog
tlsproxy  unix  -       -       y       -       0       tlsproxy

File: /etc/postfix/main.cf

postscreen_dnsbl_sites = zen.spamhaus.org*3
                        bl.spamcop.net
                        b.barracudacentral.org*2
postscreen_dnsbl_action = enforce
postscreen_greet_action = enforce
postscreen_blacklist_action = enforce

3. Added DNSBL Checks to Recipient Restrictions

Purpose: Second layer DNSBL checking during SMTP transaction.

File: /etc/postfix/main.cf

smtpd_recipient_restrictions =
    permit_sasl_authenticated,
    permit_mynetworks,
    reject_invalid_helo_hostname,
    reject_non_fqdn_helo_hostname,
    reject_unknown_recipient_domain,
    reject_unauth_destination,
    reject_unauth_pipelining,
    reject_rbl_client zen.spamhaus.org,
    reject_rbl_client bl.spamcop.net,
    check_policy_service unix:private/policyd-spf,
    permit

4. Enabled SPF Verification

Purpose: Verify SPF records for incoming mail.

Installation:

apt install -y postfix-policyd-spf-python

File: /etc/postfix/master.cf

policyd-spf  unix  -       n       n       -       0       spawn
    user=policyd-spf argv=/usr/bin/policyd-spf-perl

File: /etc/postfix/main.cf

smtpd_recipient_restrictions =
    ...
    check_policy_service unix:private/policyd-spf,
    permit

5. Fixed SpamAssassin Learning Script

Problem: Script didn't use --mbox flag for mbox format mailboxes.

File: /root/scripts/sa_learn_vmail.sh

if [ -d "$PATH_TO_MAIL" ]; then
    # Directory (Maildir style)
    log "INFO" "Training $TYPE_LABEL for user $USER from directory $PATH_TO_MAIL"
    sa-learn $SA_LEARN_ARGS "$PATH_TO_MAIL" >>"$LOG_FILE" 2>&1
elif [ -f "$PATH_TO_MAIL" ]; then
    # Single file (mbox style)
    log "INFO" "Training $TYPE_LABEL for user $USER from mbox file $PATH_TO_MAIL"
    sa-learn $SA_LEARN_ARGS --mbox "$PATH_TO_MAIL" >>"$LOG_FILE" 2>&1

Timer: sa-learn-vmail.timer runs daily at 03:30

6. Enabled Daily Rule Updates

Purpose: Keep SpamAssassin rules current via sa-update.

Command:

systemctl enable --now spamassassin-maintenance.timer

Timer: spamassassin-maintenance.timer runs daily around 06:00

Current Spam Protection Stack

  1. Postscreen - Early connection screening (DNSBL, greet pause, protocol tests)
  2. SMTP Restrictions - HELO validation, DNSBL checks
  3. SPF Verification - policyd-spf-python
  4. DKIM Verification - OpenDKIM (already configured)
  5. SpamAssassin - Content filtering via milter
  6. Bayesian Learning - Daily training from Junk/Sent folders
  7. Rule Updates - Daily sa-update

Verification

Check postscreen is blocking spam:

tail -f /var/log/mail.log | grep postscreen

Check SpamAssassin is filtering:

systemctl status spamass-milter

Manual training:

sa-learn --spam --mbox /var/vmail/oib/mail/Junk
sa-learn --ham --mbox /var/vmail/oib/mail/INBOX