Server — Mail — Razor

Posted on 9 2026

SpamAssassin scores incoming mail against a large rule set to determine how likely it is to be spam. Most of those rules are heuristic: they look at message structure, header patterns, and content characteristics that correlate with spam. Razor adds a different kind of check: it computes a signature of the message and queries a distributed network to see whether that exact message, or something very close to it, has already been reported as spam by other users.

The distinction matters. A heuristic rule can catch a category of spam. A Razor lookup can catch a specific spam campaign. When a new spam run starts and millions of copies of the same message go out, Razor knows about it within minutes of the first reports coming in. SpamAssassin’s rules may take days to be updated.

This article covers installing Razor, registering with the network, enabling it in SpamAssassin, and verifying it is working.

Before installing

Two things to know upfront.

Razor is free for personal use, subject to capacity constraints. It is not available for unlimited free use, which is why SpamAssassin ships with the Razor plugin commented out in init.pre rather than enabled by default. For a homelab mail server receiving personal mail, the personal use terms apply and capacity is not a concern. If February were processing mail for a business or a significant number of users, the terms would need more careful reading.

Razor uses TCP port 2703 to communicate with its server network, alongside TCP port 7 for server discovery pings. February’s UFW configuration allows outbound connections by default, so no rule changes are needed. If you have restricted outbound traffic, add an explicit allow:

sudo ufw allow out 2703/tcp

Installation

Razor is in Ubuntu’s standard repository:

sudo apt install razor

This installs the Razor client tools and the Perl modules SpamAssassin needs to call them. SpamAssassin itself should already be installed as part of the mail setup.

Creating the Razor home directory

Razor stores its configuration, server lists, identity, and logs in a home directory. Create it under the SpamAssassin user’s directory:

sudo mkdir -p /var/lib/spamassassin/.razor
sudo chown -R spamd:spamd /var/lib/spamassassin/.razor

The directory must be owned by the user SpamAssassin runs as. On Ubuntu, that is spamd. If your installation uses a different user, adjust accordingly. Running Razor operations as the wrong user creates files with the wrong ownership, which SpamAssassin then cannot read.

Registering with the network

Razor requires a one-time registration to obtain an identity. The identity is what the network uses to track your client’s reputation over time: clients that consistently report correct spam verdicts earn higher trust in the network’s confidence calculations.

Run all three registration commands as the spamd user:

sudo -u spamd razor-admin -home=/var/lib/spamassassin/.razor -create
sudo -u spamd razor-admin -home=/var/lib/spamassassin/.razor -register
sudo -u spamd razor-admin -home=/var/lib/spamassassin/.razor -discover

-create creates the directory structure and default configuration files inside the Razor home.

-register contacts the Razor registration server and obtains an identity for this client. It creates an identity file in the Razor home directory. This step requires internet access.

-discover queries the Razor discovery server to find the nearest server cluster and writes a server list to the Razor home directory. Also requires internet access.

Confirm all three completed without errors before continuing. If -register or -discover fail with a connection error, check that port 2703 is reachable from February:

nc -zv razor.cloudmark.com 2703

A successful connection shows Connection to razor.cloudmark.com 2703 port [tcp/*] succeeded.

Enabling Razor in SpamAssassin

SpamAssassin ships with Razor commented out in its plugin configuration. Two files need editing.

Uncomment the plugin

Edit /etc/spamassassin/init.pre (or /etc/spamassassin/v310.pre on some Ubuntu versions, check which exists):

ls /etc/spamassassin/*.pre

Find and uncomment the Razor2 plugin line by removing the leading #:

# Before:
# loadplugin Mail::SpamAssassin::Plugin::Razor2

# After:
loadplugin Mail::SpamAssassin::Plugin::Razor2

Configure the plugin

Add Razor configuration to /etc/spamassassin/local.cf:

# Razor2 configuration
use_razor2          1
razor_config        /var/lib/spamassassin/.razor/razor-agent.conf
razor_timeout       10
razor_fork          1

# Razor scoring
score RAZOR2_CHECK              2.5
score RAZOR2_CF_RANGE_51_100    3.0
score RAZOR2_CF_RANGE_E8_51_100 3.5

razor_config points to the configuration file created by razor-admin -create. The path must match where you created the Razor home directory.

razor_timeout 10 sets the maximum time SpamAssassin waits for a Razor response. Ten seconds is generous. If Razor is consistently slow or unreachable, this prevents it from delaying mail processing.

razor_fork 1 tells SpamAssassin to run Razor queries in a forked process rather than synchronously. This improves throughput by allowing other checks to proceed while waiting for the Razor response.

The scoring values add SpamAssassin score points when Razor identifies a message. RAZOR2_CHECK is the base hit. RAZOR2_CF_RANGE_51_100 fires when the confidence value is between 51 and 100 percent. RAZOR2_CF_RANGE_E8_51_100 is the engine 8 (Cloudmark’s engine) high-confidence variant. Stacking these scores means a high-confidence Razor hit adds up to 9 points total, which on a SpamAssassin threshold of 5 is more than enough to tag the message as spam on Razor alone.

Adjust the scores downward if you find Razor producing false positives. The values above are conservative enough for a personal mail server but can be tuned.

Restarting SpamAssassin

sudo systemctl restart spamd

Check the service started cleanly:

sudo systemctl status spamd
sudo journalctl -u spamd -n 20

Testing

Verify SpamAssassin can load the Razor plugin without errors:

sudo -u spamd spamassassin --lint 2>&1 | grep -i razor

A clean result shows nothing or shows Razor-related debug lines without errors. Any line containing error or failed indicates a configuration problem.

Test Razor directly against SpamAssassin’s included sample spam file:

sudo -u spamd spamassassin -t -D razor2   < /usr/share/doc/spamassassin/sample-spam.txt 2>&1 | grep -i razor

The -t flag runs in test mode without submitting anything to the network or affecting Bayesian training. The output should include lines showing Razor connecting to its servers and returning a result. What the sample spam file scores depends on whether that specific message is in Razor’s database, so a zero score on the sample is not necessarily a problem.

A more reliable test is passing a known spam message that has been in circulation. Any spam you have received recently is a good candidate. Pipe it through SpamAssassin in debug mode and look for Razor returning a non-zero confidence value:

sudo -u spamd spamassassin -t -D razor2 < /path/to/spam.eml 2>&1 | grep -E "razor|RAZOR"

What Razor does not do

Razor identifies known spam by signature. It does not catch spam it has not seen before, spam that is unique to your address, or spam that has been specifically crafted to evade signature matching by varying content slightly between recipients.

It is one layer in a multi-layer defence. SpamAssassin’s heuristic rules catch pattern-based spam. Razor catches known campaigns. Bayesian filtering, covered separately, catches spam patterns learned from your specific mail flow. None of these is sufficient alone; all three together cover the realistic range of spam February will encounter.

Razor also does not filter at the SMTP level. It operates on messages that have already been accepted by Postfix and are being evaluated by SpamAssassin. Aggressive spam filtering at the Postfix level (rejecting connections from known bad senders before the message body is received) is a separate and earlier line of defence.

Log entries to recognise

Once Razor is active, SpamAssassin’s log will include entries like:

razor2: results: spam? 1, highest cf: 100

or

razor2: results: spam? 0, highest cf: 0

The first line means Razor identified the message as spam with 100% confidence. The second means it found no match. Both are expected depending on the message. The absence of any Razor-related log lines means the plugin is not running, which warrants investigation.