SpamAssassin Configuration Tips

I just moved the first users over to my Virtualmin server and SpamAssassin as it is configured by default on Debian 12 is definitely not hitting enough of the spam – one client is getting inundated by dozens of messages an hour that the old filter (ASSP) was able to catch.

So, I’ve tried to accumulate some tweaks to the server (while trying not to break anything Virtualmin automates) to see if I could stem the tide. So far it isn’t enough, so I was hoping to share what I’ve done and see if there’s some obvious things I’m missing. (The biggest one, I suspect, was suggested to me in another thread on here – postscreen – but I’m trying to get my head around how to use it without messing up general user usage of SMTP, etc.)

Any tips on what seems to work to (relatively aggressively) fight spam, I’m all ears. A lot of threads I’ve found on here or elsewhere seem to be from many years ago, with links to additions to SpamAssassin that are no longer supported.

Here’s what I’ve done so far. In postfix, I’ve added/enabled OpenDMARC, OpenDKIM, policyd-spf and two core RBLs:

smtpd_recipient_restrictions = permit_mynetworks,   permit_sasl_authenticated,   reject_unauth_destination,  check_policy_service unix:private/policyd-spf, check_policy_service inet:127.0.0.1:10023,
   reject_rhsbl_helo dbl.spamhaus.org,
   reject_rhsbl_reverse_client dbl.spamhaus.org,
   reject_rhsbl_sender dbl.spamhaus.org,
   permit_dnswl_client list.dnswl.org=127.0.[0..255].[1..3],
   reject_rbl_client zen.spamhaus.org,
   reject_rbl_client bl.spamcop.net

Jumping down the config a bit:

milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:127.0.0.1:8891,inet:127.0.0.1:8893
non_smtpd_milters = inet:127.0.0.1:8891,inet:127.0.0.1:8893

(I haven’t successfully verified OpenDMARC is working yet. The tests always seem to stop with OpenDKIM.)

And a few other seemingly wise filters:

smtpd_sender_restrictions =
   permit_mynetworks
   permit_sasl_authenticated
   reject_unknown_reverse_client_hostname
   reject_unknown_client_hostname

smtpd_helo_required = yes
smtpd_helo_restrictions =
    permit_mynetworks
    permit_sasl_authenticated
    reject_invalid_helo_hostname
    reject_non_fqdn_helo_hostname
    reject_unknown_helo_hostname

On the SpamAssassin side, I compiled DCC and also installed Pyzor and Razor. I then added the following rules:

razor_config /etc/mail/spamassassin/.razor/razor-agent.conf
pyzor_options --homedir /etc/mail/spamassassin
#pyzor_add_header 1

use_dcc 1
# When using dccifd, socket will be search from dcc_home
dcc_home /var/dcc
dcc_timeout 8
# If not using dccifd, dccproc is used
dcc_path /usr/local/bin/dccproc

# RAZOR seem to be getting overruled by other parts of SA, so increase impact.
score RAZOR2_CHECK 2.0
score RAZOR2_CF_RANGE_51_100 3.0
score RAZOR2_CF_RANGE_41_50 2.5
score RAZOR2_CF_RANGE_31_40 2.0
score RAZOR2_CF_RANGE_21_30 1.5
score RAZOR2_CF_RANGE_11_20 1.0
score RAZOR2_CF_RANGE_1_10 0.5

# From https://www.linuxbabe.com/redhat/spamassassin-centos-rhel-block-email-spam
score PDS_FROM_2_EMAILS 3.0
score EMPTY_MESSAGE 3.5
score FREEMAIL_DISPTO 2.0
score FREEMAIL_FORGED_REPLYTO 3.5
score DKIM_ADSP_NXDOMAIN 5.0
score FORGED_GMAIL_RCVD 2.5

header    CUSTOM_DMARC_FAIL   Authentication-Results =~ /dmarc=fail/
describe  CUSTOM_DMARC_FAIL   This email failed DMARC check
score     CUSTOM_DMARC_FAIL   3.0

body      BOUNCE_MSG    /(Undelivered Mail Returned to Sender|Undeliverable|Auto-Reply|Automatic reply)/i
describe  BOUNCE_MSG    Undelivered mail notifications or auto-reply messages
score     BOUNCE_MSG    -1.5

header RCVD_IN_BRBL eval:check_rbl('brbl-lastexternal', 'b.barracudacentral.org.', '127.0.0.2')
describe RCVD_IN_BRBL Received via relay listed in Barracuda RBL
score RCVD_IN_BRBL 1.0
tflags RCVD_IN_BRBL net
SYSTEM INFORMATION
OS type and version Debian 12
Webmin version 2.111
Virtualmin version 7.20.1
Webserver version NGINX 1.18.0/Apache 2.4.52
Related packages DCC, Pyzor, Razor, OpenDMARC, OpenDKIM

In Virtualmin → DNS Settings → DNS Options are the settings for SPF action for other senders. I set it to Disallow. There is also DMARC policy for emails that fail SPF or DKIM which I set to Quarantine.

