Learn Mailserver - Anti-Spam: SpamAssassin & RBL
Episode 14 of 23

Learn Mailserver - Anti-Spam: SpamAssassin & RBL

Fighting spam on three layers: rejecting well-known IPs via RBL/DNSBL at the start of the connection, forcing servers to talk with proper helo and identity, then scoring email content with SpamAssassin including bayes learning and greylisting to suppress incoming spam.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Introduction

A mail server that lives on the internet will be bombarded with spam from the very first minute. Previous episodes prepared the authentication gate; now we build layered defense against spam.

The strategy has three layers: RBL/DNSBL rejects well-known IPs at the start of the connection, SpamAssassin scores email content with rule-based scoring, and greylisting slows down the impatient senders that typify spammers. We'll also learn to make SpamAssassin "learn" from the email you mark.

Spam Sources and Layered Strategy

Spam comes from many sources: known IPs, botnets, new domains, and deceptive content. No single filter catches everything. The concept of defense in depth means each layer filters a portion:

  1. Reject at connection — IP on an RBL list, no helo, or bad reputation.
  2. Reject at recipient — unknown recipient (already handled in episode 10).
  3. Score content — SpamAssassin scores and flags.
  4. Test behavior — greylisting filters automated senders.

The earlier a decision is made, the fewer resources it uses — so the first layer is always the cheapest.

RBL/DNSBL: Reject at the Gate

RBL (Realtime Blackhole List) / DNSBL (DNS-based Blackhole List) are lists of IPs or domains known for sending spam. Rejection is done with a simple DNS query to the list server, for example Zen Spamhaus. In Postfix, install it via smtpd_recipient_restrictions:

Enable Zen Spamhaus RBL
sudo postconf -e 'smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_rbl_client zen.spamhaus.org, permit'
sudo postfix reload

reject_rbl_client zen.spamhaus.org rejects connections from IPs listed in that list. Note the order: after the recipient is validated, the RBL is checked — this order prevents internal IPs (permit_mynetworks) from being caught by the RBL.

Test that the RBL works:

Test RBL with a known IP
postmap -q 127.0.0.2 zen.spamhaus.org

127.0.0.2 is a test IP that's always listed on Zen; if the query returns a value, your DNSBL connection works.

SpamAssassin: Scoring Content

SpamAssassin examines email headers and body, then scores it based on hundreds of rules. Email scoring above a threshold (usually 5.0) is flagged as spam. Install and enable it:

Install SpamAssassin
sudo apt install -y spamassassin
sudo systemctl enable spamassassin

SpamAssassin integrates with Postfix in one of two ways: via a milter, or via a content filter (usually Amavis — episode 15). For now, the core configuration is in /etc/spamassassin/local.cf:

plaintext
required_score 5.0
rewrite_header Subject [SPAM]
report_safe 0
  • required_score — the score threshold to be considered spam.
  • rewrite_header — marks the subject so it's visible.
  • report_safe 0 — deliver the original email with added headers, not a separate report.

Test SpamAssassin with a sample message:

Test the score with a sample message
spamassassin -t < /tmp/contoh-email.txt | grep -i score

Bayes Learning: Making the Filter Learn

SpamAssassin's strength is bayes: it learns from the email you mark. The more it's trained, the more accurate its scores. Train it with sa-learn:

Train bayes from the spam folder
sa-learn --spam /var/mail/vhosts/example.com/admin/Maildir/.Junk/cur/
sa-learn --ham /var/mail/vhosts/example.com/admin/Maildir/cur/

Every time a user marks email as spam (--spam) or not-spam (--ham), add it to the corpus. Choose the right folder — in Roundcube, the spam folder is usually named .Junk or Spam.

Greylisting with Postgrey

Greylisting temporarily rejects email from unknown servers (the sender-IP/sender/recipient triplet) and asks for a redelivery a few minutes later. Legitimate mail servers will retry; automated spammers usually won't. Install Postgrey:

Install Postgrey
sudo apt install -y postgrey

Then add it to the restrictions:

Enable greylisting
sudo postconf -e 'smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_rbl_client zen.spamhaus.org, check_policy_service inet:127.0.0.1:10023, permit'
sudo postfix reload

check_policy_service inet:127.0.0.1:10023 contacts Postgrey for the triplet decision. The first connection is delayed a few minutes; legitimate senders retry, mass spammers don't.

Tip

Don't greylist local senders — add a skip for internal subnets. And remember, greylisting adds latency; for critical communication that needs instant response, consider whitelisting certain domains or IPs.

Assembling Complete Defense

Combine all four layers into one coherent policy:

Complete anti-spam policy
sudo postconf -e 'smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination, reject_unknown_recipient_domain, reject_rbl_client zen.spamhaus.org, check_policy_service inet:127.0.0.1:10023, permit'
sudo postconf -e 'smtpd_helo_required = yes'
sudo postfix reload

Note the additions reject_unknown_recipient_domain (rejects destination domains that don't resolve) and smtpd_helo_required (forces clients to speak with a helo). Monitor the impact in the logs — episode 19 covers how to read each layer's effect.

Conclusion

Episode 14 is done. Key takeaways:

  • Layered defense: reject IPs (RBL), score content (SpamAssassin), test behavior (greylisting).
  • reject_rbl_client zen.spamhaus.org rejects well-known IPs at the gate.
  • SpamAssassin scores with rules; bayes learns from sa-learn.
  • Greylisting slows down automated senders; legitimate senders retry.
  • The order in smtpd_recipient_restrictions determines effectiveness and performance.

Spam is fought on three layers. In episode 15 we add the final layer: Antivirus & Content Filtering — ClamAV and Amavis — scanning every email for viruses and malware before it enters the mailbox. See you in episode 15!

Learn Mailserver - Anti-Spam: SpamAssassin & RBL | Learn Mailserver