Zimbra Anti-Spam Best Practices – Updated for 2024

Zimbra Anti-Spam Best Practices – Updated for 2024

Each year, we read in the various data breach reports that email remains the Number One attack vector used for phishing, whaling, malware distribution and other scams.

In this blog post, continuously updated since March 2019, we describe how we supplement the various open-source anti-spam capabilities that ship with Zimbra with two commercial block list providers for a low-cost, high-impact solution.

End-User Training Is Key

We cannot overemphasize the need for periodic end-user training.  Anti-spam will never be perfect, so users need to be trained when to pause, take a deep breath and think before they open or reply to an email.  When a user receives an email from someone they know, but the email seems suspicious, DO NOT REPLY to the email!  Instead, train your users to FORWARD the email to the (alleged) original sender.  This is because the “From:” portion of an email can be easily forged, but the recipient will have the correct email address for the sender in their Address Book. 

This “forged sender” technique is typically how those emails purporting to be from the CFO and ordering expediting payment to a vendor (really the scammer who sent the email in the first place) cause so much trouble; the poor accounting clerk thinks s/he is replying to the CFO, but is really replying to the scammer.

Lastly, in most of the recent email hacks with which I am familiar, two-factor authentication would have prevented the exploit from being deployed, so we are strongly encouraging our customers to deploy two-factor authentication — it’s really not as inconvenient to use as most people presume.

Deliverability and Domain Spoofing

The email world was already changing before COVID 19 caused email volumes to more than double, but what was acceptable just a few short years ago is no longer. Senders large and small have a responsibility to prevent their domain from beeing spoofed by bad actors, by sending “authenticated” emails.

That means you need:

  1. An accurate SPF record with at least a soft fail (“~all”, although a hard fail “-all” is preferable);
  2. To be doing DKIM signing wherever you can, and;
  3. To have a DMARC record with a policy of either “reject” (ideal) or “quarantine”.

Yahoo, Google, and the other majors have started rejecting — yes, rejecting outright, not just marking as spam and delivering — emails whose senders do not have a DMARC record. Their policies are expected to become increasingly strict over time, so if you haven’t already, now is the time to get your SPF, DKIM and DMARC records in order.

Anti-Spam Quick Level Set: Terminology, Approach and Techniques
Here are some key terms and concepts to make sure we are all on the same page:

  • Gray Mail – Email that technically isn’t spam, but that most users don’t want.  You downloaded a whitepaper and had to give up your email address, so now you are receiving all kinds of offers via email that you technically authorized when you accepted the terms and conditions to be able to download that whitepaper.
  • Spam – For our purposes, “spam” is email that has been determined to be junk.  In the United States, the CAN-SPAM Act has a more rigorous definition. In countries covered by the GDPR, “UCE” or Unsolicited Commercial Email is even more heavily restricted. If an email is unequivocally junk, Zimbra deletes it.  If it is marginally junk, Zimbra can prepend the Subject line with a warning and place it in the user’s Junk folder.  The threshold between deletion and sending on is adjustable.
  • Block List – A third-party service that Zimbra can use to identify IP addresses and domains that are known spam sources, either because they are just bad guys (in the eyes of the block list provider) or because they are nice guys that have been hacked.  Some block lists are very aggressive in their listing policies; others less so.  There are three types of block lists:
    • Left-hand side block lists for checking IP addresses (“RBLs”);
    • Right-hand side block lists for checking domains (“RHSBLs”), and;
    • URI block lists for checking links within an email body (“URIBLs”).
  • False Positive – A legitimate email incorrectly identified as spam.  Block Lists are rated on their frequency of false positives.  Typically, the higher the rate of false positives, the less spam a block list will allow.  This trade off between efficacy and accuracy warrants a discussion with management.  Customers that have high requirements for both low false positives and near-zero spam are typically prospects for additional commercial third-party services, like Mimecast.
  • Postfix – The open source MTA (Mail Transfer Agent) software included with Zimbra that accepts email from, and delivers email to, other mail servers and Zimbra mailboxes.
  • Amavisd – The open source software that is tightly integrated with Postfix, and which processes emails through SpamAssassin and ClamAV before allowing Postfix to deliver them.
  • SpamAssassin – A powerful open source software that ships with Zimbra and which performs hundreds of tests on an email.  Each test result adds a positive (bad) or negative (good) score to an email.  At the end of the exercise, SpamAssassin adds up all of the tests’ individual scores to get a combined score for the email. Scores above a certain threshold result in the email being classified as Spam.  The thresholds at which SpamAssassin marks an email as Junk and delivers it to the end user, or deletes it outright are adjustable.
  • ClamAV – The open source anti-virus engine that ships with Zimbra and which is preconfigured to update itself.

