Deployment guide

SpamAssassin

Overview

This image runs Apache SpamAssassin, the long-established open-source anti-spam platform, configured and hardened so you can score mail within minutes of launch. The spamd daemon does the analysis. It scores each message against a large, regularly updated rule set that combines header and body heuristics, Bayesian statistical filtering, DNS blocklists, and SPF and DKIM checks. Your mail system pipes messages through the fast spamc client to get a verdict.

The image is secure by default. spamd runs as a dedicated non-root system user (debian-spamd). It is bound to the loopback address (127.0.0.1), and its accept list is restricted to 127.0.0.1. Nothing off the VM can reach it until you explicitly widen access to a mail-host network you trust.

A single management tool, sa-access, does that. It opens and closes the daemon to specific networks and refuses any world-open exposure as a hard guardrail.

A current rule set is fetched at build time with sa-update, and the operating system maintenance timer is left enabled so every deployed VM keeps its rules fresh. On the first boot of every VM, a one-shot service records the server's details and the exact commands to open the daemon in a root-only information file.

What you get:

  • The Apache SpamAssassin spamd daemon and spamc client (Ubuntu 24.04 noble main), with the rules engine and sa-update
  • spamd running as the non-root debian-spamd user, bound to 127.0.0.1:783 only (secure by default)
  • A loopback-only accept list until you open it, managed with the sa-access tool (world-open exposure is refused)
  • A current rule set fetched at build time, with the spamassassin-maintenance timer left enabled for ongoing refresh
  • Per-VM first-boot initialisation that writes server details to /root/spamassassin-info.txt
  • All packages from the Ubuntu archive (Apache-2.0 SpamAssassin): open source, with no third-party repository
  • 24/7 SecureAnyCloud support

Prerequisites

Before you deploy this image you need:

  • An active Microsoft Azure subscription where you can create virtual machines
  • An SSH key pair for administrator access to the VM
  • A virtual network and subnet in the target region. Mail servers reach spamd over the private network, so put the mail hosts that will use it in the same VNet or a peered one
  • A network security group (NSG) that allows inbound TCP 22 from your administrator network. spamd listens on TCP 783. Open that port, scoped to your mail-host subnets, only after you widen access with sa-access
  • The Azure CLI installed locally if you plan to deploy from the command line

Standard_B2s (2 vCPU / 4 GiB RAM) is a balanced default. Size the VM to the volume of mail you will score.

1

Deploy from the Azure Marketplace

Sign in to the Azure Portal, select Create a resource, and search the Marketplace for Apache SpamAssassin by SecureAnyCloud. Select the listing, then select Create.

On the Basics tab, pick your subscription and resource group, a region, and a VM size (Standard_B2s or larger). Under Administrator account, select SSH public key, set the username, and paste your public key.

Under Inbound port rules, allow SSH (22) for administration only. spamd stays loopback-only until you open it.

Select Review + create, then Create. First-boot initialisation completes within a few seconds of the VM reaching the Running state.

2

Deploy from the Azure CLI

The following block creates a VM from the SecureAnyCloud Apache SpamAssassin image into an existing VNet and subnet. Replace the bracketed values with your own.

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:spamassassin-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name spamassassin \
  --image sac1647283583153:spamassassin-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard
3

Connect as the Administrator over SSH

Connect to the VM over SSH as the administrator user you set at deploy time (azureuser by default on Ubuntu). The administrator account accepts SSH keys only.

ssh azureuser@<vm-public-ip>
4

Confirm the Daemon is Running

spamd starts automatically on boot. Confirm four things: the service is active, it runs as the non-root debian-spamd user, it is bound to the loopback address only, and the configuration is valid.

sudo systemctl is-active spamd.service ps -o user,comm -C spamd | sort -u sudo ss -ltnp | grep ':783'
sudo spamassassin --lint && echo "configuration OK"

The process owner is debian-spamd, not root. The listening socket is 127.0.0.1:783, never 0.0.0.0:783. A clean --lint means the rule set loaded without error.

5

The Secure-by-Default Model

Read the first-boot information file and the exposure summary at any time. The file records the server's private IP and the exact commands to open spamd to your mail hosts.

sudo cat /root/spamassassin-info.txt
sudo sa-access status

The image ships with spamd listening on 127.0.0.1 and accepting connections from 127.0.0.1 only. This is deliberate. No host on the network can use the daemon until you explicitly allow its network.

