diff --git a/bundles/rspamd/files/dkim.conf b/bundles/rspamd/files/dkim.conf new file mode 100644 index 0000000..3ca59d9 --- /dev/null +++ b/bundles/rspamd/files/dkim.conf @@ -0,0 +1,4 @@ +# TODO +path = "/var/lib/rspamd/dkim/$selector.key"; +selector = "2019"; +allow_username_mismatch = true; diff --git a/bundles/rspamd/files/ip_whitelist.map b/bundles/rspamd/files/ip_whitelist.map new file mode 100644 index 0000000..416ea5f --- /dev/null +++ b/bundles/rspamd/files/ip_whitelist.map @@ -0,0 +1,3 @@ +% for ip in sorted(node.metadata.get('rspamd', {}).get('ignore_spam_check_for_ips', set())): +${ip} +% endfor diff --git a/bundles/rspamd/files/local.d/classifier-bayes.conf b/bundles/rspamd/files/local.d/classifier-bayes.conf new file mode 100644 index 0000000..e3dd51a --- /dev/null +++ b/bundles/rspamd/files/local.d/classifier-bayes.conf @@ -0,0 +1 @@ +backend = "redis"; diff --git a/bundles/rspamd/files/local.d/logging.inc b/bundles/rspamd/files/local.d/logging.inc new file mode 100644 index 0000000..01dc2c4 --- /dev/null +++ b/bundles/rspamd/files/local.d/logging.inc @@ -0,0 +1,2 @@ +systemd = true; +type = "console"; diff --git a/bundles/rspamd/files/local.d/milter_headers.conf b/bundles/rspamd/files/local.d/milter_headers.conf new file mode 100644 index 0000000..73bc830 --- /dev/null +++ b/bundles/rspamd/files/local.d/milter_headers.conf @@ -0,0 +1,2 @@ +use = ["x-spamd-bar", "x-spam-level", "authentication-results"]; +authenticated_headers = ["authentication-results"]; diff --git a/bundles/rspamd/files/local.d/multimap.conf b/bundles/rspamd/files/local.d/multimap.conf new file mode 100644 index 0000000..66935ea --- /dev/null +++ b/bundles/rspamd/files/local.d/multimap.conf @@ -0,0 +1,6 @@ +IP_WHITELIST { + type = "ip"; + prefilter = true; + map = "/etc/rspamd/local.d/ip_whitelist.map"; + action = "accept"; +} diff --git a/bundles/rspamd/files/local.d/redis.conf b/bundles/rspamd/files/local.d/redis.conf new file mode 100644 index 0000000..5a9c582 --- /dev/null +++ b/bundles/rspamd/files/local.d/redis.conf @@ -0,0 +1 @@ +servers = "127.0.0.1"; diff --git a/bundles/rspamd/files/local.d/worker-normal.inc b/bundles/rspamd/files/local.d/worker-normal.inc new file mode 100644 index 0000000..e26e6b8 --- /dev/null +++ b/bundles/rspamd/files/local.d/worker-normal.inc @@ -0,0 +1 @@ +bind_socket = "localhost:11333"; diff --git a/bundles/rspamd/files/local.d/worker-proxy.inc b/bundles/rspamd/files/local.d/worker-proxy.inc new file mode 100644 index 0000000..e49b3ec --- /dev/null +++ b/bundles/rspamd/files/local.d/worker-proxy.inc @@ -0,0 +1,7 @@ +bind_socket = "localhost:11332"; +milter = yes; +timeout = 120s; +upstream "local" { + default = yes; + self_scan = yes; +} diff --git a/bundles/rspamd/files/override.d/antivirus.conf b/bundles/rspamd/files/override.d/antivirus.conf new file mode 100644 index 0000000..5dd7791 --- /dev/null +++ b/bundles/rspamd/files/override.d/antivirus.conf @@ -0,0 +1,6 @@ +clamav { + servers = "/run/clamav/clamd.ctl"; + action = "reject"; + type = "clamav"; + symbol = "CLAM_VIRUS"; +} diff --git a/bundles/rspamd/files/worker-controller.inc b/bundles/rspamd/files/worker-controller.inc new file mode 100644 index 0000000..b202913 --- /dev/null +++ b/bundles/rspamd/files/worker-controller.inc @@ -0,0 +1 @@ +password = "${node.metadata['rspamd']['password']}"; diff --git a/bundles/rspamd/items.py b/bundles/rspamd/items.py new file mode 100644 index 0000000..b8ceaeb --- /dev/null +++ b/bundles/rspamd/items.py @@ -0,0 +1,88 @@ +from os import listdir +from os.path import join + +directories = { + '/etc/rspamd/local.d': { + 'purge': True, + 'needs': { + 'pkg_apt:rspamd', + }, + 'triggers': { + 'svc_systemd:rspamd:restart', + }, + }, + '/etc/rspamd/override.d': { + 'purge': True, + 'needs': { + 'pkg_apt:rspamd', + }, + 'triggers': { + 'svc_systemd:rspamd:restart', + }, + }, +} + +svc_systemd = { + 'rspamd': { + 'needs': { + 'file:', + 'pkg_apt:rspamd', + }, + }, + 'clamav-daemon': { + 'needs': { + 'pkg_apt:clamav', + 'pkg_apt:clamav-daemon', + }, + }, + 'clamav-freshclam': { + 'needs': { + 'pkg_apt:clamav-freshclam', + }, + }, +} + +files = { + '/etc/rspamd/local.d/ip_whitelist.map': { + 'content_type': 'mako', + 'triggers': { + 'svc_systemd:rspamd:restart', + }, + }, +} + +# TODO manage this using bundlewrap +if node.metadata.get('rspamd', {}).get('dkim', False): + for i in {'arc', 'dkim_signing'}: + files[f'/etc/rspamd/local.d/{i}.conf'] = { + 'source': 'dkim.conf', + 'triggers': { + 'svc_systemd:rspamd:restart', + }, + } + +if 'password' in node.metadata.get('rspamd', {}): + files['/etc/rspamd/local.d/worker-controller.inc'] = { + 'content_type': 'mako', + 'triggers': { + 'svc_systemd:rspamd:restart', + }, + } + +local_config_path = join(repo.path, 'bundles', 'rspamd', 'files', 'local.d') +for f in listdir(local_config_path): + files[f'/etc/rspamd/local.d/{f}'] = { + 'source': f'local.d/{f}', + 'triggers': { + 'svc_systemd:rspamd:restart', + }, + } + +override_config_path = join(repo.path, 'bundles', 'rspamd', 'files', 'override.d') +for f in listdir(override_config_path): + files[f'/etc/rspamd/override.d/{f}'] = { + 'source': f'override.d/{f}', + 'triggers': { + 'svc_systemd:rspamd:restart', + }, + } diff --git a/bundles/rspamd/metadata.py b/bundles/rspamd/metadata.py index 380dc4a..720dd24 100644 --- a/bundles/rspamd/metadata.py +++ b/bundles/rspamd/metadata.py @@ -1,8 +1,40 @@ # WIP defaults = { 'apt': { + 'repos': { + 'rspamd': { + 'items': { + 'deb [arch=amd64] http://rspamd.com/apt-stable/ {os_release} main', + }, + }, + }, 'packages': { + 'clamav': {}, + 'clamav-daemon': {}, + 'clamav-freshclam': {}, + 'clamav-unofficial-sigs': {}, 'rspamd': {}, }, }, + 'cron': { + 'clamav-unofficial-sigs': f'{node.magic_number%60} */4 * * * clamav /usr/sbin/clamav-unofficial-sigs >/dev/null', + }, } + + +# Nodes managed by us should always be able to send mail to all other +# servers. +@metadata_reactor +def populate_permitted_ips_list_with_ips_from_repo(metadata): + ips = set() + + for rnode in repo.nodes: + for ip in repo.libs.tools.resolve_identifier(repo, rnode.name): + if not ip.is_private: + ips.add(str(ip)) + + return { + 'rspamd': { + 'ignore_spam_check_for_ips': ips, + }, + } diff --git a/nodes/htz/ex42-1048908.py b/nodes/htz/ex42-1048908.py index 6715b26..e61feac 100644 --- a/nodes/htz/ex42-1048908.py +++ b/nodes/htz/ex42-1048908.py @@ -96,14 +96,8 @@ nodes['htz.ex42-1048908'] = { 'matrix.franzi.business': { 'franzi.business', }, - 'mx0.kunbox.net': set(), # TODO move to bundle 'part.of.the.trans-agenda.eu': set(), }, - 'reload_after': { - # TODO move to bundles - 'dovecot', - 'postfix', - }, }, 'matrix-synapse': { 'server_name': 'franzi.business', @@ -197,7 +191,7 @@ nodes['htz.ex42-1048908'] = { 'extras': True, }, 'postfixadmin.mx0.kunbox.net': { - 'webroot': '/srv/postfixadmin/public/', + 'webroot': '/opt/postfixadmin/public/', 'php': True, }, 'rspamd.mx0.kunbox.net': { @@ -281,6 +275,30 @@ nodes['htz.ex42-1048908'] = { }, }, }, + 'rspamd': { + 'dkim': True, + 'ignore_spam_check_for_ips': { + # entropia + '188.40.158.213', + '188.40.158.214', + '188.40.158.218', + '2a01:4f8:221:2f83:2130::2', + '2a01:4f8:221:2f83:2140::2', + '2a01:4f8:221:2f83:2180::2', + # ccc + '212.12.55.65', + '212.12.55.67', + '2a00:14b0:4200:3000:23:55:0:65', + # IN-Berlin mailman + '130.133.8.35', + '192.109.42.28', + '193.29.188.9', + '217.197.80.23', + '217.197.80.134', + '2001:bf0:c000:a::2:134', + }, + 'password': vault.decrypt('encrypt$gAAAAABfp7qzym32R6Go1A6oax0NGQM7EBMckbEbnZC6-RSKx-klSJsL57XbSUTD-AJM-gBIPzlmor-3bfVxPWLRYXtO8uTVw6jNQ1yt15ReHkOTijVqV2ACk-LTDBG3p4YKBn0pQgNvvjXhWV_J1-Pgjywbl4sHXc0zqjCGZ6xtEn6ywj0Pd599JJjREF4QCIFVZVWuKvo1'), + }, 'travelynx': { 'version': '1.18.7', 'mail_from': 'travelynx@franzi.business',