Our anti-spam techniques comprise deploying sensible configuration adjustments to the the open source softwares that ship with Zimbra, supplemented with two paid third-party blocklists.  Budget US$1.00 to US$3.00 per mailbox per year for third-party block lists to use within Zimbra, and you will be all set.  If you need more enhanced email security services like data loss prevention, end-to-end encryption, user-managed quarantines, compliance assurance and email continuity so users can send and receive emails even when Zimbra is down, you are a candidate for a subscription from like AppRiver, ProofPoint, Barracuda etc.

The rest of the article presumes you have already signed up for subscriptions from invaluement and Spamhaus (or from alternative providers you deem better suited to your environment) and want to deploy their services in Zimbra.

Technique #1 – Outright Blocking With Postscreen
Zimbra’s Postfix now ships with Postscreen, a kind of inbound email firewall. Postscreen effectively blocks bad guys without putting any strain on the the Zimbra server.  The Zimbra Postscreen wiki describes this tool, and how to configure it, in great detail. But the wiki recommends some very aggressive blocklists for the zimbraMtaPostscreenDnsblSites variable, and our experience has been that using the blocklists listed in that wiki cause a lot of false positives.  As a result, we only use the free list provided by Barracuda Central (thank you Barracuda!) and one of our paid provider’s lists.  To simplify, we ran as the Zimbra user:

zmprov mcf zimbraMtaPostscreenDnsblSites 'b.barracudacentral.org=127.0.0.2*7' zimbraMtaPostscreenDnsblSites 'sip-sip24.<your-account-code>.invaluement.com=127.0.0.2*6' zimbraMtaPostscreenDnsblSites '<your-account-code>.zen.dq.spamhaus.net=127.0.0.[2..255]
zmprov mcf zimbraMtaPostscreenDnsblAction enforce
zmprov mcf zimbraMtaPostscreenGreetAction enforce
zmprov mcf zimbraMtaPostscreenNonSmtpCommandAction drop
zmprov mcf zimbraMtaPostscreenPipeliningAction enforce
zmprov mcf zimbraMtaPostscreenDnsblTTL 5m

zimbra@zimbra:~$ zmprov gcf zimbraMtaPostscreenDnsblSites
zimbraMtaPostscreenDnsblSites: b.barracudacentral.org=127.0.0.2*7 zimbraMtaPostscreenDnsblSites: sip-sip24.<our_account_number>.invaluement.com=127.0.0.2*6
zimbra@zimbra:~$

Postscreen is really resource-efficient. It doesn’t require a lot of RAM, disk nor CPU cycles to implement. But this is where we recommend using only blacklists that have a very, very low known rate of “false positives”. And this screen is for the IP address of the sending server onlyThe Third Strategy – Front Door Blocking Via DNS Checks

Within a few minutes, Zimbra’s zmconfigd configuration daemon will pick up the above changes and reload Postfix appropriately.

Technique #2 – Outright Blocking With Postfix DNS Protocol Checks
Outside email servers trying to send you email should behave appropriately and be configured according to published and accepted standards. Most are not, and often for acceptable reasons.  Zimbra’s Postfix allows you to check a number of these via settings in the Admin Console (Home > Configure > Global Settings > MTA), but all but two of these checks can generate frequent false positives. The two checks that don’t generate false positives, but which will block a lot of spam are:

zmprov mcf +zimbraMtaRestriction reject_non_fqdn_sender
zmprov mcf +zimbraMtaRestriction reject_unknown_sender_domain
zmprov mcf +zimbraMtaRestriction reject_unknown_reverse_client_hostname

The “reject_unknown_sender_domain” according to the Postfix documentation, performs some specific checks to ensure the sender’s domain actually exists in public DNS. If the sender’s domain doesn’t exist, the email is not accepted. Similarly, the “reject_non_fqdn_sender” check will reject the email if the MAIL FROM isn’t a properly-formed email address. “johnny@hosting” would get rejected by the non-fqdn check and “johnny@hosting666.com” would get rejected by the unknown sender domain test because (at least as of this writing) the domain “hosting666.com” doesn’t exist.  The “reject_unknown_reverse_client_hostname” will block receiving email from any host that doesn’t have a PTR record — except from senders who authenticate with a username and password.

