Custom spam rules

what is proper way to add custom spam rules?
I created file
/etc/spamassassin/66_blacklist.cf
and insert there
blacklist_from *etmailservices.com
and did
systemctl restart spampd

But still, that particular rule is not working

Return-Path: <bounce-WCC4YC4TXMMUXCO322WGPH6QCE.500018@bounce.i.s50.etmailservices.com>
........
X-Spam-Report: 
	* -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at
	*      https://www.dnswl.org/, no trust
	*      [161.71.34.73 listed in list.dnswl.org]
	* -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%
	*      [score: 0.0000]
	*  2.0 DMARC_FAIL_NONE DMARC check failed (p=none)
	* -0.1 SPF_PASS SPF check passed
	*  0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record
	*  0.0 HTML_MESSAGE BODY: HTML included in message
	*  0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily
	*       valid
	* -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
	*  1.4 PYZOR_CHECK Listed in Pyzor
	*      (https://pyzor.readthedocs.io/en/latest/)
	*  0.0 LOTS_OF_MONEY Huge... sums of money
	*  0.0 T_KAM_HTML_FONT_INVALID Test for Invalidly Named or Formatted
	*      Colors in HTML
X-Spam-Score: 1.4

in other hand, when I do
spamassassin -t < test.msg
rule is working

Content analysis details:   (100.5 points, 7.0 required)

 pts rule name              description
---- ---------------------- --------------------------------------------------
-0.0 RCVD_IN_DNSWL_NONE     RBL: Sender listed at https://www.dnswl.org/,
                             no trust
                            [161.71.34.73 listed in list.dnswl.org]
 0.0 USER_IN_BLOCKLIST      From: user is listed in the block-list
 100 USER_IN_BLACKLIST      DEPRECATED: See USER_IN_BLOCKLIST
-1.9 BAYES_00               BODY: Bayes spam probability is 0 to 1%
                            [score: 0.0000]
-0.1 SPF_PASS               SPF check passed
 2.0 DMARC_FAIL_NONE        DMARC check failed (p=none)
 0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record
 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level
                            mail domains are different
 0.0 PP_MIME_FAKE_ASCII_TEXT BODY: MIME text/plain claims to be ASCII
                             but isn't
 0.1 DKIM_SIGNED            Message has a DKIM or DK signature, not necessarily
                            valid
 0.0 LOTS_OF_MONEY          Huge... sums of money
 0.1 DKIM_INVALID           DKIM or DK signature exists, but is not valid
 0.0 T_MONEY_PERCENT        X% of a lot of money for you

where is the problem then?

Is etmailservices also in the from field?

no, but as far I understand “from” in spamassassin’s sense is envelope-from, not “From:” field where anybody can write random things or leave it empty. For “From:” field I have always used some header parsing rules, not simple “blacklist_from”.
And yes, in this case, envelope-from contains “etmailservices”

Received: from xx.xx.xx ([xx.xx.xx.xx])
    by xx.xx.xx with LMTP
    id 6N49I/EoS2r7xT4AAWoIBQ
    (envelope-from <bounce-WCC4YC4TXMMUXCO322WGPH6QCE.500018@bounce.i.s50.etmailservices.com>)
    for <xx@xx.xx>; Mon, 06 Jul 2026 07:02:57 +0300

Actually in 66_blacklist.cf is many more rules, and is hard to understand what triggers where, but main problem is, why “spampd” and “spamassassin -t” results are different and why one find it’s a spam, and another does not.
If they using same config, then they should produce same result?

edit:
hmm, it seems like my 66_blacklist.cf is not totally ignored.
All of 288 rules like

blacklist_from *etmailservices.com
blacklist_from loan@us.com
blacklist_from *@cmail20.com
blacklist_from *@allbizem.eu
blacklist_from *@hubspot.com

does not work, but all rules like

header   SPAM_SUBJ_2    Subject =~ /clickandgrow/i
describe SPAM_SUBJ_2    Subject spam
score    SPAM_SUBJ_2    100.0

does work. So that’s not the file itself, but something is wrong with “blacklist_from” part of it. “spamassassin --lint” not finding any errors …

What is the working way to describe custom “envelope-from” blacklist/whitelist rules?
Can it be that Postfix send incomplete headers to the spampd?

If the linter says it’s ok and other rules are used, the config seems ok. Spampd simply forwards the rules to spamassassin.
Spamassassin documentation states the following fields are checked
Resent-From
Envelope-Sender
Resent-Sender
X-Envelope-From
From

You mention slightly different fields. Could this explain the difference?

I don’t know from where these names coming from, but I have never noticed them in email headers.

For example, I scanned all my 528214 emails in MIAB server, and “Envelope-Sender” is not found in any of them.

X-Envelope-From: is in some, but it seems to be related to forwarded messages from few particular mail services, etc.

In my previous mail server (sendmail+MailScanner) everything was working, and it even added header
X-MailScanner-From: name@domain.tld
where was what it’s thinking this mail coming from. Very easy to follow.
It was always envelope-from or also known as “MAIL FROM: recipient@domain.tld” line in SMTP protocol. Didn’t check if MailScanner or Spamassassin did the actual filtering, but file with custom rules where in /etc/mail/spamassassin/ folder at least.

With hundreds of 25+ year old mail addresses, amount of spam is just insane and now I’m trying to migrate all my old rules to MIAB.

It’s weird, that spampd just ignoring these rules, and spamassassin does not. It must be something about how postfix passes mails to the spampd. This is only difference between spampd and spamassassin.
Will investigate it further trying to debug spampd to see what it actually get from postfix.

EDIT:
More important piece of information

envelope_sender_header Name-Of-Header
SpamAssassin will attempt to discover the address used in the 'MAIL FROM:' phase of the SMTP transaction that delivered this message, if this data has been made available by the SMTP server. This is used in the EnvelopeFrom pseudo-header, and for various rules such as SPF checking.
By default, various MTAs will use different headers, such as the following:

    X-Envelope-From
    Envelope-Sender
    X-Sender
    Return-Path

and indeed Return-Path is in all the emails.

EDIT2:

after full day of testing I have found nothing.

In same mail and in same file:
blacklist_from *@smlydlv3.net not working
header CUSTOM_RULE From =~ /smlydlv3.net/i not working
header CUSTOM_RULE Return-Path =~ /smlydlv3.net/i not working
header CUSTOM_RULE Envelope-Sender =~ /smlydlv3.net/i not working

header CUSTOM_RULE List-Software =~ /smaily/i or many other random fields is working!

basically anything that involve envelope-from address is not working. spampd is not very debuggable either. With --debug option it logs only From: and To: fileds from message body, not from header. I have feeling, that postfix do not send full header to the spamdp at all.

Another weird thing is that spampd listen on port 10025 right?
Well …

root@mail:# telnet 127.0.0.1 10025
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 xx.xx.xx Dovecot (Ubuntu) ready.

what is Dovecot doing there?
Is lmtp somehow involved there as well?

If you look at the design of Mail-in-a-Box, you see that Postfix forwards mails to Spamassassin (via spampd), which in turn forwards them to Dovecot. That is why you end up at Dovecot.

To help with debugging: look for /etc/default/spampd then change in there ADDOPTS="--maxsize=2000 -d --log-rules-hit". Then restart spampd sudo systemctl restart spampd
To see if your rules are loaded use spamassassin --lint -D 2>&1 | less. If no configuration changes are made from the default Mail-in-a-Box, this is the same set that spampd will use to run spamassassin.

I noted a configuration option of spampd:

       --set-envelope-headers or --seh "(new in v2.30)"
            Turns  on addition of X-Envelope-To and X-Envelope-From headers to the mail being scanned before it is passed to
            SpamAssassin. The idea is  to  help  SA  process  any  blacklist/whitelist  to/from  directives  on  the  actual
            sender/recipients  instead  of  the  possibly  bogus  envelope headers. This potentially exposes the list of all
            recipients of that mail (even BCC'ed ones).  Therefore usage of this option is discouraged.

            NOTE: Even though spampd tries to prevent this leakage by removing  the  X-Envelope-To  header  after  scanning,
            SpamAssassin itself might add headers itself which report one or more of the recipients which had been listed in
            this header.

       --set-envelope-from or --sef "(new in v2.30)"
            Same  as  above  option  but  only  enables  the  addition of X-Envelope-From header.  For those that don't feel
            comfortable with the possible information exposure of X-Envelope-To.  The above option overrides this one.

Perhaps on your old server these were enabled? They are not on MiaB

I already did that, but this adds one line to the spampd logs, where is listed all the hits, but same and more is in mail header anyway. So no new information there.

hmm, that looks promising.
Added both of them and indeed some lines appeared in the mail header, like
X-Envelope-From: xx@xx.xx
Will wait for some spam and see what happens.

Thanks.

EDIT:
in first look, a lot more
spampd[1323520]: identified spam …
messaged appear in logs, but that may be coincidence.
What they actually hit need more analyzing …
I’ll let you know …

I can confirm, that Spamassassin works much better after adding these to spampd.
No drawbacks so far.

Good to hear!
Two remarks:

  • On an upgrade of Mailinabox, this configuration change might be lost. Verify it’s there after an upgrade
  • I suspect the reason it now works better for you is due to your spamassassin rules depending on this. That’s not a worry for you, but for others reading this: changing this configuration won’t magically make your spamassasin work better.
1 Like

yes, I’m already have meter long checklist to go through after every update.
MIAB should provide a way to keep config changes. I know this is complicated, but still, there is not many software installs, what wipe everything clean after every update. I’m already start thinking about the script to restore selected files from backup after update.

Maybe you should at least consider to add these switches to official install.
If they make custom rules work as documented, and if there is no drawbacks, then why not.

Thanks again for helping me out.