From 6c2dc20d1bd4100572017704e429ffaa8c55cc15 Mon Sep 17 00:00:00 2001 From: Martin Winkler Date: Sun, 17 Jan 2021 13:47:08 +0100 Subject: [PATCH] New seqs for spamassassin and postgrey --- seqs/postgrey.sh | 80 +++++++++++++++++++++++ seqs/spamass.sh | 161 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 241 insertions(+) create mode 100755 seqs/postgrey.sh create mode 100755 seqs/spamass.sh diff --git a/seqs/postgrey.sh b/seqs/postgrey.sh new file mode 100755 index 0000000..50a4e26 --- /dev/null +++ b/seqs/postgrey.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +toolName=postgrey +toolDeps="$toolName" +toolWhitelistLoc="/etc/postgrey/whitelist_clients" +updateUrl="https://postgrey.schweikert.ch/pub/postgrey_whitelist_clients" + +# Get script working directory +# (when called from a different directory) +WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )" +CONFIG=0 +CONFIG_FILE_NAME="${toolName}.cfg" +CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example" + +#step_config() { +# echo "Called once before executing steps." +# ## e.g. to source a config file manually: +# #. "$CONFIG_FILE" +# ## or to use sequencer api: +# #initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE" +# #if [ $? -eq 0 ] ; then +# # CONFIG=1 +# #fi +#} + +step_1_info() { echo "Install $toolDeps"; } +step_1_alias() { ALIAS="install"; } +step_1() { + local aptOpt= + if [ $QUIET -ne 0 ];then + aptOpt="-y" + fi + exe apt update + exe apt install "$toolDeps" $aptOpt +} + +step_2_info() { + echo "Add cron to update whitelist_clients from" + echoinfo "$updateUrl" +} +step_2_alias() { ALIAS="cron"; } +step_2() { + addConf -s "$postCron" "$postCronLoc" +} +postCronLoc="/etc/cron.d/postgreyWhitelistUpdate" +postCron="# -q quiet -N timestamping (overwrite existing file) -O target file +01 23 5 * * root /usr/bin/wget -qNO \"$toolWhitelistLoc\" $updateUrl && /usr/sbin/service postgrey restart" + +step_3_info() { echo "Configuration notes"; } +step_3_alias() { ALIAS="notes"; } +step_3() { + echo "$toolNotes" +} +toolNotes=" +# Reduce default message delay to 1 minute + [/etc/default/postgrey] + POSTGREY_OPTS=\"--inet=10023 --delay=60\" + +# Custom local whitelist rules + [/etc/postgrey/whitelist_clients.local] + # Rule examples + # own domains + mydomain.com + # own network + /^.*\.(lan|local)$/ + 192.168.0.0/24 + fd21::/64 + # External domains in frequent use + # Amazon mail system + amazonses.com +" + +step_10_info() { echo "Restart $toolName"; } +step_10_alias() { ALIAS="restart"; } +step_10() { + exe service $toolName restart +} + +VERSION_SEQREV=11 +. /usr/local/bin/sequencer.sh diff --git a/seqs/spamass.sh b/seqs/spamass.sh new file mode 100755 index 0000000..d9c1fc4 --- /dev/null +++ b/seqs/spamass.sh @@ -0,0 +1,161 @@ +#!/bin/bash + +toolName=spamassassin +toolDeps="$toolName spamc" +toolUser='debian-spamd' + +# Get script working directory +# (when called from a different directory) +WDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )" +CONFIG=0 +CONFIG_FILE_NAME="${toolName}.cfg" +CONFIG_FILE_TEMPLATE="$WDIR/${CONFIG_FILE_NAME}.example" + +#step_config() { +# echo "Called once before executing steps." +# ## e.g. to source a config file manually: +# #. "$CONFIG_FILE" +# ## or to use sequencer api: +# #initSeqConfig "$CONFIG_FILE_NAME" "$CONFIG_FILE_TEMPLATE" +# #if [ $? -eq 0 ] ; then +# # CONFIG=1 +# #fi +#} + +step_1_info() { + echo "Install packages: $toolDeps" + echoinfo "May take a long time" +} +step_1_alias() { ALIAS="install"; } +step_1() { + local aptOpt= + if [ $QUIET -ne 0 ];then + aptOpt="-y" + fi + exe apt update + exe apt install $toolDeps $aptOpt +} + +step_20_info() { echo "List spam/ham counts"; } +step_20() { + exe mysql -D $SA_BAYES_DBNAME -e 'select username,spam_count,ham_count from bayes_vars;' +} +SA_BAYES_DBNAME='spambayes_db' + +step_50_info() { echo "Notes"; } +step_50_alias() { ALIAS="notes"; } +step_50() { + echo "$notes" +} +notes=' +# Configuration + [/etc/default/spamassassin] + CRON=1 + + [/etc/spamassassin/local.cf] + # Customize there + + [/etc/postfix/master.cf] + smtp inet n - - - - smtpd + [...] + -o content_filter=spamassassin + + submission inet n - - - - smtpd + [...] + -o content_filter=spamassassin + + smtps inet n - y - - smtpd + [...] + -o content_filter=spamassassin + + + spamassassin unix - n n - - pipe + user=debian-spamd argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f ${sender} ${recipient} + +# Bayes data in mysql + * Create empty database spambayes_db + + [/etc/spamassassin/local.cf] + bayes_store_module Mail::SpamAssassin::BayesStore::MySQL + bayes_sql_dsn DBI:mysql:spambayes_db:localhost + bayes_sql_username user + bayes_sql_password pass + +# Global sieve script for spam to junk + * If sieve before is a folder all scripts inside are executed + + [/etc/dovecot/conf.d/90-sieve.conf] + sieve_before = /var/lib/dovecot/sieve.d/ + + * The global sieve script needs to be compiled with sievec + and changed group to vmail for access permissions + (chown root:vmail script; chmod 750 script) + + [/var/lib/dovecot/sieve.d/spam-global.sieve] + require "fileinto"; + if header :contains "X-Spam-Flag" "YES" { + fileinto "Junk"; + } + + +# Configure sieve as replacement for deprecated plugin dovecot-antispam + https://doc.dovecot.org/configuration_manual/howto/antispam_with_sieve/ + + [/etc/dovecot/conf.d/20-imap.conf] + mail_plugins = $mail_plugins imap_sieve + + [/etc/dovecot/conf.d/90-sieve.conf] + sieve_plugins = sieve_imapsieve sieve_extprograms + + # From elsewhere to Spam folder + imapsieve_mailbox1_name = Spam + imapsieve_mailbox1_causes = COPY + imapsieve_mailbox1_before = file:/usr/lib/dovecot/sieve-pipe/report-spam.sieve + + # From Spam folder to elsewhere + imapsieve_mailbox2_name = * + imapsieve_mailbox2_from = Spam + imapsieve_mailbox2_causes = COPY + imapsieve_mailbox2_before = file:/usr/lib/dovecot/sieve-pipe/report-ham.sieve + + sieve_extensions = +notify +imapflags +vnd.dovecot.execute + sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment + + [/etc/dovecot/conf.d/90-sieve-extprograms.conf + sieve_pipe_bin_dir = /usr/lib/dovecot/sieve-pipe + sieve_execute_bin_dir = /usr/lib/dovecot/sieve-execute + + [/usr/lib/dovecot/sieve-pipe/report-spam.sieve] + require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"]; + if environment :matches "imap.user" "*" { + set "username" "${1}"; + pipe :copy "sa-learn-spam.sh" [ "${username}" ]; + + [/usr/lib/dovecot/sieve-pipe/report-ham.sieve] + require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"]; + if environment :matches "imap.mailbox" "*" { + set "mailbox" "${1}"; + } + if string "${mailbox}" "Trash" { + stop; + } + if environment :matches "imap.user" "*" { + set "username" "${1}"; + } + pipe :copy "sa-learn-ham.sh" [ "${username}" ]; + + [/usr/lib/dovecot/sieve-pipe/sa-learn-spam.sh] + #!/bin/sh + # sa-learn is used in parallel. Be aware of system resources when + # moving multiple messages at the same time + saNewSpam=$(cat);( echo "$saNewSpam" | /usr/bin/sa-learn -u ${1} --spam ) & + + [/usr/lib/dovecot/sieve-pipe/sa-learn-ham.sh] + #!/bin/sh + # sa-learn is used in parallel. Be aware of system resources when + # moving multiple messages at the same time + saNewHam=$(cat);( echo "$saNewHam" | /usr/bin/sa-learn -u ${1} --ham ) & +' + +VERSION_SEQREV=11 +. /usr/local/bin/sequencer.sh