Is Greylisting Still Effective Against Spam in Modern Email Servers? A Technical Deep Dive for Developers


2 views

Greylisting temporarily rejects emails from unknown senders with a 4XX SMTP response code (typically 451 4.7.1). Legitimate MTAs will retry delivery after a delay (usually 15-30 minutes), while many spam bots won't. Here's a basic Postfix implementation:


# /etc/postfix/main.cf
smtpd_recipient_restrictions = 
    check_policy_service unix:private/policy,
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination

# /etc/postfix/master.cf
policy    unix  -       n       n       -       -       spawn
    user=greylist argv=/usr/local/bin/greylist.pl

By 2012, we observed:

  • Advanced spammers implemented retry logic mimicking legitimate MTAs
  • Botnets using persistent connections bypassed greylisting entirely
  • Cloud-based spam platforms (e.g., compromised AWS instances) had proper retry mechanisms

A Python script to analyze greylisting effectiveness:


import re
from collections import defaultdict

def analyze_mail_log(log_path):
    retry_pattern = re.compile(r'status=deferred.*451 4.7.1')
    success_pattern = re.compile(r'status=sent')
    
    stats = defaultdict(int)
    
    with open(log_path) as f:
        for line in f:
            if retry_pattern.search(line):
                stats['deferred'] += 1
            elif success_pattern.search(line):
                stats['delivered'] += 1
    
    effectiveness = stats['deferred'] / (stats['deferred'] + stats['delivered'])
    return f"Greylisting blocked {effectiveness:.1%} of suspicious traffic"

For 2012-era protection, combine greylisting with:


# Postfix + SpamAssassin + ClamAV combo
smtpd_milters = inet:127.0.0.1:8892
non_smtpd_milters = $smtpd_milters
milter_default_action = accept
milter_protocol = 6

content_filter = scan:127.0.0.1:10025
receive_override_options = no_address_mappings

Greylisting databases can grow large. This SQLite maintenance script helps:


#!/bin/bash
# Clean old greylist entries
sqlite3 /var/lib/greylist.db <

For high-volume servers, consider Redis instead:


import redis
import time

r = redis.StrictRedis()

def check_greylist(sender, recipient):
    key = f"grey:{sender}:{recipient}"
    if r.exists(key):
        return True
    r.setex(key, 86400, int(time.time()))
    return False

html

Greylisting, once a silver bullet against spam in the early 2000s, works by temporarily rejecting emails from unknown senders with a 4xx SMTP code. Legitimate MTAs will retry delivery after the delay period (typically 5-15 minutes), while many spam bots won't.

In 2024, greylisting remains partially effective but with significant limitations:

  • Advanced spamming networks now implement retry logic (AWS SES, SendGrid templates)
  • Botnets often use persistent connections to bypass greylisting
  • Cloud-based email services automatically handle temporary failures

Here's a Postfix greylisting configuration that still works for about 40-60% of spam:

# /etc/postfix/main.cf
smtpd_recipient_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination,
    check_policy_service unix:private/policy,
    reject_rbl_client zen.spamhaus.org

# Greylisting policy service
policy_time_limit = 3600

For comprehensive protection, combine greylisting with:

# Rspamd configuration snippet (modern alternative)
modules {
    greylist {
        expire = 1d;
        timeout = 5m;
    }
    rbl {
        rules {
            SPAMHAUS_XBL {
                rbl = "xbl.spamhaus.org";
            }
        }
    }
    neural {
        enabled = true;
    }
}

On high-volume servers, greylisting can cause:

  • Increased disk I/O from greylist databases
  • Delayed delivery for legitimate emails
  • Additional DNS lookups for RBL checks

Greylisting still provides value as part of a layered defense, but shouldn't be your primary anti-spam measure in 2024. Combine it with:

  • Machine learning filters (SpamAssassin, Rspamd)
  • Strict SPF/DKIM/DMARC policies
  • IP reputation services