In Virtualmin → Email Settings, there is Email Greylisting.

Thanks, @Calport. I think I have all the right things turn on there, I hope.

Incidentally, I’m starting to wonder if somehow SpamAssassin isn’t actually filtering the e-mail. If I look at headers in e-mail received, I don’t see any SA headers, which seems odd… maybe the issue SpamAssassin per se but somehow e-mail not running through SA? (It looks enabled from the Virtualmin side, but I’d expect headers on the e-mail indicating the spam score – positive or negative as it may be – etc., and I don’t see those…)

You don’t see something like this?

Return-Path: <interglobe@marketing.goindigo.in>
X-Spam-Checker-Version: SpamAssassin on vps.indiax.com
X-Spam-Level:
X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,
        DKIM_VALID,DKIM_VALID_AU,HTML_FONT_LOW_CONTRAST,HTML_MESSAGE,
        RCVD_IN_DNSWL_NONE,RCVD_IN_ZEN_BLOCKED_OPENDNS,SPF_HELO_NONE,SPF_PASS,
        URIBL_DBL_BLOCKED_OPENDNS,URIBL_ZEN_BLOCKED_OPENDNS autolearn=ham
        autolearn_force=no version=3.4.6
X-Original-To: niel@calport.com

No, it seems to be missing… that should show even on non-spam, correct?

Yes it should show as you can see from the screenshot the message scored 2 and the spam threshold is a score of 5

Yes, there’s no sign of those headers. It appears that SpamAssassin is enabled on every e-mail account, so I’m not sure why it isn’t actually running…

Try
journalctl -t spamd --since "1 hour ago"
and
systemctl status spamassassin
to ensure that spamd is running
and that the virtualmin config looks like this


EDIT
you may need/want to remove the --since "1 hour ago" if you get no results from journalctl

1 Like

my policy section of my postfix config. I spent a lot of time reading the official docs and this is the correct baseline config that we should all be using. Each of the settings are no in their correction section. You will read somepeople say put this setting here it still works, well this is a legacy thing and will be rmeoved in postfix v3.9 (of top of my head)

smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unknown_client_hostname
smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_helo_hostname
smtpd_sender_restrictions = reject_non_fqdn_sender, reject_unknown_sender_domain
smtpd_recipient_restrictions = reject_non_fqdn_recipient, reject_unknown_recipient_domain
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_data_restrictions = reject_unauth_pipelining

There are more settings and you cannot set all these by the GUI becasue there are some bugs

see: My Virtualmin Notes | QuantumWarp

1 Like

Thanks. I’m not seeing anything of note since yesterday morning as far as filtering. It does appear it was adding headers up to that point. I tried to manually run a spam through spamc, connecting to spamd, and if I do that, I do see those attempts in the logs, e.g, like this:


Jul 21 06:57:36 ---.-----.com spamd[1220358]: spamd: connection from localhost [::1]:50990 to port 783, fd 5
Jul 21 06:57:36 ---.-----.com spamd[1220358]: spamd: setuid to root succeeded
Jul 21 06:57:36 ---.-----.com spamd[1220358]: spamd: still running as root: user not specified with -u, not found, or set to root, falling back to nobody
Jul 21 06:57:36 ---.-----.com spamd[1220358]: spamd: processing message <00e101dadabd$9489bda0$bd9d38e0$@com> for root:65534
Jul 21 06:57:36 ---.-----.com spamd[1220358]: check: dns_block_rule RCVD_IN_VALIDITY_SAFE_BLOCKED hit, creating /root/.spamassassin/dnsblock_sa-accredit.habeas.com (This means DNSBL blocked you due to too many queries. Set all affected rules score to 0, or use "dns_query_restriction deny sa-accredit.habeas.com" to disable queries)
Jul 21 06:57:36 ---.-----.com spamd[1220358]: check: dns_block_rule RCVD_IN_VALIDITY_CERTIFIED_BLOCKED hit, creating /root/.spamassassin/dnsblock_sa-trusted.bondedsender.org (This means DNSBL blocked you due to too many queries. Set all affected rules score to 0, or use "dns_query_restriction deny sa-trusted.bondedsender.org" to disable queries)
Jul 21 06:57:36 ---.-----.com spamd[1220358]: check: dns_block_rule RCVD_IN_VALIDITY_RPBL_BLOCKED hit, creating /root/.spamassassin/dnsblock_bl.score.senderscore.com (This means DNSBL blocked you due to too many queries. Set all affected rules score to 0, or use "dns_query_restriction deny bl.score.senderscore.com" to disable queries)
Jul 21 06:57:36 ---.-----.com spamd[1220358]: plugin: eval failed: bayes: (in learn) locker: safe_lock: cannot create tmp lockfile /root/.spamassassin/bayes.lock.---.-----.com.1220358 for /root/.spamassassin/bayes.lock: Permission denied
Jul 21 06:57:36 ---.-----.com spamd[1220358]: spamd: clean message (-0.1/5.0) for root:65534 in 0.4 seconds, 13603 bytes.
Jul 21 06:57:36 ---.-----.com spamd[1220358]: spamd: result: .  0 - DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DMARC_PASS,FREEMAIL_FROM,HTML_MESSAGE,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE scantime=0.4,size=13603,user=root,uid=65534,required_score=5.0,rhost=localhost,raddr=::1,rport=50990,mid=<00e101dadabd$9489bda0$bd9d38e0$@com>,autolearn=unavailable autolearn_force=no
Jul 21 06:57:36 ---.-----.com spamd[1220319]: prefork: child states: II

