Apache SpamAssassin Anti-Spam Filter on AWS User Guide
Overview
This image runs Apache SpamAssassin, the open source, Apache-2.0 licensed anti-spam platform. SpamAssassin is a rule-based mail filter that scores every message against hundreds of tests - header and body heuristics, Bayesian statistics, DNS blocklists, SPF/DKIM checks and collaborative-filtering signals - and flags anything over a configurable threshold as spam. 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: access control is by network, not by password. The spamd scanning daemon runs as the dedicated non-root debian-spamd system user, and 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:
| OS variant | SSH login user |
|---|---|
| Ubuntu 24.04 LTS | ubuntu |
Use your EC2 key pair, for example:
ssh -i /path/to/your-key.pem ubuntu@<vm-ip>
Step 1: 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 cloudimg listing and choose Select, then 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, and either 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 - during which the appliance writes its per-instance details and restarts spamd - takes a few seconds after the instance state becomes Running and the status checks pass.
Step 2: Launch the Instance from the AWS CLI
The following block launches an instance from the cloudimg SpamAssassin Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with 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 1
Step 3: Confirm the spamd Daemon and Its Secure-by-Default Exposure
SSH into the instance 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.txt
Confirm the daemon is active and locked to loopback with sa-access status:
sudo sa-access status
You will see 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 (cloudimg) -- 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))
You can confirm 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 spamd
Step 4: Prove 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 containing 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 -4
The message is flagged as spam - 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,
Step 5: 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 -1
The 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,
Step 6: 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 status
sa-access refuses a world-open exposure as a hard guardrail - it will 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:
sudo sa-access loopback
After opening spamd, remember to 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 you control.
Step 7: 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.eml
spamc -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, and contact cloudimg support for an integration walkthrough tailored to your mail stack.
Step 8: 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.service
For sharper detection over time, enable and train Bayesian filtering by feeding spamd examples of known spam and known ham with sa-learn. cloudimg support can help you set up automated Bayesian training against your own mail flow.
Step 9: 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; 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 it is covered by standard unattended security updates.
- Always restrict access at both layers - the
sa-accessallow-list and the EC2 security group - to the specific networks you trust.
Support
cloudimg provides 24/7 technical support for this product by email and live chat.
- Contact: support@cloudimg.co.uk
- 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.