Technique #3 – Outright Blocking of Bad Sending Servers
Now we start using blocklists within Postfix, and their are two kinds: “RBLs” or left-hand-side blocklists, and RHSBLs or right-hand-side blocklists. RBLs list IP addresses; RHSBLs list domains. Different blocklist providers have different philosophies about how IP addresses and domains get listed. Some are forthcoming and transparent; others less so. Some are clearly very aggressive in their listing methodologies and fully acknowledge they will cause some “false positives” periodically. Some have clear rules for delisting; others do not. So before you choose any blocklists to use, be sure you make sure the culture of the blocklist aligns with the culture of your company’s sensitivity to false positives. Here’s what we do (please be sure to substitute your own invalument account code first!):

zmprov mcf +zimbraMtaRestriction "reject_rbl_client b.barracudacentral.org"
zmprov mcf +zimbraMtaRestriction "reject_rbl_client sip-sip24.<account_code>.invaluement.com"
zmprov mcf +zimbraMtaRestriction "reject_rbl_client <account_code>.zen.dq.spamhaus.net"

Above we use a free block list from Barracuda, one paid blocklist from invaluement and one from Spamhaus. We used to use cbl.abuseat.org, but their data is included in Spamhaus, so no need to query them directly if you are using Spamhaus.

Those three RBLs together we have found do a fantastic job of blocking spam from known bad IP addresses. Each one periodically catches an IP address the others do not.

Technique #4 – Outright Blocking of Bad Sending Domains
So far we’ve used Postfix’s Postscreen and Postfix itself, with some RBL add-ins, to block spam from known bad IP addresses. The next step is to use Postfix to block spam from known bad domains. For, that we use RHSBLs from one of our paid blocklist providers (again, be sure to use your account code after you subscribe):

zmprov mcf +zimbraMtaRestriction "reject_rhsbl_client <account_code>.df.uribl.com"
zmprov mcf +zimbraMtaRestriction "reject_rhsbl_client uri.<account_code>.invaluement.com"
zmprov mcf +zimbraMtaRestriction "reject_rhsbl_reverse_client <account_code>.dbl.dq.spamhaus.net"
zmprov mcf +zimbraMtaRestriction "reject_rhsbl_reverse_client <account_code>.zrd.dq.spamhaus.net"
zmprov mcf +zimbraMtaRestriction "reject_rhsbl_reverse_client uri.<account_code>.invaluement.com"
zmprov mcf +zimbraMtaRestriction "reject_rhsbl_sender <account_code>.dbl.dq.spamhaus.net"
zmprov mcf +zimbraMtaRestriction "reject_rhsbl_sender uri.<account_code>.invaluement.com"
zmprov mcf +zimbraMtaRestriction "reject_rhsbl_sender <account_code>.zrd.dq.spamhaus.net"

 

Technique #5 – Outright Blocking of Certain Attachments
By default, Zimbra does not block what could be dangerous email attachments, like Visual Basic scripts, Windows Registry edits etc.  So, we need to block those attachments and let the System Administrator and the recipient know we have done so. Zimbra by default also blocks encrypted attachments, but it is more common these days that many users email password-protected files to each other, so in our systems we allow this.  To effect these changes we run:

zmprov mcf +zimbraMtaBlockedExtension asd
zmprov mcf +zimbraMtaBlockedExtension bat
zmprov mcf +zimbraMtaBlockedExtension cab
zmprov mcf +zimbraMtaBlockedExtension chm
zmprov mcf +zimbraMtaBlockedExtension cmd
zmprov mcf +zimbraMtaBlockedExtension com
zmprov mcf +zimbraMtaBlockedExtension cpl
zmprov mcf +zimbraMtaBlockedExtension cpgz
zmprov mcf +zimbraMtaBlockedExtension dll
zmprov mcf +zimbraMtaBlockedExtension do
zmprov mcf +zimbraMtaBlockedExtension exe
zmprov mcf +zimbraMtaBlockedExtension hlp
zmprov mcf +zimbraMtaBlockedExtension hta
zmprov mcf +zimbraMtaBlockedExtension html
zmprov mcf +zimbraMtaBlockedExtension js
zmprov mcf +zimbraMtaBlockedExtension jse
zmprov mcf +zimbraMtaBlockedExtension lnk
zmprov mcf +zimbraMtaBlockedExtension ocx
zmprov mcf +zimbraMtaBlockedExtension pif
zmprov mcf +zimbraMtaBlockedExtension reg
zmprov mcf +zimbraMtaBlockedExtension scr
zmprov mcf +zimbraMtaBlockedExtension shb
zmprov mcf +zimbraMtaBlockedExtension shm
zmprov mcf +zimbraMtaBlockedExtension shs
zmprov mcf +zimbraMtaBlockedExtension shtml
zmprov mcf +zimbraMtaBlockedExtension vbe
zmprov mcf +zimbraMtaBlockedExtension vbs
zmprov mcf +zimbraMtaBlockedExtension vbx
zmprov mcf +zimbraMtaBlockedExtension vxd
zmprov mcf +zimbraMtaBlockedExtension wsf
zmprov mcf +zimbraMtaBlockedExtension wsh
zmprov mcf +zimbraMtaBlockedExtension xl
zmprov mcf zimbraMtaBlockedExtensionWarnAdmin TRUE
zmprov mcf zimbraMtaBlockedExtensionWarnRecipient TRUE
zmprov mcf zimbraVirusBlockEncryptedArchive FALSE

 

Technique #6 – Email Content Checking
So far Postfix/Postscreen have done all of the work via low-cost DNS lookups, and all of the checks have been binary: Is the sender on a blocklist? Yes? Drop the connection or don’t accept the email.  For emails which have not yet been rejected, Postfix will now accept the email and pass it off to Amavisd for processing. 

Zimbra ships Amavisd preconfigured to process emails through ClamAV and SpamAssassin.  Amavisd can be configured to process emails through additional third-party services (configuring that is beyond the scope of this article).  Once processed, the emails are (a) delivered to the recipient (either because the email is clean, or because the email has been marked as spammy and put in the user’s Junk folder), (b) placed in a quarantine or (c) just discarded if the email’s spam score is off the charts.  We control the “discard/spam/not spam” thresholds and the Subject prepend for spammy emails like so:

zmprov mcf zimbraSpamKillPercent 75
zmprov mcf zimbraSpamTagPercent 19
zmprov mcf zimbraSpamSubjectTag "** CAUTION! SUSPICIOUS EMAIL ** "

 

At least on Ubuntu, a basic install of the operating system doesn’t install as many file extraction tools and Perl libraries as Amavis and SpamAssassin would like.  To install some additional tools Amavis can use to check the contents of many unencrypted archives, we run as the root user the following command.

apt-get install libgeo-ip-perl libgeo-ipfree-perl libnet-patricia-perl lrzip lzop arj zoo rar unrar p7zip-full p7zip-rar tnef ripole nomarch arc

 

Moving on, Zimbra’s log file “/var/log/zimbra.log” contains a lot of good information about which emails are accepted/rejected, but no detail on the components of an email’s spam score.  To get that detail (so we can tune things later if needed, and explain to a disgruntled user why an email was marked as spam) we need to bump up Amavis’s logging level from the default 1 to 2, like so:

zmprov mcf zimbraAmavisLogLevel 2

 

Not all of Amavis’s configurations are adjustable via Zimbra Global Config variables.  Zimbra ships Amavis’s config template file as “/opt/zimbra/conf/amavisd.conf.in”.  Every time Zimbra (or just Amavis) is restarted, Zimbra’s zmconfigd configuration daemon reads this template file and rewrites the actual amavisd.conf file right before starting the amavisd service.  We need to make a few minor changes…

First, SpamAssassin skips over emails with large bodies, on the premise that spammers won’t waste time sending big emails.  Wrong.  Spammers just pad emails with a bunch of invisible junk to avoid getting their emails’ contents checked.  So we need to empower SpamAssassin to check those larger emails. 

The second thing we need to do to amavisd.conf.in is whitelist Zimbra’s Daily Mail Report, else the lists of bad domains that got blocked will cause the Daily Mail Report itself to be marked as Spam.

To effect both of those changes, as the zimbra user edit  “/opt/zimbra/conf/amavisd.conf.in” in two places:

# ORIGINAL LINE BELOW - CHANGES TO THIS FILE WILL NOT SURVIVE ZIMBRA UPGRADES
# $sa_mail_body_size_limit = 512*1024; # don't waste time on SA if mail is larger
$sa_mail_body_size_limit = 1024*1024; # don't waste time on SA if mail is larger

