Files
shell_sequencer/seqs/rspamd.sh

244 lines
7.5 KiB
Bash
Executable File

#!/usr/bin/env bash
readonly toolName=rspamd
# Already defined by sequencer.sh, but may be overwritten
#readonly seq_configName="${sq_scriptName:?}.cfg"
#readonly seq_configTemplate="${seq_origin:?}/${sq_configName:?}.example"
sq_aptOpt=
sq_config=0
seq_config() {
## Called once before executing steps.
## e.g. to source a config file manually:
#. "${seq_origin:?}/${seq_configName:?}"
## or to use sequencer api with profile config file support:
#if initSeqConfig -p "${seq_fileName:?}" "${seq_configTemplate:?}" ; then
## or to use sequencer api with global config file:
#if initSeqConfig "${seq_configName:?}" "${seq_configTemplate:?}" ; then
# sq_config=1
#else
# # End if no configuration file exists
# dry || return 1
#fi
## Apt cmdline option to suppress user interaction
interactive || sq_aptOpt="-y"
## Disable error checks if external scripts are used
## e.g. error on unbound variables
#disableErrorCheck
## Return of non zero value will abort the sequence
return 0
}
step_1_info() { echo "Setup custom repository for raspberry pi OS"; }
step_1_alias() { echo "install"; }
step_1() {
local lRaspbianRelease="Raspbian_$(lsb_release -sr)"
local lFileName="home_susenerf_rspamd-exotic-debian"
local lRepoUrl="http://download.opensuse.org/repositories/home:/susenerf:/rspamd-exotic-debian"
exep echo "deb ${lRepoUrl}/${lRaspbianRelease}/ /" "|" sudo tee /etc/apt/sources.list.d/${lFileName}.list
exep curl -fsSL "${lRepoUrl}/${lRaspbianRelease}/Release.key" "|" gpg --dearmor "|" sudo tee /etc/apt/trusted.gpg.d/${lFileName}.gpg ">" /dev/null
exe apt update
}
step_2_info() { echo "Install ${toolName} with apt"; }
step_2() {
exe apt install rspamd redis-server
}
step_10_info() { echo "Add ufw rule for WebUI (11334)"; }
step_10_alias() { echo "ufw"; }
step_10() {
exe ufw allow 11334/tcp comment "rspamd WebUI"
}
step_50_info() { echo "Notes"; }
step_50_alias() { echo "notes"; }
step_50() {
color green
cat <<NOTES_END
# Configuration
First generate a new encrypted password string to be used
with the web UI of ${toolName}
rspamadm pw
and insert the result into:
[/etc/rspamd/local.d/worker-controller.inc]
bind_socket = "*:11334";
password = <Result of rspamadm pw>
enable_password = <Result of rspamadm pw>
[/etc/rspamd/local.d/redis.conf]
server = "127.0.0.1";
timeout = 3s;
[/etc/rspamd/local.d/classifier-bayes.conf]
backend = "redis";
autolearn = true;
[/etc/rspamd/local.d/dkim_signing.conf]
enabled = false;
[/etc/rspamd/local.d/milter_headers.conf]
authenticated_headers = ["authentication-results"];
use = ["x-spamd-result","x-spam-level","x-spamd-bar", "my-x-spam-score","x-spam-status", "authentication-results"];
# add X-Spam-Score header (like SA does)
# Source: https://groups.google.com/forum/#!topic/rspamd/fEdbnG0J18I
custom {
my-x-spam-score = <<EOD
return function(task, common_meta)
local sc = common_meta['metric_score'] or task:get_metric_score()
-- return no error
return nil,
-- header(s) to add
{['X-Spam-Score'] = string.format('%.2f', sc[1])},
-- header(s) to remove
{['X-Spam-Score'] = 1},
-- metadata to store
{}
end
EOD;
}
[/etc/rspamd/local.d/phishing.conf]
openphish_enabled = true;
phishtank_enabled = true;
[/etc/rspamd/local.d/greylist.conf]
enabled = true;
timeout = 1min;
[/etc/rspamd/local.d/mx_check.conf]
enabled = true;
timeout = 5.0;
# A map of specific domains that should be excluded from MX check
exclude_domains = [
"https://maps.rspamd.com/freemail/disposable.txt.zst",
"https://maps.rspamd.com/freemail/free.txt.zst",
"\${CONFDIR}/maps.d/maillist.inc",
"\${CONFDIR}/maps.d/redirectors.inc",
"\${CONFDIR}/maps.d/dmarc_whitelist.inc",
"\${CONFDIR}/maps.d/surbl-whitelist.inc",
"\${CONFDIR}/maps.d/spf_dkim_whitelist.inc",
];
## Don't check mails send from local network
[/etc/rspamd/local.d/multimap.conf]
IP_WHITELIST {
type = "ip";
prefilter = true;
map = "/\${LOCAL_CONFDIR}/local.d/ip_whitelist.map";
action = "accept";
description = "Accept mails from local network"
}
#WHITELIST_SENDER_DOMAIN {
# type = "from";
# filter = "email:domain";
# map = "/etc/rspamd/local.d/whitelist.sender.domain.map";
# score = -6.0
#}
[/etc/rspamd/local.d/ip_whitelist.map]
fd00::/8
192.168.0.0/16
10.0.0.0/8
# Configuring Postfix
[/etc/postfix/main.cf]
# Invoke rspamd to check for spam
smtpd_milters = inet:localhost:11332
# skip mail without checks if something goes wrong
milter_default_action = accept
# 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 "rspamd-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 "rspamd-learn-ham.sh" [ "\${username}" ];
[/usr/lib/dovecot/sieve-pipe/rspamd-learn-spam.sh]
#!/bin/sh
# rspamc learn is used in parallel. Be aware of system resources when
# moving multiple messages at the same time
rspamdNewSpam=\$(cat);( echo "\$rspamdNewSpam" | /usr/bin/rspamc learn_spam ) &
[/usr/lib/dovecot/sieve-pipe/rspamd-learn-ham.sh]
#!/bin/sh
# rspamc learn is used in parallel. Be aware of system resources when
# moving multiple messages at the same time
rspamdNewHam=\$(cat);( echo "\$rspamdNewHam" | /usr/bin/rspamc learn_ham ) &
NOTES_END
}
# shellcheck disable=SC2034 # Appears unused
readonly sqr_minVersion=16
# shellcheck disable=SC1091 # Don't follow this source
. /usr/local/bin/sequencer.sh