Spamassassin Rule Definitions

spamassassin rules

Spamassassin Rule Definitions

These are considered ‘privileged’.

Only users running spamassassin from their procmailrc’s or forward files, or sysadmins editing a file in /etc/mail/spamassassin, can use them.

If you add or modify a test, please be sure to run a sanity check afterwards by running spamassassin --lint. This will avoid confusing error messages, or other tests being skipped as a side-effect. spamd users cannot use them in their user_prefs files, for security and efficiency reasons, unless allow_user_rules is enabled.

allow_user_rules (0|1) Default:0

Allows users to create rules in their user_prefs .

Causes spamassassin to recompile all the tests each time it processes a message for a user with a rule in their user_prefs , which effects performance.

It is not recommended.allow_user_rules will not modify an existing system rule .

describe test description

Describes a test in the detailed report. Limit description to 50 characters.test names which begin with __ are reserved for meta-match sub-rules, and are not scored or listed in the ‘tests hit’ reports.

test names must not start with a number, contain only alphanumerics and underscores and be less than 22 characters. Lower-case characters should not be used, sub-rules, and are not scored or listed in the ‘tests hit’ reports.

test names which begin with T_ are reserved for tests which are undergoing QA, and these are given a very low score.

test name example: FROM_ENDS_IN_NUMS.