Lower down in the file, look for the following lines and insert a prescore for the virus notifications sender email you use (example in green). This also ensures that the Daily Mail Report (assuming you use the same sender) will also not be marked as spam:

'returns.groups.yahoo.com' => -3.0,
'clusternews@linuxnetworx.com' => -3.0,
'antivirus-notifications@missioncriticalemail.com' => -40.0,
lc('lvs-users-admin@LinuxVirtualServer.org') => -3.0,
lc('owner-textbreakingnews@CNNIMAIL12.CNN.COM') => -5.0,

# soft-blocklisting (positive score)
'sender@example.net' => 3.0,
'.example.net' => 1.0,

 

Now that SpamAssassin is going to be asked to process a lot more, and bigger emails, Amavis needs a RAM disk for SpamAssassin to do that work.   RAM disk provisioning varies from distribution to distribution, but on Ubuntu 16.04 with Zimbra 8.8.x and where the zimbra user’s UID and GID are both 999, you can add the following line to /etc/fstab to create a 1GB RAM disk:

tmpfs /opt/zimbra/data/amavisd/tmp tmpfs defaults,noexec,nodev,nosuid,size=1024m,mode=750,uid=999,gid=999 0 0

For most Zimbra MTAs, a 1GB RAM disk will be large enough. But if you have more than the standard amavis processes running, or you allow large file size attachments, it’s possible you may need a larger RAM disk.  Ralf Hildebrandt, the author of the seminal Book of Postfix, has a blog that contains the RAM disk sizing formula you can use.

Note that Amavis cannot be running if you want to implement this without a reboot.  To do so on a live Zimbra system you would do:

(As root)
su - zimbra
zmamavisdctl stop
ls /opt/zimbra/data/amavisd/tmp <= This directory should be empty with Amavis stopped
exit <= To go back to being root
mount /opt/zimbra/data/amavisd/tmp
df -h <= To make sure the mount succeeded
chown -R zimbra.zimbra /opt/zimbra/data/amavisd/tmp
su - zimbra
zmamavisdctl start
postfix flush
ls /opt/zimbra/data/amavisd/tmp <= This directory should now have a few "amavis-2019..." directories

 

The SpamAssassin project periodically updates the hundreds of rules SpamAssassin uses, but Zimbra by default does not update SpamAssassin’s rules, so we need to tell Zimbra to update SpamAssassin periodically and restart SpamAssassin after an update:

zmlocalconfig -e antispam_enable_rule_updates=true
zmlocalconfig -e antispam_enable_restarts=true

 

ClamAV takes care of updating itself by default; Zimbra runs ClamAV’s companion “freshclam” service periodically to update ClamAV’s virus definitions.  Unfortunately, the default update frequency is too infrequent for us, so to update the virus definitions every two hours we run:

zmprov mcf zimbraVirusDefinitionsUpdateFrequency 1h

 

Now that Amavis, SpamAssasin and ClamAV are ready to zoom, we need to tweak SpamAssassin to use our paid blocklist providers, and to prevent some common false positives.

invaluement, uribl.com and Spamhaus provide customers with SpamAssassin configuration files that should be placed in /opt/zimbra/data/spamassassin/localrules. These files cause SpamAssasin to perform the additional/changed email content scanning tests supported by the providers. In addition, non-Zimbra files in this directory are left intact by Zimbra’s installer, so Zimbra Patches and indeed Zimbra version upgrades will not “break” your SpamAssassin customizations. 

We do need to do one more thing to customize SpamAssassin…  If you have not already done so, as the zimbra user run:

nano ~/data/spamassassin/localrules/zzsauser.cf

Add the following lines to the above zzsauser.cf file:

