Based on Debian 11 "Bullseye" environment.


milter-greylist will provide the greylisting and some additional functionalities.
Greylisting is one of the powerful protection from spam, but too strong to apply to all connections. The milter-greylist can handle when to use greylist based on SPF checks.


# apt install milter-greylist


To run milter-greylist

Unfortunately, there is a long-lasting issue. Some tweaks are required to make milter-greylist work with Postfix.

The socket location in greylist.conf has to be changed from the example.

# For sendmail use the following two lines
#socket "/var/run/milter-greylist/milter-greylist.sock" # Comment out sendmail configuration
#user "smmsp"                                           # Comment out sendmail configuration

# For Postfix uncomment the following two lines and comment out the
# sendmail ones above.
#socket "/var/run/milter-greylist/milter-greylist.sock" 660
socket "/var/spool/postfix/milter-greylist/milter-greylist.sock" 660 # Add socket location
#user "postfix"

Greylisting configuration

milter-greylist has many capabilities. `man milter-greylist` will give you what it will do, and `man greylist.conf` will give you the full explanation.
In this case, configure /etc/milter-greylist/greylist.conf to act as follows.

  • Log to syslog
  • Localhost is whitelisted
  • Servers with "SPF pass" will be whitelisted
    • Except for "SPF self": This is milter-greylist original SPF result. If SPF test passes with a bad record, for example, "+all". The milter-greylist will detect it as "SPF self".
  • Every mail other than above will be greylisted.
  • Greylist interval time is 2minutes
# Log milter-greylist activity to a file
#stat ">>/var/milter-greylist/greylist.log" \
#      "%T{%Y/%m/%d %T} %d [%i] %f -> %r %S (ACL %A) %Xc %Xe %Xm %Xh\n"
# Same, sent to syslog # Uncomment below
stat "|logger -p" \
      "%T{%Y/%m/%d %T} %d [%i] %f -> %r %S (ACL %A) %Xc %Xe %Xm %Xh"

* snip *

# Your own network, which should not suffer greylisting
list "my network" addr { ::1/128 }    # Add IPv6

* snip *

# Add localaddr, greylist configuration lines below
# Add global address for this server to enable "SPF self"

# Greylist delay time
greylist 2m

racl continue from /.*/ addheader "X-Greylist: inspected by %V for IP:'%i' DOMAIN:'%d' HELO:'%h' FROM:'%f' RCPT:'%r'"

# And here is the access list
racl whitelist list "my network"
racl greylist spf self
racl whitelist spf pass
racl greylist default
  • You will see "milter-greylist: GeoIP is not available" every time, but please ignore it. Adding geoipdb config used to eliminate this error log, but now it doesn't work.
    From milter-greylist 4.6.3 (available from Bookworm), GeoIP2 is available. If you really need GeoIP for the filtering consider getting the package from Bookworm.

Now, milter-greylist should be ready to start.

# systemctl restart milter-greylist

Configure Postfix

Configure Postfix to use milter-greylist as one of the milters.
Add the following line to /etc/postfix/

# milter
milter_default_action = accept
smtpd_milters = unix:/milter-greylist/milter-greylist.sock
  • milter_default_action specifies how Postfix should act when milter has errors. Postfix will reject the mail with tempfail, asking for resending by default.
    See details on the official site

To connect to the milter-greylist socket, Postfix has to join the group greylist.

# adduser postfix greylist
# systemctl restart postfix


Now Postfix should transfer the mail to milter-greylist before Dovecot. Send a mail and see the logs and received mail headers if the milter-greylist is working.
For trouble shooting, there is log level parameter in /etc/milter-greylist/greylist.conf

# Be verbose (or use -v flag)

Additional ACLs

Authentication-Results header

The milter-greylist does check SPF, but doesn't provide the "Authentication-Result" header. If you need this standard header, it can be added with some "addheader" tricks.
To add the 7 standard SPF result, add racl lines below.

racl whitelist list "my network"
racl continue spf self addheader "Authentication-Results: %Mj; spf=softfail smtp.mailfrom=%f"
racl continue spf pass addheader "Authentication-Results: %Mj; spf=pass smtp.mailfrom=%f"
racl continue spf softfail addheader "Authentication-Results: %Mj; spf=softfail smtp.mailfrom=%f"
racl continue spf fail addheader "Authentication-Results: %Mj; spf=fail smtp.mailfrom=%f"
racl continue spf none addheader "Authentication-Results: %Mj; spf=none smtp.mailfrom=%f"
racl continue spf neutral addheader "Authentication-Results: %Mj; spf=neutral smtp.mailfrom=%f"
racl continue spf error addheader "Authentication-Results: %Mj; spf=temperror smtp.mailfrom=%f"
racl continue spf unknown addheader "Authentication-Results: %Mj; spf=permerror smtp.mailfrom=%f"
racl greylist spf self
racl whitelist spf pass
racl whitelist domain
racl whitelist domain
racl greylist default

Additional whitelisted domains

"" and "" are whitelisted in the ACL above. There are some companies using Gmail or Outlook services with (probably) incomplete configurations. Emails from those organizations fail with the SPF test.
The more serious issue is, Google and Microsoft will try re-sending the mail after the temporary failure (greylisted). If there is only one IP address they use, the second attempt should pass the greylisting, but the IP address will change every time, and every attempt looks like the first contact to this server. This process goes into the infinity loop of greylisting - resending and fails eventually.

So please check if your mail configuration is really good enough even if you're using one of the major services. All your emails might be recognized as spam...

Update History


  • Add explanation to enable Authentication-Results header.


  • Update configurations to align with Bullseye.
  • An additional explanation for the whitelisted google and outlook domains.