Have you altered the delivery agent? Without procmail-wrapper and procmail, you won’t have any Virtualmin-managed spam filtering features working.

1 Like

Oh! I just found this particular issue: when so much spam was getting through, I upped the size of messages for SpamAssassin to scan to 1 MB rather than 512KB. However, I should say that’s what I meant to do, not what I did: I left it KB, but thought it was MB, so I wasn’t filtering anything over 1KB in size. :man_facepalming:

3 Likes

Thank you. I’ll give these a try tomorrow… now that I have it actually scanning all messages under 1 MB and not 1 KB (!), as I mentioned just above, I’m “back in business,” but I was seeing a flood of spam come in even when I was “in business” (which is why I was fiddling around and messed up that config to begin with).

Anything I can do to optimize Postfix or SpamAssassin to make them tougher on incoming spam is great.

So, I now have Postgrey, OpenDMARC and OpenDKIM running in Postfix and DCC, Razor and Pyzor running for SpamAssassin. I am seeing those errors I shared above of RBLs blocking us for overuse (although I only have two working e-mail accounts on the server right now) and also some issues with SA wanting to write data to /root/.spamassassin and having permission denied. I’m not sure if either of those would impact its performance.

Thank you, @Joe, @shoulders, @jimr1 and @calport for all the suggestions so far. I’m really grateful!

I personally run a pfsense box in-between the internet and my server, this does all my IP and Domain blocking as it is much better at it. The lists are updated more frequently. I do leave spamassassin to do blocks as it see fit from the default RBL just incase any are missed. I do not have any blocks in Postfix.

From reading people say do not use RBL in Postfix to block emails as this is a waste. Postfix are moving away from this to be a pure MTA and say this should be left to dedicated software such as spamassassain.

Only doing lookups in one place (i.e. spamassassin) stops double lookups. Maybe move your RBLs from Postfix to Spamassassain? I would be interested on your thoughts.

DCC, Razor, Pyzor - are these still supported?

The Postfix rules above are worth studying, it was very hard to get my head around chasing all the varius settings and people still thinking postfix was on v2.0 when they gave their advise :smile:

check_policy_service unix:private/policyd-spf

  • I don’t have this statement, or possibly postfix-policyd-spf-python installed. did you install this service?
  • I use a ‘test’ on spamassassain to drop emails with a failed SPF check
  • This might be useful to block emails getting sent to a domain with a dodgy SPF unless this is now part of the postfix settings. It might be worth checking. SPF is about receiving emails. :smile:

not all postfix setups are the same, on my real old server it is set like this

smtpd_base_cfg = permit_mynetworks permit_sasl_authenticated reject_unauth_destination reject_unknown_recipient_domain reject_unauth_pipelining reject_invalid_hostname
smtpd_black_list = reject_rbl_client bl.spamcop.net reject_rbl_client zen.spamhaus.org
smtpd_milter_list = check_policy_service unix:private/policy-spf
smtpd_rbl_check = check_client_access hash:/etc/postfix/rbl_override
smtpd_recipient_restrictions = $smtpd_base_cfg $smtpd_rbl_check $smtpd_black_list $smtpd_milter_list

and still works fine

This is how I would like to see the Postfix policy sections

from Remove `SMTP Client Restrictions` and create `Access restriction lists` · Issue #2171 · webmin/webmin · GitHub

1 Like

no sign of being able to have an rbl_overide there or any other hashed file that you might want to add, this although it looks nice, does not allow the user to ‘tune’ postfix to their requirements but Webmin → Servers → Postfix Mail Server → Edit Config Files already allows this to happen.

You add them into the correct field (smtpd_recipient_restrictions / Spam Blocking Policy). If you check my detailed notes all of this is explained.

The complex polices you can make for postfix are not viable with a GUI and tick boxes for these options.

I can not read your notes as I have an eye problem which means I can not read anything on a white background very well at all


anything with a green arrow is blurred anything with a red arrow is just a blur (unreadable) and the body text does not have enough contrast from the background, perhaps you need to add a dark option for people with disabilities ?

1 Like

Yes, accessibility is important and Google search rankings suffer for websites which have poor contrast or are difficult to read for people with poor vision.

For @jimr1 and others - in Google Chrome there are extensions available which can assist with websites which are not accessible by design.

See

Apologies for going a bit off topic here but this could help many and accessibility is a topic which needs more awareness.

3 Likes