# Change the subnets below to match your internal networks!
internal_networks 10.7.57.0/24
internal_networks 10.8.0.0/19
score __RCVD_IN_DNSWL 0.001
score DKIM_INVALID 3.0
score DOS_OUTLOOK_TO_MX 0
score FORGED_GMAIL_RCVD 4.0
score FREEMAIL_REPLY 2.5
score FREEMAIL_REPLYTO 2.5
score FROM_FMBLA_NEWDOM 5.0
score FROM_FMBLA_NEWDOM14 3.0
score FROM_FMBLA_NEWDOM28 2.5
score FROM_NEWDOM_BTC 3.0
score FUZZY_BITCOIN 2.0
score HTML_OBFUSCATE_10_20 0.25
score MAILING_LIST_MULTI 0.1
score MALFORMED_FREEMAIL 4.0
score MISSING_HEADERS 2.0
score MSGID_NOFQDN1 2.5
score RCVD_IN_DNSWL_HI 0.001
score RCVD_IN_DNSWL_MED 0.001
score RCVD_IN_PBL 1.0
score RCVD_IN_RP_CERTIFIED 0.00
score RCVD_IN_RP_RNBL 4.0
score RCVD_IN_VALIDITY_CERTIFIED -0.1
score RCVD_IN_VALIDITY_RPBL 0.1
score RCVD_IN_VALIDITY_SAFE -0.1
score RDNS_NONE 0.1
score SENDGRID_REDIR 1.75
score SPF_FAIL 3.5
score TO_EQ_FM_DIRECT_MX 0
score TO_MALFORMED 2.5
score URIBL_ABUSE_SURBL 5.0
score URIBL_BLACK 3.0
use_bayes 0
use_razor2 0
use_pyzor 0
dns_query_restriction deny dnsbl.sorbs.net
dns_query_restriction deny multi.surbl.org
dns_query_restriction deny list.dnswl.org
dns_query_restriction deny uribl.com
dns_query_restriction deny spamhaus.org
dns_query_restriction deny dob.sibl.support-intelligence.net
dns_query_restriction deny psbl.surriel.com
dns_query_restriction deny isipp.com
# Begin Validity Tests
dns_query_restriction deny bl.score.senderscore.com
dns_query_restriction deny sa-accredit.habeas.com
dns_query_restriction deny sa-trusted.bondedsender.org
# End Validity Tests
clear_originating_ip_headers
originating_ip_headers X-Yahoo-Post-IP X-Apparently-From
originating_ip_headers X-SenderIP X-AOL-IP
originating_ip_headers X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp
# Begin Custom and Third-Party Rules:
# Fabel Spam Sources
header RCVD_IN_FABEL rbleval:check_rbl('fabel', 'spamsources.fabel.dk.')
describe RCVD_IN_FABEL Received via a relay in spamsources.fabel.dk
tflags RCVD_IN_FABEL net
score  RCVD_IN_FABEL 2
header     SPAM_BANNED1     Subject =~ /failure to verify account Incoming Messages on/i
describe   SPAM_BANNED1     Subject contains subjectname
score      SPAM_BANNED1     40.0
header     SPAM_BANNED2     Subject =~ /Password Expiry Notification/i
describe   SPAM_BANNED2     Subject contains subjectname
score      SPAM_BANNED2     40.0
header     SPAM_BANNED3     Subject =~ /Password Expiration Notification/i
describe   SPAM_BANNED3     Subject contains subjectname
score      SPAM_BANNED3     40.0
header     SPAM_BANNED4     Subject =~ /E-Mail Storage Bandwidth Limit Has Exceeded/i
describe   SPAM_BANNED4     Subject contains subjectname
score      SPAM_BANNED4     40.0
header     SPAM_BANNED5     Subject =~ /Friendly City is sharing a file with you/i
describe   SPAM_BANNED5     Subject contains subjectname
score      SPAM_BANNED5     40.0
header     SPAM_BANNED6     Subject =~ /Password Expiry Notice/i
describe   SPAM_BANNED6     Subject contains subjectname
score      SPAM_BANNED6     40.0
body       GEEK_SQUAD1      /eek Squad Antivirus/i
score      GEEK_SQUAD1      40.0
describe   GEEK_SQUAD1      Body contains unusual G for Geek Squad Antivirus
header     SPAM_BANNED7     Subject =~ /Account admin will be Shut-down today update now to avoid suspension/i
describe   SPAM_BANNED7     Subject contains subjectname
score      SPAM_BANNED7     40.0
header     SPAM_BANNED8     Subject =~ /Access Restriction, Keep Current to stay Active/i
describe   SPAM_BANNED8     Subject contains subjectname
score      SPAM_BANNED8     40.0
header     SPAM_BANNED9     Subject =~ /ATTENTION: Important Password Notice for /i
describe   SPAM_BANNED9     Subject contains subjectname
score      SPAM_BANNED9     40.0
header     SPAM_BANNED10    Subject =~ / MAIL SHUTDOWM/i
describe   SPAM_BANNED10    Subject contains subjectname
score      SPAM_BANNED10    40.0
# Mirror Google, Yahoo etc. re unauthenticated email:
ifplugin Mail::SpamAssassin::Plugin::DKIM
score DKIM_SIGNED    -0.01
meta  DKIM_UNSIGNED  !DKIM_SIGNED
score DKIM_UNSIGNED  1.75
endif
score DMARC_MISSING  2.0
score SPF_NONE       1.75
score DMARC_PASS_NONE 1.0
# End unauthenticated email check
score RCVD_IN_VALIDITY_CERTIFIED -0.1
score RCVD_IN_VALIDITY_SAFE -0.1
score RCVD_IN_VALIDITY_RPBL 0.1
#Google APPSHEET ABUSE
header __KAM_APPSHEET1 From:addr =~ /noreply\@appsheet\.com/i
meta KAM_APPSHEET ( __KAM_APPSHEET1 >= 1 )
describe KAM_APPSHEET Google AppSheet being abused by spammers
score KAM_APPSHEET 3.0
#Docusign SCAM
header __KAM_DOCUSIGN1 Subject =~ /New e-DocuSign Signature|new e-signature docusign|docusign electronic signature|transfer notice|docusign (electronic|signature) service|docusign document|p
lease_complete_document/i
header __KAM_DOCUSIGN2 From:name =~ /docusign/i
header __KAM_DOCUSIGN3 From:addr !~ /docusign/i
uri __KAM_DOCUSIGN4 /\.weebly\.com|docs\.google\.com|onedrive\.live\.com|\.linodeobjects\.com/i
body __KAM_DOCUSIGN5A /scan the QR Code/i
body __KAM_DOCUSIGN5B /secure link to docusign/i
meta KAM_DOCUSIGN ((__KAM_DOCUSIGN1 >= 1) + (__KAM_DOCUSIGN2 + __KAM_DOCUSIGN3 >= 2) + (FREEMAIL_FROM + LOTS_OF_MONEY + __KAM_DOCUSIGN4 >= 1) >= 3)
describe KAM_DOCUSIGN Fake Document Signature account notices
score KAM_DOCUSIGN 4.5
meta KAM_DOCUSIGN_LOW (__KAM_DOCUSIGN1 + __KAM_DOCUSIGN4 >= 2)
describe KAM_DOCUSIGN_LOW Lower score Fake Document Signature Account Notice
score KAM_DOCUSIGN_LOW 3.0
meta KAM_DOCUSIGN_QR ((__KAM_DOCUSIGN1 >= 1) + (__KAM_DOCUSIGN2 + __KAM_DOCUSIGN3 >= 2) + (__KAM_DOCUSIGN5A + __KAM_DOCUSIGN5B >= 2) >= 3)
describe KAM_DOCUSIGN_QR Qishing scam with Docusign
score KAM_DOCUSIGN_QR 4.5
#FAKE DOCUSIGN
ifplugin Mail::SpamAssassin::Plugin::MIMEHeader
mimeheader    __KAM_FAKE_DOCUSIGN1 Content-Type =~ /docusign\.png/i
header __KAM_FAKE_DOCUSIGN2 Subject =~ /D0cuSign\: Signature Required/i
meta KAM_FAKE_DOCUSIGN (__KAM_FAKE_DOCUSIGN1 + T_HTML_ATTACH >= 2) || (__KAM_FAKE_DOCUSIGN2)
describe KAM_FAKE_DOCUSIGN Fake Docusign Document
score KAM_FAKE_DOCUSIGN 3.0
endif
#FAKE DOCUSIGN
header __KAM_FAKE_DOCUSIGN2_1 Subject =~ /signature required/i
uri __KAM_FAKE_DOCUSIGN2_2 /mimecastprotect.com.*urldefense.proofpoint.co/i
body __KAM_FAKE_DOCUSIGN2_3 /docusign/i
meta KAM_FAKE_DOCUSIGN2 ( __KAM_FAKE_DOCUSIGN2_1 + __KAM_FAKE_DOCUSIGN2_2 + __KAM_FAKE_DOCUSIGN2_3 >= 3 )
describe KAM_FAKE_DOCUSIGN2 Likely Fake DocuSign Email
score KAM_FAKE_DOCUSIGN2 4.5
#End

