Skip to content

Download vspam-agent

Lightweight mail policy daemon that protects Postfix from phishing in real-time. Checks sender domains and IPs against the vspam.org threat database with local caching. Fail-open design — mail is never blocked due to agent errors.

v0.1.2Linux amd64 + arm64AGPL-3.0~10 MB, no deps

Get a free API key to unlock all agent features — higher rate limits, async threat reporting, and community voting. Sign up at vspam.org/account

How it works
Incoming email → Postfix (SMTP)
  → smtpd_recipient_restrictions
    → check_policy_service inet:127.0.0.1:10045
      → vspam-agent
        1. Check local BoltDB cache (sub-ms)
        2. Query operator lookup / exact-host RBL
        3. Query dnsbl.vspam.org (DNS blocklist)
        → DUNNO (allow) or REJECT (block)
        → Async report new threats back to API
Fail-open
API down or DNS errors = allow. Mail is never blocked by agent failure.

Operator-Safe Enforcement Defaults

Primary block path

The agent is best used for canonical phishing domains and exact IPv4 or IPv6 host decisions, where direct evidence and score-aware publication are strongest.

Context, not auto-block

IPv6 prefix watch and ASN reputation are better as operator review signals unless your environment has its own policy layer for broader throttling or inspection.

Trust & correction

Delist requests are reviewed by a human within 48 hours, need no account, and are tracked publicly by ID — see delist policy. Review speed and false-positive trends are public on status, statistics, and methodology.

Install from Repository

Recommended

Automatic updates via your system package manager. Packages hosted on packages.vspam.org.

Debian / Ubuntu

bash
# Add GPG key
curl -fsSL https://packages.vspam.org/apt/vspam-archive-keyring.gpg \
  | sudo gpg --dearmor -o /usr/share/keyrings/vspam-archive-keyring.gpg

# Add repository
echo "deb [signed-by=/usr/share/keyrings/vspam-archive-keyring.gpg] \
  https://packages.vspam.org/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/vspam.list

# Install
sudo apt update && sudo apt install vspam-agent

RHEL / CentOS / Fedora

bash
# Add repository
sudo tee /etc/yum.repos.d/vspam.repo <<EOF
[vspam]
name=vspam.org packages
baseurl=https://packages.vspam.org/rpm/el/9/\$basearch/
enabled=1
gpgcheck=1
gpgkey=https://packages.vspam.org/rpm/RPM-GPG-KEY-vspam
EOF

# Install
sudo dnf install vspam-agent

Manual Download

6 packages · GPG-signed

Download individual packages if you prefer manual installation or don't have repo access.

PlatformArchFileInstall
Debian / Ubuntuamd64vspam-agent_0.1.2_amd64.debsudo dpkg -i vspam-agent_0.1.2_amd64.deb
Debian / Ubuntuarm64vspam-agent_0.1.2_arm64.debsudo dpkg -i vspam-agent_0.1.2_arm64.deb
RHEL / CentOS / Fedorax86_64vspam-agent-0.1.2-1.x86_64.rpmsudo rpm -i vspam-agent-0.1.2-1.x86_64.rpm
RHEL / CentOS / Fedoraaarch64vspam-agent-0.1.2-1.aarch64.rpmsudo rpm -i vspam-agent-0.1.2-1.aarch64.rpm
Linux (manual)amd64vspam-agent-0.1.2-linux-amd64.tar.gztar xzf vspam-agent-0.1.2-linux-amd64.tar.gz && sudo cp vspam-agent-*/vspam-agent /usr/local/bin/
Linux (manual)arm64vspam-agent-0.1.2-linux-arm64.tar.gztar xzf vspam-agent-0.1.2-linux-arm64.tar.gz && sudo cp vspam-agent-*/vspam-agent /usr/local/bin/

All packages available on GitHub Releases and packages.vspam.org/releases.

Verify Packages

All packages are GPG-signed. Verify integrity before installing.

Import GPG public key
bash
# Debian/Ubuntu — key is imported automatically with the repo setup above
# For manual verification:
curl -fsSL https://packages.vspam.org/apt/vspam-archive-keyring.gpg | gpg --import

# RHEL/CentOS/Fedora
sudo rpm --import https://packages.vspam.org/rpm/RPM-GPG-KEY-vspam
Verify tarball checksums
bash
curl -fsSLO https://packages.vspam.org/releases/SHA256SUMS
curl -fsSLO https://packages.vspam.org/releases/SHA256SUMS.asc

# Verify the checksum file signature
gpg --verify SHA256SUMS.asc SHA256SUMS

# Verify your download
sha256sum -c SHA256SUMS --ignore-missing
Verify tarball GPG signature
bash
# Each tarball has a detached .asc signature
curl -fsSLO https://packages.vspam.org/releases/vspam-agent-0.1.2-linux-amd64.tar.gz
curl -fsSLO https://packages.vspam.org/releases/vspam-agent-0.1.2-linux-amd64.tar.gz.asc
gpg --verify vspam-agent-0.1.2-linux-amd64.tar.gz.asc
GPG key fingerprint
Key ID: admin@vspam.org — verify at packages.vspam.org/apt/vspam-archive-keyring.gpg

Quick Start

4 steps
1Install via package manager
bash
# Debian/Ubuntu (after adding repo — see above)
sudo apt update && sudo apt install vspam-agent

# RHEL/CentOS/Fedora (after adding repo — see above)
sudo dnf install vspam-agent
2ConfigureOptional · works with defaults
yaml
# /etc/vspam/agent.yml
api_url: https://api.vspam.org
api_key: "your-key-here"        # optional, get one at vspam.org/account
listen: tcp://127.0.0.1:10045
cache_ttl: 10m
dnsbl_enabled: true
dnsbl_zone: dnsbl.vspam.org
3Start the agent
bash
sudo systemctl enable --now vspam-agent
sudo systemctl status vspam-agent
4Add to Postfix
ini
# /etc/postfix/main.cf

# Fail open. Postfix defaults to deferring every message with a 451 when a
# policy service is unreachable, on a 100s timeout, so these two lines matter
# more than the third: without them, an agent restart stops your mail.
smtpd_policy_service_default_action = DUNNO
smtpd_policy_service_timeout = 10s

smtpd_recipient_restrictions =
    permit_mynetworks,
    permit_sasl_authenticated,
    reject_unauth_destination,
    check_policy_service inet:127.0.0.1:10045

# Then reload
sudo postfix reload

Configuration Reference

Config file: /etc/vspam/agent.yml

yaml
# vspam.org API endpoint
api_url: https://api.vspam.org

# API key (get one at https://vspam.org/account)
api_key: "vspam_xxxxxxxxxxxx"

# Policy daemon listen address
listen: tcp://127.0.0.1:10045

# Local cache (BoltDB)
cache_ttl: 10m
cache_path: /var/lib/vspam/cache.db

# DNSBL lookup
dnsbl_enabled: true
dnsbl_zone: dnsbl.vspam.org

# Reject message for blocked senders
reject_message: "550 Message rejected: sender listed in vspam.org (phishing)"

# Auto-report (requires api_key)
reporting_enabled: true
queue_size: 1000

log_level: info

Lookup Chain

01
Local cache BoltDB

Sub-millisecond, avoids network calls for repeat senders.

02
REST API
GET /api/v1/public/operator-lookup

Canonical domain and ASN checks without client-side hashing.

03
IP RBL / DNSBL
GET /api/v1/rbl/check?ip=... or dig <domain>.dnsbl.vspam.org A

Exact IPv4 / IPv6 host checks and direct DNSBL policy lookups.

First definitive result wins
Cache stores both positive (malicious) and negative (clean) results with configurable TTL.

Security

Runs as unprivileged vspam system user
Systemd hardening: NoNewPrivileges, ProtectSystem=strict, PrivateTmp
API key stored in config file with 0640 permissions
Fail-open: lookup errors never block mail delivery
Cache prevents API/DNS amplification from high mail volume

Why It Stays Out Of The Way

Fail-open

API down or DNS errors = allow (DUNNO). Mail never blocked by agent failure.

Fast

BoltDB cache means repeat lookups are sub-millisecond.

Async reporting

Blocked senders are reported to the API in the background. SMTP response is never delayed.

Lightweight

Single Go binary, ~10 MB, no dependencies.

Operator-safe by design

Exact hosts and canonical domains are the main enforcement path; broader IPv6 prefix and ASN context should stay in review workflows unless you have explicit policy for them.

Command Line

The same binary is the CLI, so installing the package gets you both — one version, one signature, one thing to upgrade. Serving stays the default, so the systemd unit is unaffected.

bash
vspam-agent check <indicator>...   # exit 1 if any are listed
vspam-agent report <indicator>     # submit one
vspam-agent bulk [file]            # submit many, one per line (stdin by default)
vspam-agent eml [file]             # extract indicators from a message

Checking

Exit codes are the interface: 0 nothing listed, 1 something listed, 2 the lookup failed. A failed lookup is deliberately not 0 — a script gating mail on this should fail loudly rather than let a message through because DNS was down. No API key is needed; one raises the rate limit.

bash
$ vspam-agent check login-paypa1.com safe.example.org
login-paypa1.com                         LISTED   phishing_domain (consensus)
safe.example.org                         clean

if ! vspam-agent check "$DOMAIN" >/dev/null; then echo "refusing $DOMAIN"; fi

Reporting

Type and category are inferred using the same rules as the web submit form, and defanged input is normalized. Lists longer than the API’s 100-per-request cap are split across requests rather than rejected. --dry-run prints what would be sent and submits nothing.

bash
vspam-agent report --evidence "credential harvest, seen 2026-08-26" \
  'hxxps://login-paypa1[.]com/verify'

grep -oP 'https?://\S+' quarantine.log | vspam-agent bulk

Message files

Reads the sender addresses, the connecting IP from the header your own MX wrote, and links in the text parts. The message is parsed locally and never uploaded — only the extracted indicators are sent, and only with --report.

bash
$ vspam-agent eml suspicious.eml
email      from             support@evil.example.net
ip         received         203.0.113.66
url        body             https://login.evil.example.net/verify?u=1

3 indicators. Re-run with --report to submit them.

Running the daemon

bash
# Serving is the default, so the subcommand is optional
vspam-agent
vspam-agent --config /etc/vspam/agent.yml serve

vspam-agent version

Systemd Service

bash
sudo systemctl start vspam-agent    # Start
sudo systemctl stop vspam-agent     # Stop
sudo systemctl restart vspam-agent  # Restart
sudo systemctl status vspam-agent   # Status
sudo journalctl -u vspam-agent -f   # Logs

Troubleshooting

Agent not starting
bash
sudo journalctl -u vspam-agent -e
# Common: config parse error, port already in use, permission denied
Mail not being checked
bash
# Verify Postfix config
postconf smtpd_recipient_restrictions | grep policy

# Verify agent is listening
ss -tlnp | grep 10045
False positives
bash
# Check why a domain was blocked
sudo journalctl -u vspam-agent | grep "domain.com"

# Request delisting at https://vspam.org/delist
Cache issues
bash
sudo systemctl stop vspam-agent
sudo rm /var/lib/vspam/cache.db
sudo systemctl start vspam-agent

Source

The filter configuration — the Rspamd module, the SpamAssassin rules, the Ansible role and the mailcow overlay — is public and AGPL-3.0 licensed at github.com/vspam-org/integrations. The agent daemon's repository is not published yet; the binaries above are built from it and signed with the key below.