[`]()header test exists:name_of_header`

Defines a header existence test. Simplest of the header tests.header test header op /pattern/modifiers [if-unset: string]

Define a test which evaluates the header.header is the name of a mail header Subject, To, etc.

Appending :raw to the header name will inhibit decoding of quoted-printable or base-64 encoded strings.

Appending :addr to the header name will cause everything except the first email address to be removed from the header.

For example, all of the following will result in



example@foo (Foo Blah)

example@foo, example@bar

display: example@foo (Foo Blah), example@bar ;

Foo Blah <example@foo>

``Foo Blah'' <example@foo>

``'Foo Blah''' <example@foo>

Appending :name to the header name will cause everything except the first real name to be removed from the header.

For example, all of the following will result in

Foo Blah

example@foo (Foo Blah)

example@foo (Foo Blah), example@bar

display: example@foo (Foo Blah), example@bar ;

Foo Blah <example@foo>

``Foo Blah'' <example@foo>

``'Foo Blah''' <example@foo>


|ALL |refers to the text of all the message’s headers.


|------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |ToCc |refers to the contents of both the ‘To’ and ‘Cc’ headers.


|EnvelopeFrom|is the address used in the ‘MAIL FROM:’ phase of the SMTP transaction that delivered this message.


|MESSAGEID |is a symbol meaning all Message-Id’s found in the message; some mailing list software moves the real ‘Message-Id’ to ‘Resent-Message-Id’ or ‘X-Message-Id’, then uses its own one in the ‘Message-Id’ header. The value returned for this symbol is the text from all 3 headers, separated by newlines.


op is either =~ contains regular expression or !~ does not contain regular expression,

pattern is a valid Perl regular expression, with modifiers as regexp modifiers.

Multi-line rules are not supported.

The # character must be escaped \# or else it will be considered to be the start of a comment and not part of the regexp.

[if-unset: string] string will be used if the header is not found in the mail message.

header test eval:name_of_eval_method([arguments])

Defines a header eval test.name_of_eval_method is the name of a method on the Mail::SpamAssassin::EvalTests object.

Found in lib/Mail/SpamAssassin/Plugin,,,,,,,, WLBLEval

header test eval:check_rbl(set, zone [, sub-test])

Check a DNSBL BlackList or whitelist.

This* collects Received: headers from the message, * extracts the IP addresses, * selects which ones are ‘untrusted’ based on the trusted_networks logic, and * queries that DNSBL zone.

Duplicated IPs are only queried oncePrivate IPs, listed in: IANA 10,172.16,192.168, duccw privip , ducw autoipi APIPA169.254, or rfc3330

are not queried.set

This is used as a ‘zone ID’. to look up a multiple-meaning zone like NJABL or SORBS, you can then query the results from that zone using it; but all check_rbl_sub() calls must use that zone ID.If more than one IP address gets a DNSBL hit for a particular rule, it does not affect the score because rules are only triggered once per message.


root zone of the DNSBL, ending in a period.sub-test

argument behaves the same as the sub-test argument in check_rbl_sub() .* selecting all IPs except for the originating one Place -notfirsthop at the end of the set name. For querying DNS lists which include dialup IP addresses; the first hop may be a dialup, but as long as there is at least one more hop, via their outgoing SMTP server, that’s legitimate, and so should not gain points. If there is only one hop, that will be queried anyway, as it should be relaying via its outgoing SMTP server instead of sending directly to your MX mail exchange. * selecting IPs by whether they are trusted When checking a ‘nice’ DNSBL a DNS whitelist, you cannot trust the IP addresses in Received headers that were not added by trusted relays. Place -firsttrusted at the end of the set name to test the first IP address that can be trusted. That should test the IP address of the relay that connected to the most remote trusted relay. This requires that SpamAssassin know which relays are trusted. For simple cases, SpamAssassin makes a good evaluation. For complex cases set trusted_networks manually. Place -untrusted to test all untrusted IP addresses at the end of the set name. This does NOT include the IP address from the most recent ‘untrusted line’, as used in ‘-firsttrusted’ above. refering to the trustworthiness of the IP address data, not the source header line, here; and in the case of the most recent header the 'firsttrusted', that data can be trusted. See the Wiki page * Selecting the last external IP Place -lastexternal at the end of the set name, to select only the external host that connected to your internal network, or at least the last external host with a public IP.

header test eval:check_rbl_txt('set', 'zone')

Same as check_rbl, except querying using IN TXT instead of IN A records. If the zone supports it, it will result in a line of text describing why the IP is listed, typically a hyperlink to a database entry.header test eval:check_rbl_sub('set', 'sub-test')

Create a sub-test for ‘set’. If you want to look up a multi-meaning zone like, you can then query the results from that zone using the zone ID from the original query. The sub-test may either be an IPv4 dotted address for RBLs that return multiple A records or a non-negative decimal number to specify a bitmask for RBLs that return a single A record containing a bitmask of results, a SenderBase test beginning with ``sb:’‘, or if none of the preceding options seem to fit a regular expression.Note: the set name must be exactly the same for as the main query rule, including selections like ‘-notfirsthop’ appearing at the end of the set name.

body test eval:name_of_eval_method([args])

Define a body eval test.[`]()body test /pattern/modifiers`

pattern is a Perl regular expression.The ‘body’ in this case is the textual parts of the message body; any non-text MIME parts are stripped, and the message decoded from Quoted-Printable or Base-64-encoded format if necessary.

The message Subject header is considered part of the body and becomes the first paragraph when running the rules.

All HTML tags and line breaks are removed before matching.uri test /pattern/modifiers

The ‘uri’ is a list of all the URIs in the body of the email, and the test will be run on each of those URIs, adjusting the score if a match is found. Use this test instead of one of the body tests when you need to match a URI, as it is more accurately bound to the start/end points of the URI, and will also be faster.rawbody test /pattern/modifiers

The ‘raw body’ of a message is the raw data inside all textual parts.

The text will be decoded from base64 or quoted-printable encoding, but HTML tags and line breaks will still be present.

The pattern will be applied line-by-line.rawbody test eval:name_of_eval_method([args])

full test /pattern/modifiers

Define a full message pattern test.The full message is the pristine message headers plus the pristine message body, including all MIME data such as images, other attachments, MIME boundaries, etc.

full test eval:name_of_eval_method([args])

Define a full message eval test.meta test boolean expression

Define a boolean expression test in terms of other tests that have been hit or not hit. For example:meta META1 TEST1 && !TEST2 _|__|_ TEST3

English language operators and, , or will be treated as rule names. There is no XOR operator.

meta test boolean arithmetic expression

Can also define a boolean arithmetic expression in terms of other tests, with a hit test having the value ``1’’ and an unhit test having the value ``0’‘. For example:meta META2 3 \* TEST1 \- 2 \* TEST2 > 0

Note that Perl builtins and functions, like abs(), can’t be used, and will be treated as rule names.

If you want to define a meta-rule, but do not want its individual sub-rules to count towards the final score unless the entire meta-rule matches, give the sub-rules names that start with ‘__’ two underscores. SpamAssassin will ignore these for scoring.

tflags test [ {net|nice|learn|userconf|noautolearn} ]

set flags on a test used in the score-determination back end system for details of the test’s behaviour. See bayes_auto_learnnetnetwork test, and not run in the mass checking system or if -L is used, therefore its score should not be modified. [`]()nice`

Intended to compensate for common false positives, and should be assigned a negative score.userconfrequires user configuration before it can be used like language\- specific tests.learnrequires training before it can be used.noautolearnexplicitly ignored when calculating the score for learning systems.

priority test n

Assign a specific priority to a test. All tests, except for DNS and Meta tests, are run in increasing priority value order negative priority values are run before positive priority values. The default test priority is 0 zero.