There are plenty of sources for researching the meanings of each of the scores for the tests above; we’ll leave it to you as a homework assignment if you decide you want to know more about individual tests.

The “internal_networks” parameter isn’t a white list, nor is it strictly required, but in my experience you’ll have less problems if you list all of your Zimbra servers or their network here.

About the Originating IP headers section..  Spamhaus engineering presumes the use of Amavis Policy Banks, which Zimbra does not use to the extent Spamhaus’s default configuration assumes.  With Policy Banks, you can apply different Spamassassin processing rules to emails, depending on where they originated.  The default Spamhaus config files evaluate all IP addresses listed as the Originating IP in the header, but users who have IMAP clients and do SMTP-Auth from a blocklisted IP at a coffee shop will find Spamhaus (and other tests as described above), will block those emails as spam, just because of the IP address from which the email originated.  So, we need first to clear from any Spamassassin/Spamhaus evaluation all originating IP headers, and then explicitly list those headers whose IP addresses should be evaluated — while leaving out the headers (like from IMAP client users) that will likely generate false positives.

Lastly, we want SpamAssassin not to run any of the baked-in tests that rely on the above three DNS RBL providers.  Starting from the bottom, we don’t need to query spamhaus.org because we subscribed to paid Spamhaus, and so query spamhaus.net.  The spamhaus.org tests built in to SpamAssassin are effectively then redundant.  In the middle, uribl.com is a terrific blocklist provider who offer both free and paid services.  If your DNS query volumes exceed their free threshold limit, you will see “URIBL_BLOCKED” in /var/log/zimbra.log.  So, either pay them for their services, or stop adding load to their DNS services and extra processing time for each email. The first provider is known for their Good Senders List, which we have chosen not to use, so excise their tests from SpamAssassin here.

