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
spamddaemon andspamcclient (Ubuntu 24.04 noble main), with the rules engine andsa-update spamdrunning as the non-rootdebian-spamduser, bound to127.0.0.1:783only (secure by default)- A loopback-only accept list until you open it, managed with the
sa-accesstool (world-open exposure is refused) - A current rule set fetched at build time, with the
spamassassin-maintenancetimer 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
spamdover 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.
spamdlistens on TCP 783. Open that port, scoped to your mail-host subnets, only after you widen access withsa-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.
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.
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 StandardConnect 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>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.
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 statusThe 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.
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 -RThe 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.
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 -RThe report shows a low score, no X-Spam-Flag: YES header, and a verdict of not spam.
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 statusThe 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 loopbackWorld-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.
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 = acceptFor 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.
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 --versionYou can refresh rules on demand at any time and reload the daemon:
sudo sa-update && sudo systemctl reload spamd.servicesa-update exits 0 when it installed new rules and 1 when the rules are already current. Both results are normal.
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
Overview
This image runs Apache SpamAssassin, the open-source, Apache-2.0 licensed anti-spam platform. SpamAssassin is a rule-based mail filter. It scores every message against hundreds of tests and flags anything over a configurable threshold as spam. The tests include header and body heuristics, Bayesian statistics, DNS blocklists, SPF/DKIM checks and collaborative-filtering signals.
It is the de facto standard spam filter for Unix mail servers and integrates with Postfix, Exim, Sendmail, amavisd and dovecot.
This is a headless daemon and command-line image. There is no web interface and no credential to manage, because access control is by network, not by password. The spamd scanning daemon runs as the dedicated non-root debian-spamd system user. Mail systems, or you by hand, pipe messages through the spamc client to have them scored.
The single most important property of this image is that it is secure by default. spamd is bound to the loopback address (127.0.0.1), with an allow-list restricted to 127.0.0.1, and the security group opens only SSH. Nothing off the instance can reach the scanning daemon until you explicitly widen access to your own trusted mail hosts with the bundled sa-access tool.
A current rule set is fetched at build time, and the operating system's maintenance schedule keeps refreshing rules on your instance.
Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Connecting to Your Instance
This listing may offer more than one operating system variant. Connect over SSH on port 22 as the default login user for the variant you launched.
For Ubuntu 24.04 LTS, the SSH login user is ubuntu.
Use your EC2 key pair, for example:
ssh -i /path/to/your-key.pem ubuntu@<vm-ip>Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for SpamAssassin. Select the SecureAnyCloud listing, choose Select, then choose Continue on the subscription summary.
Pick an instance type of m5.large or another size that suits your workload. Choose your EC2 key pair under Key pair (login).
Under Network settings, select your VPC and subnet. Create or select a security group that opens port 22 from your management network. Leave the root volume at the default size or larger.
Select Launch instance. First-boot initialisation takes a few seconds after the instance state becomes Running and the status checks pass. During that time the appliance writes its per-instance details and restarts spamd.
Launch the Instance from the AWS CLI
The following block launches an instance from the SecureAnyCloud SpamAssassin Marketplace AMI into an existing subnet and security group. Replace the values in angle brackets as follows:
- <ami-id>: the AMI ID shown on the Marketplace listing
- <key-name>: your EC2 key pair name
- <subnet-id>: your subnet ID
- <security-group-id>: a security group that opens port 22 from your management network
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--count 1Confirm the spamd Daemon and Its Secure-by-Default Exposure
Connect to the instance over SSH and read the instance note, then check the daemon's status with the bundled sa-access tool. The note is written on first boot and lives at /root/spamassassin-info.txt:
sudo cat /root/spamassassin-info.txtConfirm the daemon is active and locked to loopback with sa-access status:
sudo sa-access statusThe output shows the daemon active, listening on 127.0.0.1, with a loopback-only allow-list. It is not reachable from anywhere off the instance:
SpamAssassin spamd (sac) -- single-node appliance service : active listen : 127.0.0.1 allowed-ips : 127.0.0.1 Live listening sockets (spamd, port 783): LISTEN 0 4096 127.0.0.1:783 0.0.0.0:* users:(("spamd child",pid=6699,fd=4),("spamd child",pid=6698,fd=4),("spamd",pid=6644,fd=4))Confirm that the daemon runs as the non-root debian-spamd user, not as root:
systemctl status spamd.service --no-pager | head -6 ps -o user=,comm= -C spamd | sort -u● spamd.service - Perl-based spam filter using text analysis Loaded: loaded (/usr/lib/systemd/system/spamd.service; enabled; preset: enabled) Drop-In: /etc/systemd/system/spamd.service.d └─override.conf Active: active (running) since Sat 2026-07-25 04:05:24 UTC; 1min 39s ago Main PID: 6644 (spamd) debian-spamd spamdProve Spam Detection with the GTUBE Test String
GTUBE (the Generic Test for Unsolicited Bulk Email) is a standard string that every correctly configured SpamAssassin install scores as spam. Pipe a message that contains it through spamc and inspect the annotated headers:
GTUBE='XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X' printf 'From: attacker@example.net\nTo: victim@example.org\nSubject: cheap meds\n\n%s\n' "$GTUBE" | spamc | grep -E '^X-Spam-(Flag|Level|Status)' | head -4The message is flagged as spam. It carries X-Spam-Flag: YES and a score far over the threshold:
X-Spam-Flag: YES X-Spam-Level: ************************************************** X-Spam-Status: Yes, score=1001.5 required=5.0 tests=GTUBE,MISSING_DATE,Score a Clean Message
A well-formed legitimate message scores below the threshold and is not flagged. Pipe one through spamc and inspect the status header:
printf 'From: alice@example.com\nTo: bob@example.com\nSubject: Lunch tomorrow\n\nHi Bob, are we still on for lunch tomorrow at noon? Thanks, Alice\n' | spamc | grep -E '^X-Spam-Status' | head -1The status shows No. The message is under the threshold and is delivered normally:
X-Spam-Status: No, score=1.5 required=5.0 tests=MISSING_DATE,MISSING_MID,Open spamd to a Trusted Mail-Host Network
By default, nothing off the instance can reach spamd. When you are ready to have your mail servers use this appliance for scanning, allow their network with sa-access allow. Then open TCP 783 to that same network in your EC2 security group.
Replace <your-mgmt-cidr> with the CIDR of your trusted mail-host network:
sudo sa-access allow <your-mgmt-cidr>
sudo sa-access statussa-access refuses a world-open exposure as a hard guardrail. It does not accept * or 0.0.0.0/0. Grant access only to the specific networks you trust.
To revoke a network, use sudo sa-access deny <your-mgmt-cidr>. To revert entirely to the shipped loopback-only default at any time, run:
sudo sa-access loopbackAfter opening spamd, add an inbound rule for TCP 783 from your trusted network to the instance's EC2 security group. sa-access manages the daemon's own allow-list, but the security group is a separate layer that you control.
Integrate with Your Mail Transport Agent
Once spamd is reachable from your mail hosts, point your MTA's content filter at it. SpamAssassin integrates with Postfix, Exim, Sendmail, amavisd and dovecot.
A common pattern is to run amavisd-new (or spamass-milter) on the mail host and have it call this appliance's spamd over TCP 783.
For a quick manual test from a permitted mail host, use the spamc client with the -d (daemon host) option:
spamc -d <vm-ip> -p 783 -c < /path/to/message.emlspamc -c exits 0 for a clean message and 1 for spam, which makes it easy to wire into a delivery pipeline.
Consult your MTA's documentation for the exact content-filter hook. Contact SecureAnyCloud support for an integration walkthrough tailored to your mail stack.
Keep the Rule Set Fresh
The image ships with a current rule set fetched by sa-update at build time, and the operating system's maintenance schedule keeps it refreshed on your instance. You can refresh rules on demand and reload the daemon at any time:
sudo sa-update && sudo systemctl reload spamd.service || sudo systemctl restart spamd.serviceFor sharper detection over time, enable and train Bayesian filtering. Use sa-learn to feed spamd examples of known spam and known ham. SecureAnyCloud support can help you set up automated Bayesian training against your own mail flow.
Security Notes
spamdruns as the dedicated non-rootdebian-spamdsystem user via a systemd drop-in, using an ambient capability to bind the privileged default port without running as root.- The daemon ships bound to
127.0.0.1with a loopback-only allow-list, so it has no network attack surface until you open it. - The
sa-accesstool refuses a world-open exposure, so you cannot accidentally expose the scanner to the whole internet. - SpamAssassin installs unmodified from the operating system's official package archive, so standard unattended security updates cover it.
- Restrict access at both layers, the
sa-accessallow-list and the EC2 security group, to the specific networks you trust.
Support
SecureAnyCloud provides 24/7 technical support for this product by email and live chat.
- Contact: sales@secureanycloud.com
- Response times: critical issues receive a one-hour average response.
- Scope: integrating SpamAssassin with your mail transport agent, opening
spamdto trusted mail hosts safely, score and threshold tuning, custom rule development, keeping the rule set fresh, Bayesian training, performance tuning and maintenance guidance.
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 AWS
Launch Apache SpamAssassin on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com