Train Proxmox Mail Gateway SpamAssassin from cPanel Spam

Proxmox Mail Gateway (PMG) is a great solution for filtering incoming and outgoing mail for spam. By default SpamAssassin in is not trained with what emails should be considered spam and what emails should be allowed to be passed through PMG. As such we need to provide PMG with what is SPAM and what is HAM (not spam). Strangely enough PMG doesn’t provide a very intuitive way to achieve this, so we wrote a script which will feed all junk mail from cPanel accounts to PMG to train SpamAssassin.

Of course tweaking in PMG is also required to make sure you don’t block legitimate mail, but this method certainly gets one started and provides a good base for filtering spam mail.

Step 1 – Create script on PMG to accept data from cPanel server

nano /bin/remote-commands.sh
#!/bin/sh
case "$SSH_ORIGINAL_COMMAND" in
        report)
                sa-learn --spam
                ;;
        revoke)
                sa-learn --ham
                ;;
        *)
                echo "Invalid command?"
                ;;
esac
chmod +x /bin/remote-commands.sh

Step 2 – Generate SSH key on cPanel

ssh-keygen -t rsa -b 4096

Authorize the generated key on PMG with the following command:

ssh-copy-id -i ~/.ssh/id_rsa.pub root@pmg-ip

Step 3 – Edit authorized_keys on PMG to use restricted command

nano ~/.ssh/authorized_keys

Add command=”/bin/remote-commands.sh” in front of the ssh key as follows:

command="/bin/remote-commands.sh" ssh-rsa KEY.. root@hostname

Step 4 – Create the spam reporter script on cPanel

nano /bin/spam-reporter.sh
#!/bin/bash
MAILFILTER=PROXMOX_MAIL_GATEWAY_MAIN_PUBLIC_IP

for i in /home/*/mail/*/*/.spam/cur/* /home/*/mail/*/*/.Junk/cur/* /home/*/mail/.spam/cur/* /home/*/mail/.Junk/cur/* /home/*/mail/*/*/.spam/new/* /home/*/mail/*/*/.Junk/new/* /home/*/mail/.spam/new/* /home/*/mail/.Junk/new/*; do
        if [ -f "$i" ]; then
                STATUS=`file "$i"`
                if [[ $STATUS == *"gzip"* ]]; then
        if [ -f "$i" ]; then
                STATUS=`file "$i"`
                tmp_dir=$(mktemp -d -t spam-reporter-XXXXXXXXXX)
                if [[ $STATUS == *"gzip"* ]]; then
                        gunzip -d -c "$i" > $tmp_dir
                fi
                if [[ $STATUS == *"bzip2"* ]]; then
                        bzip2 -d -c "$i" > $tmp_dir
                fi
                if [[ $STATUS == *"SMTP mail"* ]]; then
                        cp "$i" $tmp_dir
                fi
                find $tmp_dir -type f -exec cat {} \; | ssh -i ~/.ssh/pmg root@$MAILFILTER report
                if [ $? != 0 ]; then
                       echo "Error running sa-learn. Aborting."
                       exit 1
                fi
                rm -f "$i"
                rm -rf $tmp_dir
        fi
done

Be sure to replace PROXMOX_MAIL_GATEWAY_MAIN_PUBLIC_IP with PMG IP

chmod +x /bin/spam-reporter.sh

Step 5 – Create timer specs and timer on the cPanel server to invoke the feeder

nano /etc/systemd/system/spam-reporter.service
[Unit]
Description=This service automatically reports spam.
Wants=spam-reporter.timer

[Service]
Type=oneshot
ExecStart=/bin/spam-reporter.sh

[Install]
WantedBy=multi-user.target
nano /etc/systemd/system/spam-reporter.timer
[Unit]
Description=This is the timer to check for spam and report it.
Requires=spam-reporter.service

[Timer]
Unit=spam-reporter.service
OnCalendar=*:0/5


[Install]
WantedBy=timers.target

Step 6 – Enable the timer

systemctl daemon-reload && systemctl enable spam-reporter.timer --now

Each time junk mail is then received on your cPanel server, this will then be fed back to PMG.

Credit for the scripts go to CRC