diff --git a/crond/crontab b/crond/crontab index 4ed5df72d3db0396d9b98b5828b0433fc8b49396..d8163597c038dc6965aa1beb565e5f00c72efb4a 100644 --- a/crond/crontab +++ b/crond/crontab @@ -1,2 +1,3 @@ @daily docker exec mail_clamd_1 clamd-update @daily docker exec mail_spamd_1 spamd-learn +@daily docker exec mail_spamd_1 spamd-update diff --git a/spamd/.dockerignore b/spamd/.dockerignore index 5638aeaee9c6b6f4a4d2f1127ad7fef552cc78c3..0d163eeb3c98c303325c59cd2b491bbb62f6e4e3 100644 --- a/spamd/.dockerignore +++ b/spamd/.dockerignore @@ -2,3 +2,4 @@ !entrypoint !spamd-ping !spamd-learn +!spamd-update diff --git a/spamd/Dockerfile b/spamd/Dockerfile index 53d1f4c30fc305fc98cc5ace4f8ffdf23e03ae23..5651e9ebf2ad1b7e744b31c1a7d0183bce930711 100644 --- a/spamd/Dockerfile +++ b/spamd/Dockerfile @@ -4,16 +4,23 @@ RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ gnupg \ libmail-spf-perl \ + sa-compile \ spamassassin \ spamc \ && \ - sa-update && \ + usermod --append --groups mail debian-spamd && \ + install -m 640 -o debian-spamd -g debian-spamd /dev/null /var/run/spamd.pid && \ + install -d -m 750 -o debian-spamd -g debian-spamd /run/spamd && \ + install -d -m 750 -o debian-spamd -g debian-spamd /var/backups/sa-learn && \ + rm -rf /run/spamd/* /var/backups/sa-learn/* && \ rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/* /var/cache/apt/archives/* -COPY --chown=root:root spamd-ping spamd-learn /usr/local/bin/ -COPY --chown=root:root entrypoint /entrypoint -EXPOSE 783 +COPY --chown=root:root entrypoint spamd-ping spamd-learn spamd-update /usr/local/bin/ +USER debian-spamd +WORKDIR /var/lib/spamassassin +RUN spamd-update +EXPOSE 7783 VOLUME /run/spamd VOLUME /var/backups/sa-learn -ENTRYPOINT [ "/entrypoint" ] -CMD [ "spamd", "--create-prefs", "--max-children=5", "--helper-home-dir", "--listen=0.0.0.0:783", "--socketpath=/var/run/spamd/spamd.sock", "--syslog=stderr" ] +ENTRYPOINT [ "entrypoint" ] +CMD [ "spamd", "--create-prefs", "--max-children=5", "--helper-home-dir", "--listen=0.0.0.0:7783", "--socketpath=/var/run/spamd/spamd.sock", "--syslog=stderr", "--pidfile=/var/run/spamd.pid" ] HEALTHCHECK CMD spamd-ping diff --git a/spamd/README.md b/spamd/README.md index b70b15d18cc2e30918dfe2b329e667df960235f5..6bd0ffa5b12f8f6742f492d757eba9280cf4d30b 100644 --- a/spamd/README.md +++ b/spamd/README.md @@ -4,7 +4,7 @@ ## Exposed interfaces -The daemon is accessible over TCP at port 783 and over the `spamd.sock` Unix +The daemon is accessible over TCP at port 7783 and over the `spamd.sock` Unix socket in the `/run/spamd` volume. ## Training the Bayesian classifier @@ -16,6 +16,10 @@ database from that volume. To update the database run `spamd-learn` from inside the container with `docker exec` (there's no need to restart the container afterwards). For an example see the [Cron image](../crond) inside this project. +## Updating the rules + +Use the `spamd-update` script in the image. + ## License This software is licensed under the MIT license (see `LICENSE.txt`). diff --git a/spamd/entrypoint b/spamd/entrypoint index 76130f4d148979306ded4d6f26ecdeeffabc9dec..720261aa340c9c9d8ba5385083f9a3a7b21ef3d7 100755 --- a/spamd/entrypoint +++ b/spamd/entrypoint @@ -1,9 +1,9 @@ #!/bin/sh set -eux -install -d -m 750 -o debian-spamd -g debian-spamd /run/spamd -install -d -m 750 -o debian-spamd -g debian-spamd /var/backups/sa-learn - -sh -c 'sleep 60; sa-learn --restore /var/backups/sa-learn/backup.txt' & +if [ -f /var/backups/sa-learn/backup.txt ] +then + sh -c 'sleep 60; sa-learn --restore /var/backups/sa-learn/backup.txt' & +fi eval exec "$@" diff --git a/spamd/spamd-learn b/spamd/spamd-learn index 4c8c4b2266b652c1fa22a28090dc54bad0420f3f..f8c9353ceceabc016f5330f9569b1824e674a3d4 100755 --- a/spamd/spamd-learn +++ b/spamd/spamd-learn @@ -5,9 +5,14 @@ set -eux for user in $(find /var/mail -maxdepth 1 -mindepth 1 -type d) do sa-learn --spam --mbox --forget "$user/Junk" || true - find "$user" -maxdepth 1 -type f -print0 | \ - grep -Zv 'Drafts\|Inbox\|Junk\|Sent' | \ - xargs -0rn1 -- sa-learn --ham --mbox --forget || true + find "$user" \ + -maxdepth 1 \ + -type f \ + \! -name Junk \ + \! -name Inbox \ + \! -name Sent \ + -execdir sa-learn --ham --mbox --forget "{}" \; done +sa-learn --sync sa-learn --backup > /var/backups/sa-learn/backup.txt diff --git a/spamd/spamd-ping b/spamd/spamd-ping index 90c81a7a51d6d4828208fa2503bd485d8d889ca1..e36d2725e93e2f7448453d4c7d9d4130c0040dc2 100755 --- a/spamd/spamd-ping +++ b/spamd/spamd-ping @@ -2,5 +2,5 @@ set -eux sa-check_spamd --verbose --socketpath /run/spamd/spamd.sock || exit 1 -sa-check_spamd --verbose --hostname localhost || exit 1 +sa-check_spamd --verbose --hostname localhost --port 7783 || exit 1 exit 0 diff --git a/spamd/spamd-update b/spamd/spamd-update new file mode 100755 index 0000000000000000000000000000000000000000..18e33e8d82aa7f9f04002eb1a16f3eb7d0ec5f84 --- /dev/null +++ b/spamd/spamd-update @@ -0,0 +1,18 @@ +#!/bin/sh +set -eux + +sa-update --gpghomedir /var/lib/spamassassin/sa-update-keys --verbose || exitcode="$?" + +if [ "${exitcode:-0}" -eq '0' ] +then + echo 'Successful update, recompiling rules and reloading spamd.' >&2 + sa-compile || true + kill -HUP "$(cat /var/run/spamd.pid)" || true +elif [ "${exitcode}" -eq '1' ] +then + echo 'No updates were available, exiting.' >&2 + exit 0 +else + echo "Update failed, exit code $exitcode." >&2 + exit "$exitcode" +fi