The image never ships a 0.0.0.0 listen or a 0.0.0.0/0 accept list.

6

Test Spam Detection with GTUBE

GTUBE (the Generic Test for Unsolicited Bulk Email) is a standard string that every spam filter is expected to score as spam. Pipe a message that contains it through spamc and read the report:

GTUBE='XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X' printf 'From: spammer@example.net\nTo: you@example.org\nSubject: test\n\n%s\n' "$GTUBE" | spamc -R

The report shows a score far above the default threshold of 5.0 and the GTUBE rule firing. The returned message carries an X-Spam-Flag: YES header.

This proves the daemon, the rule set and the spamc client all work end to end.

7

Confirm Clean Mail Passes

A filter is only useful if it lets legitimate mail through. Pipe a well-formed clean message through spamc and confirm that it scores below the threshold and is not flagged:

printf 'From: alice@example.com\nTo: bob@example.com\nSubject: Lunch tomorrow\nDate: Mon, 19 Jul 2026 09:00:00 +0000\nMessage-ID: <clean-001@example.com>\n\nHi Bob, are we still on for lunch tomorrow at noon? Thanks, Alice\n' | spamc -R

The report shows a low score, no X-Spam-Flag: YES header, and a verdict of not spam.

8

Open spamd to Your Mail Hosts

To let a mail server on another host use spamd, allow its network with sa-access allow. Pass a CIDR range or a single host. Use your own mail-host subnet, because the value below is only an example.

sudo sa-access allow 10.0.0.0/24
sudo sa-access status

The tool adds the network to the accept list, switches spamd to listen on all interfaces, and reloads the daemon. It still accepts only the allow-listed networks.

You must also open TCP 783 to that network in your Azure NSG. To revert to loopback-only at any time, run:

sudo sa-access loopback

World-open exposure is refused as a hard guardrail. Both sa-access allow '*' and sa-access allow 0.0.0.0/0 are rejected, so you cannot accidentally expose the daemon to the whole internet.

9

Integrate with Your Mail Server

spamd scores messages, and your mail transfer agent decides what to do with the verdict. A common pattern with Postfix is to pipe inbound mail through spamc with spamass-milter, or as a simple content filter.

This example uses the milter. Install spamass-milter on the mail host and point it at this server:

# In Postfix main.cf on your mail host, referencing this SpamAssassin server: smtpd_milters = inet:<server-private-ip>:783 non_smtpd_milters = $smtpd_milters milter_default_action = accept

For a quick, transport-agnostic check from any host that can reach the daemon, use spamc. It accepts the message on standard input and returns the scored message on standard output.

Your MTA reads the X-Spam-Flag and X-Spam-Status headers that the daemon adds, then files, quarantines or rejects the message accordingly. Keep the required_score threshold and any custom rules in /etc/spamassassin/local.cf.

10

Keeping the Rule Set Current

SpamAssassin's effectiveness depends on current rules. The image fetches a fresh rule set at build time and leaves the operating system maintenance timer enabled, so rules keep refreshing:

systemctl is-enabled spamassassin-maintenance.timer
sudo sa-update --version

You can refresh rules on demand at any time and reload the daemon:

sudo sa-update && sudo systemctl reload spamd.service

sa-update exits 0 when it installed new rules and 1 when the rules are already current. Both results are normal.

11

Hardening Notes

The image is hardened out of the box. spamd runs as the non-root debian-spamd user and listens on the loopback address only until you open it. The sa-access tool refuses world-open exposure.

Keep it locked down in production:

  • When you widen access, scope the NSG rule for TCP 783 to only the mail-host subnets that need it. Never expose 783 to the internet.
  • Grant the narrowest CIDR ranges you can.
  • Keep the rule set current with the maintenance timer.
  • Keep the OS patched (sudo apt update && sudo apt upgrade).
  • Review the scoring policy and any custom rules in /etc/spamassassin/local.cf.

Support

This image is backed by 24/7 SecureAnyCloud support. Contact us by email and chat for help with SpamAssassin configuration, spamd and spamc, integrating with Postfix or Exim, tuning the score threshold and rules, Bayesian training with sa-learn, and mail-filtering architecture on Azure.

All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.

Deploy on Azure

Launch Apache SpamAssassin on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure