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

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

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 Repositoryrecommended

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

Debian / Ubuntu

# 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

# 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

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

๐Ÿ“ฆDebian / Ubuntu(amd64)
vspam-agent_0.1.2_amd64.deb
sudo dpkg -i vspam-agent_0.1.2_amd64.deb
๐Ÿ“ฆDebian / Ubuntu(arm64)
vspam-agent_0.1.2_arm64.deb
sudo dpkg -i vspam-agent_0.1.2_arm64.deb
๐Ÿ“ฆRHEL / CentOS / Fedora(x86_64)
vspam-agent-0.1.2-1.x86_64.rpm
sudo rpm -i vspam-agent-0.1.2-1.x86_64.rpm
๐Ÿ“ฆRHEL / CentOS / Fedora(aarch64)
vspam-agent-0.1.2-1.aarch64.rpm
sudo rpm -i vspam-agent-0.1.2-1.aarch64.rpm
๐Ÿ“Linux (manual)(amd64)
vspam-agent-0.1.2-linux-amd64.tar.gz
tar xzf vspam-agent-0.1.2-linux-amd64.tar.gz && sudo cp vspam-agent-*/vspam-agent /usr/local/bin/
๐Ÿ“Linux (manual)(arm64)
vspam-agent-0.1.2-linux-arm64.tar.gz
tar 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

# 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

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

# 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

1. Install via package manager

# 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

2. Configure (optional โ€” works with defaults)

# /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

3. Start the agent

sudo systemctl enable --now vspam-agent
sudo systemctl status vspam-agent

4. Add to Postfix

# /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

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 vspam.org 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 (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.

Configuration Reference

Config file: /etc/vspam/agent.yml

# 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

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.

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.

$ 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.

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.

$ 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

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

vspam-agent version

Systemd Service

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

Lookup Chain

  1. Local cache (BoltDB) โ€” sub-millisecond, avoids network calls for repeat senders
  2. REST API (GET /api/v1/public/operator-lookup) โ€” canonical domain and ASN checks without client-side hashing
  3. 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

Troubleshooting

Agent not starting

sudo journalctl -u vspam-agent -e
# Common: config parse error, port already in use, permission denied

Mail not being checked

# Verify Postfix config
postconf smtpd_recipient_restrictions | grep policy

# Verify agent is listening
ss -tlnp | grep 10045

False positives

# Check why a domain was blocked
sudo journalctl -u vspam-agent | grep "domain.com"

# Request delisting at https://vspam.org/delist

Cache issues

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.

Integration guides โ†’Get an API key โ†’GitHub Releases โ†’