[TUTORIAL] Install RSpamD as CustomCheck

ivenae

Well-Known Member
Feb 11, 2022
144
60
48
42
I'm using Rspamd together with a custom script.
Rspamd has many advantages and works well alongside the SpamAssassin filters I’ve fine-tuned. You get a additional score which is great to sort out some additional spam. Bonus: Often it does NOT correlate with my other filters, so it is an added value.


The drawback of the custom script is that no further SpamAssassin checks are executed if the returned score is greater than 5.0 (nobody in the German forum could tell me why this happens). Therefore, I limit the score to 4.9 when outputting it—unless the score is extremely high (>9.0), in which case the email is blocked directly via before-queue filtering.

A further drawback of integrating Rspamd as a custom check is that all of Rspamd's features beyond the score itself remain unused. Among other things, Rspamd supports a considerably more sophisticated greylisting algorithm compared to Proxmox MG, which cannot be used in combination with custom check integration.

  1. Install rspamd
    apt install rspamd

  2. Open the PMG configuration file:

    nano /etc/pmg/pmg.conf

  3. Enable the custom check script by adding or updating the following section:

    section: admin
    custom_check 1
    custom_check_path /usr/local/bin/pmg-custom-check.sh

  4. Create the Custom Script


touch /usr/local/bin/pmg-custom-check.sh
chmod +x /usr/local/bin/pmg-custom-check.sh
cat > /usr/local/bin/pmg-custom-check.sh
Code:
#!/usr/bin/env bash
set -euo pipefail

# PMG custom check API v1: args: APIVERSION QUEUEFILENAME
if [[ $# -ne 2 ]]; then
  echo "usage: $0 APIVERSION QUEUEFILENAME" >&2
  exit 1
fi

apiver="$1"
queue_file="$2"
RSPAMD_HOST="127.0.0.1"
RSPAMD_PORT="11333"

echo "v1"

# Rspamd check
 rspamc_out="$(rspamc -h "${RSPAMD_HOST}:${RSPAMD_PORT}" < "$queue_file" 2>/dev/null || true)"
 score="$(awk -F': ' '/^Score: /{split($2,a," "); print a[1]; exit}' <<<"$rspamc_out")"

if [[ -n "${score:-}" ]]; then
    capped_score=$(awk -v s="$score" 'BEGIN { if (s > 4.9 && s <= 8.9) print 4.9; else print s }')
    echo "SCORE: ${capped_score}"
else
     echo "OK"
fi
exit 0

reboot the server to use custom checks


Rspamd is very fast in this setup (faster than Spam Assassin), usually taking well under 1 second for the additional check.
SA check is skipped, if CustomScore > 5:
2026-03-05T07:13:14.348030+00:00 mx postfix/smtpd[5997]: connect from mail-wm1-f70.google.com[209.85.128.70]
2026-03-05T07:13:14.434342+00:00 mx postfix/smtpd[5997]: NOQUEUE: client=mail-wm1-f70.google.com[209.85.128.70]
2026-03-05T07:13:14.484592+00:00 mx pmg-smtp-filter[5639]: 184AA69A92D0A74AE2: new mail message-id=<0107019cbcd6edd2-c586dc99-d050-4bfb-bf78-46f9e95a80eb-000000@eu-central-1.amazonses.com>
2026-03-05T07:13:15.205887+00:00 mx pmg-smtp-filter[5639]: 184AA69A92D0A74AE2: SA score=21/5 time=0.000 bayes=undefined autolearn=no hits=CustomCheck(21.29)
2026-03-05T07:13:15.208205+00:00 mx pmg-smtp-filter[5639]: 184AA69A92D0A74AE2: block mail to <mymail> (rule: Block Spam (Level 7))
2026-03-05T07:13:15.211333+00:00 mx pmg-smtp-filter[5639]: 184AA69A92D0A74AE2: processing time: 0.73 seconds (0, 0.041, 0.676)
 
Last edited:
  • Like
Reactions: Maschine76
thank you for posting this.
i have implemented this on my gateway that gets quite a bit of mail, i have been thinking about moving to rspamd for a bit but like the appliance format of pmg, this gets me that without having to change my setup much, i see it blocking some of the emails already that have been getting through.

would be cool if we got something like this built in one day.
 
  • Like
Reactions: Maschine76