Recap
So what have we accomplished?  We:

  1. Configured Postfix’s Postscreen and Postfix itself to outright block a huge percentage of junk email in a way that doesn’t tax the Zimbra server, because we do so using nothing more than a raft of DNS lookups.
  2. Blocked known dangerous attachments and configured Zimbra to let the recipient and System Administrator know that we have done so.
  3. Adjusted the spam scoring thresholds to values that will block more spam without increasing false positives.
  4. Enabled Amavis to give us more actionable information by increasing its log level.
  5. Improved performance by deploying a RAM disk.
  6. Improved accuracy by:
    1. Enabling SpamAssassin to update itself.
    2. Enabling ClamAV to update its virus definitions more frequently.
    3. Customizing SpamAssassin’s scores to eliminate false positives for Outlook and IMAP client users.
    4. Customizing SpamAssassin’s scores to improve spam detection overall.
  7. Spent somewhere between $1 and $3 per mailbox per year to get the benefit of two very good commercial blocklist providers.
  8. Made our users very happy and reduced frustration for the email administrators!

Zimbra also allows for and supports additional customizations to block spam that the above techniques on their own may not catch, but which may be specific to your environment. One example of this is nested email addresses intended to spoof legitimate email addresses. We wrote about Zimbra’s solution in a blog post late last year.  Hopefully this solution makes it into the shipping product in the near term.

If you’d like help with your anti-spam, start the conversation by filling out this form, and we’ll get right back to you!

 

Hope that helps,
L. Mark Stone
Mission Critical Email
Published originally on 21 March 2019
Updated 19 August 2019
Updated 25 September 2019
Updated 3 February 2020
Updated 9 February 2020
Updated 11 March 2020
Updated 8 April 2020
Updated 12 December 2020
Updated 30 March 2021
Updated 7 January 2022
Updated 29 July 2022 – Added shtml as blocked extension
Updated 30 October 2022 – Added reject_unknown_reverse_client_hostname restriction
Updated 1 November 2023 – Removed selected RBL provider default tests from SpamAssassin
Updated 6 November 2024 – Updated the zzsauser.cf file with recent updates and changes

P.S. Thanks to Lorenzo Milesi at YetOpen S.r.l. and Sebastián Greco for their helpful suggestions.

The information provided in this blog is intended for informational and educational purposes only. The views expressed herein are those of Mr. Stone personally. The contents of this site are not intended as advice for any purpose and are subject to change without notice. Mission Critical Email makes no warranties of any kind regarding the accuracy or completeness of any information on this site, and we make no representations regarding whether such information is up-to-date or applicable to any particular situation. All copyrights are reserved by Mr. Stone. Any portion of the material on this site may be used for personal or educational purposes provided appropriate attribution is given to Mr. Stone and this blog.