From b236fd3ac683ea1434521807c5d118040b54882c Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Tue, 30 Jan 2024 10:15:33 +0100 Subject: [PATCH 1/5] [Netfilter] add mailcow isolation rule to MAILCOW chain [Netfilter] add mailcow rule to docker-user chain [Netfilter] add mailcow isolation rule to MAILCOW chain [Netfilter] add mailcow isolation rule to MAILCOW chain [Netfilter] set mailcow isolation rule before redis [Netfilter] clear bans in redis after connecting [Netfilter] simplify mailcow isolation rule for compatibility with iptables-nft [Netfilter] stop container after mariadb, redis, dovecot, solr [Netfilter] simplify mailcow isolation rule for compatibility with iptables-nft [Netfilter] add exception for mailcow isolation rule for HA setups [Netfilter] add exception for mailcow isolation rule for HA setups [Netfilter] add DISABLE_NETFILTER_ISOLATION_RULE [Netfilter] fix wrong var name [Netfilter] add DISABLE_NETFILTER_ISOLATION_RULE to update and generate_config sh --- .gitignore | 1 + data/Dockerfiles/dovecot/docker-entrypoint.sh | 9 + data/Dockerfiles/netfilter/main.py | 90 ++++++---- .../Dockerfiles/netfilter/modules/IPTables.py | 39 +++++ data/Dockerfiles/netfilter/modules/Logger.py | 3 +- .../Dockerfiles/netfilter/modules/NFTables.py | 165 +++++++++++++++++- data/conf/dovecot/dovecot.conf | 3 + docker-compose.yml | 16 +- generate_config.sh | 3 + update.sh | 8 + 10 files changed, 290 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index 3595ecb1..e25639a7 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ data/conf/dovecot/acl_anyone data/conf/dovecot/dovecot-master.passwd data/conf/dovecot/dovecot-master.userdb data/conf/dovecot/extra.conf +data/conf/dovecot/mail_replica.conf data/conf/dovecot/global_sieve_* data/conf/dovecot/last_login data/conf/dovecot/lua diff --git a/data/Dockerfiles/dovecot/docker-entrypoint.sh b/data/Dockerfiles/dovecot/docker-entrypoint.sh index f1e2e966..a9545f33 100755 --- a/data/Dockerfiles/dovecot/docker-entrypoint.sh +++ b/data/Dockerfiles/dovecot/docker-entrypoint.sh @@ -335,6 +335,15 @@ sys.exit() EOF fi +# Set mail_replica for HA setups +if [[ -n ${MAILCOW_REPLICA_IP} && -n ${DOVEADM_REPLICA_PORT} ]]; then + cat < /etc/dovecot/mail_replica.conf +# Autogenerated by mailcow +mail_replica = tcp:${MAILCOW_REPLICA_IP}:${DOVEADM_REPLICA_PORT} +EOF +fi + + # 401 is user dovecot if [[ ! -s /mail_crypt/ecprivkey.pem || ! -s /mail_crypt/ecpubkey.pem ]]; then openssl ecparam -name prime256v1 -genkey | openssl pkey -out /mail_crypt/ecprivkey.pem diff --git a/data/Dockerfiles/netfilter/main.py b/data/Dockerfiles/netfilter/main.py index d5c1db50..8480c9ef 100644 --- a/data/Dockerfiles/netfilter/main.py +++ b/data/Dockerfiles/netfilter/main.py @@ -21,28 +21,6 @@ from modules.IPTables import IPTables from modules.NFTables import NFTables -# connect to redis -while True: - try: - redis_slaveof_ip = os.getenv('REDIS_SLAVEOF_IP', '') - redis_slaveof_port = os.getenv('REDIS_SLAVEOF_PORT', '') - if "".__eq__(redis_slaveof_ip): - r = redis.StrictRedis(host=os.getenv('IPV4_NETWORK', '172.22.1') + '.249', decode_responses=True, port=6379, db=0) - else: - r = redis.StrictRedis(host=redis_slaveof_ip, decode_responses=True, port=redis_slaveof_port, db=0) - r.ping() - except Exception as ex: - print('%s - trying again in 3 seconds' % (ex)) - time.sleep(3) - else: - break -pubsub = r.pubsub() - -# rename fail2ban to netfilter -if r.exists('F2B_LOG'): - r.rename('F2B_LOG', 'NETFILTER_LOG') - - # globals WHITELIST = [] BLACKLIST= [] @@ -50,18 +28,8 @@ bans = {} quit_now = False exit_code = 0 lock = Lock() - - -# init Logger -logger = Logger(r) -# init backend -backend = sys.argv[1] -if backend == "nftables": - logger.logInfo('Using NFTables backend') - tables = NFTables("MAILCOW", logger) -else: - logger.logInfo('Using IPTables backend') - tables = IPTables("MAILCOW", logger) +chain_name = "MAILCOW" +r = None def refreshF2boptions(): @@ -250,9 +218,10 @@ def clear(): with lock: tables.clearIPv4Table() tables.clearIPv6Table() - r.delete('F2B_ACTIVE_BANS') - r.delete('F2B_PERM_BANS') - pubsub.unsubscribe() + if r: + r.delete('F2B_ACTIVE_BANS') + r.delete('F2B_PERM_BANS') + pubsub.unsubscribe() def watch(): logger.logInfo('Watching Redis channel F2B_CHANNEL') @@ -409,15 +378,60 @@ def quit(signum, frame): if __name__ == '__main__': - refreshF2boptions() + # init Logger + logger = Logger(None) + + # init backend + backend = sys.argv[1] + if backend == "nftables": + logger.logInfo('Using NFTables backend') + tables = NFTables(chain_name, logger) + else: + logger.logInfo('Using IPTables backend') + tables = IPTables(chain_name, logger) + # In case a previous session was killed without cleanup clear() + # Reinit MAILCOW chain # Is called before threads start, no locking logger.logInfo("Initializing mailcow netfilter chain") tables.initChainIPv4() tables.initChainIPv6() + if os.getenv("DISABLE_NETFILTER_ISOLATION_RULE").lower() in ("y", "yes"): + logger.logInfo(f"Skipping {chain_name} isolation") + else: + logger.logInfo(f"Setting {chain_name} isolation") + tables.create_mailcow_isolation_rule("br-mailcow", [3306, 6379, 8983, 12345], os.getenv("MAILCOW_REPLICA_IP")) + + # connect to redis + while True: + try: + redis_slaveof_ip = os.getenv('REDIS_SLAVEOF_IP', '') + redis_slaveof_port = os.getenv('REDIS_SLAVEOF_PORT', '') + if "".__eq__(redis_slaveof_ip): + r = redis.StrictRedis(host=os.getenv('IPV4_NETWORK', '172.22.1') + '.249', decode_responses=True, port=6379, db=0) + else: + r = redis.StrictRedis(host=redis_slaveof_ip, decode_responses=True, port=redis_slaveof_port, db=0) + r.ping() + except Exception as ex: + print('%s - trying again in 3 seconds' % (ex)) + time.sleep(3) + else: + break + pubsub = r.pubsub() + Logger.r = r + + # rename fail2ban to netfilter + if r.exists('F2B_LOG'): + r.rename('F2B_LOG', 'NETFILTER_LOG') + # clear bans in redis + r.delete('F2B_ACTIVE_BANS') + r.delete('F2B_PERM_BANS') + + refreshF2boptions() + watch_thread = Thread(target=watch) watch_thread.daemon = True watch_thread.start() diff --git a/data/Dockerfiles/netfilter/modules/IPTables.py b/data/Dockerfiles/netfilter/modules/IPTables.py index c60ecc61..29a9fb65 100644 --- a/data/Dockerfiles/netfilter/modules/IPTables.py +++ b/data/Dockerfiles/netfilter/modules/IPTables.py @@ -1,5 +1,6 @@ import iptc import time +import os class IPTables: def __init__(self, chain_name, logger): @@ -211,3 +212,41 @@ class IPTables: target = rule.create_target("SNAT") target.to_source = snat_target return rule + + def create_mailcow_isolation_rule(self, _interface:str, _dports:list, _allow:str = ""): + try: + chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), self.chain_name) + + # insert mailcow isolation rule + rule = iptc.Rule() + rule.in_interface = f'! {_interface}' + rule.out_interface = _interface + rule.protocol = 'tcp' + rule.create_target("DROP") + match = rule.create_match("multiport") + match.dports = ','.join(map(str, _dports)) + + if rule in chain.rules: + chain.delete_rule(rule) + chain.insert_rule(rule, position=0) + + # insert mailcow isolation exception rule + if _allow != "": + rule = iptc.Rule() + rule.src = _allow + rule.in_interface = f'! {_interface}' + rule.out_interface = _interface + rule.protocol = 'tcp' + rule.create_target("ACCEPT") + match = rule.create_match("multiport") + match.dports = ','.join(map(str, _dports)) + + if rule in chain.rules: + chain.delete_rule(rule) + chain.insert_rule(rule, position=0) + + + return True + except Exception as e: + self.logger.logCrit(f"Error adding {self.chain_name} isolation: {e}") + return False \ No newline at end of file diff --git a/data/Dockerfiles/netfilter/modules/Logger.py b/data/Dockerfiles/netfilter/modules/Logger.py index d60d52fa..2a40de0c 100644 --- a/data/Dockerfiles/netfilter/modules/Logger.py +++ b/data/Dockerfiles/netfilter/modules/Logger.py @@ -10,7 +10,8 @@ class Logger: tolog['time'] = int(round(time.time())) tolog['priority'] = priority tolog['message'] = message - self.r.lpush('NETFILTER_LOG', json.dumps(tolog, ensure_ascii=False)) + if self.r: + self.r.lpush('NETFILTER_LOG', json.dumps(tolog, ensure_ascii=False)) print(message) def logWarn(self, message): diff --git a/data/Dockerfiles/netfilter/modules/NFTables.py b/data/Dockerfiles/netfilter/modules/NFTables.py index d341dc36..e8e02c47 100644 --- a/data/Dockerfiles/netfilter/modules/NFTables.py +++ b/data/Dockerfiles/netfilter/modules/NFTables.py @@ -1,5 +1,6 @@ import nftables import ipaddress +import os class NFTables: def __init__(self, chain_name, logger): @@ -266,6 +267,17 @@ class NFTables: return self.nft_exec_dict(delete_command) + def delete_filter_rule(self, _family:str, _chain: str, _handle:str): + delete_command = self.get_base_dict() + _rule_opts = {'family': _family, + 'table': 'filter', + 'chain': _chain, + 'handle': _handle } + _delete = {'delete': {'rule': _rule_opts} } + delete_command["nftables"].append(_delete) + + return self.nft_exec_dict(delete_command) + def snat_rule(self, _family: str, snat_target: str, source_address: str): chain_name = self.nft_chain_names[_family]['nat']['postrouting'] @@ -381,7 +393,7 @@ class NFTables: break return chain_handle - def get_rules_handle(self, _family: str, _table: str, chain_name: str): + def get_rules_handle(self, _family: str, _table: str, chain_name: str, _comment_filter = "mailcow"): rule_handle = [] # Command: 'nft list chain {family} {table} {chain_name}' _chain_opts = {'family': _family, 'table': _table, 'name': chain_name} @@ -397,7 +409,7 @@ class NFTables: rule = _object["rule"] if rule["family"] == _family and rule["table"] == _table and rule["chain"] == chain_name: - if rule.get("comment") and rule["comment"] == "mailcow": + if rule.get("comment") and rule["comment"] == _comment_filter: rule_handle.append(rule["handle"]) return rule_handle @@ -493,3 +505,152 @@ class NFTables: position+=1 return position if rule_found else False + + def create_mailcow_isolation_rule(self, _interface:str, _dports:list, _allow:str = ""): + family = "ip" + table = "filter" + comment_filter_drop = "mailcow isolation" + comment_filter_allow = "mailcow isolation allow" + json_command = self.get_base_dict() + + # Delete old mailcow isolation rules + handles = self.get_rules_handle(family, table, self.chain_name, comment_filter_drop) + for handle in handles: + self.delete_filter_rule(family, self.chain_name, handle) + handles = self.get_rules_handle(family, table, self.chain_name, comment_filter_allow) + for handle in handles: + self.delete_filter_rule(family, self.chain_name, handle) + + # insert mailcow isolation rule + _match_dict_drop = [ + { + "match": { + "op": "!=", + "left": { + "meta": { + "key": "iifname" + } + }, + "right": _interface + } + }, + { + "match": { + "op": "==", + "left": { + "meta": { + "key": "oifname" + } + }, + "right": _interface + } + }, + { + "match": { + "op": "==", + "left": { + "payload": { + "protocol": "tcp", + "field": "dport" + } + }, + "right": { + "set": _dports + } + } + }, + { + "counter": { + "packets": 0, + "bytes": 0 + } + }, + { + "drop": None + } + ] + rule_drop = { "insert": { "rule": { + "family": family, + "table": table, + "chain": self.chain_name, + "comment": comment_filter_drop, + "expr": _match_dict_drop + }}} + json_command["nftables"].append(rule_drop) + + # insert mailcow isolation allow rule + if _allow != "": + _match_dict_allow = [ + { + "match": { + "op": "==", + "left": { + "payload": { + "protocol": "ip", + "field": "saddr" + } + }, + "right": _allow + } + }, + { + "match": { + "op": "!=", + "left": { + "meta": { + "key": "iifname" + } + }, + "right": _interface + } + }, + { + "match": { + "op": "==", + "left": { + "meta": { + "key": "oifname" + } + }, + "right": _interface + } + }, + { + "match": { + "op": "==", + "left": { + "payload": { + "protocol": "tcp", + "field": "dport" + } + }, + "right": { + "set": _dports + } + } + }, + { + "counter": { + "packets": 0, + "bytes": 0 + } + }, + { + "accept": None + } + ] + rule_allow = { "insert": { "rule": { + "family": family, + "table": table, + "chain": self.chain_name, + "comment": comment_filter_allow, + "expr": _match_dict_allow + }}} + json_command["nftables"].append(rule_allow) + + success = self.nft_exec_dict(json_command) + if success == False: + self.logger.logCrit(f"Error adding {self.chain_name} isolation") + return False + + return True \ No newline at end of file diff --git a/data/conf/dovecot/dovecot.conf b/data/conf/dovecot/dovecot.conf index 159e39f4..729686fb 100644 --- a/data/conf/dovecot/dovecot.conf +++ b/data/conf/dovecot/dovecot.conf @@ -247,6 +247,9 @@ plugin { mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename mail_log_fields = uid box msgid size mail_log_cached_only = yes + + # Try set mail_replica + !include_try /etc/dovecot/mail_replica.conf } service quota-warning { executable = script /usr/local/bin/quota_notify.py diff --git a/docker-compose.yml b/docker-compose.yml index c1883f90..fa92546a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,6 +21,7 @@ services: image: mariadb:10.5 depends_on: - unbound-mailcow + - netfilter-mailcow stop_grace_period: 45s volumes: - mysql-vol-1:/var/lib/mysql/ @@ -46,6 +47,8 @@ services: volumes: - redis-vol-1:/data/ restart: always + depends_on: + - netfilter-mailcow ports: - "${REDIS_PORT:-127.0.0.1:7654}:6379" environment: @@ -222,6 +225,7 @@ services: image: mailcow/dovecot:1.27 depends_on: - mysql-mailcow + - netfilter-mailcow dns: - ${IPV4_NETWORK:-172.22.1}.254 cap_add: @@ -242,6 +246,8 @@ services: environment: - DOVECOT_MASTER_USER=${DOVECOT_MASTER_USER:-} - DOVECOT_MASTER_PASS=${DOVECOT_MASTER_PASS:-} + - MAILCOW_REPLICA_IP=${MAILCOW_REPLICA_IP:-} + - DOVEADM_REPLICA_PORT=${DOVEADM_REPLICA_PORT:-} - LOG_LINES=${LOG_LINES:-9999} - DBNAME=${DBNAME} - DBUSER=${DBUSER} @@ -437,12 +443,6 @@ services: netfilter-mailcow: image: mailcow/netfilter:1.55 stop_grace_period: 30s - depends_on: - - dovecot-mailcow - - postfix-mailcow - - sogo-mailcow - - php-fpm-mailcow - - redis-mailcow restart: always privileged: true environment: @@ -453,6 +453,8 @@ services: - SNAT6_TO_SOURCE=${SNAT6_TO_SOURCE:-n} - REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-} - REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-} + - MAILCOW_REPLICA_IP=${MAILCOW_REPLICA_IP:-} + - DISABLE_NETFILTER_ISOLATION_RULE=${DISABLE_NETFILTER_ISOLATION_RULE:-n} network_mode: "host" volumes: - /lib/modules:/lib/modules:ro @@ -553,6 +555,8 @@ services: solr-mailcow: image: mailcow/solr:1.8.2 restart: always + depends_on: + - netfilter-mailcow volumes: - solr-vol-1:/opt/solr/server/solr/dovecot-fts/data ports: diff --git a/generate_config.sh b/generate_config.sh index e62d1689..05d9ee2f 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -494,6 +494,9 @@ WEBAUTHN_ONLY_TRUSTED_VENDORS=n # Otherwise it will work normally. SPAMHAUS_DQS_KEY= +# Prevent netfilter from setting an iptables/nftables rule to isolate the mailcow docker network - y/n +# CAUTION: Disabling this may expose container ports to other neighbors on the same subnet, even if the ports are bound to localhost +DISABLE_NETFILTER_ISOLATION_RULE=n EOF mkdir -p data/assets/ssl diff --git a/update.sh b/update.sh index 5df32e00..f1e31652 100755 --- a/update.sh +++ b/update.sh @@ -481,6 +481,7 @@ CONFIG_ARRAY=( "WEBAUTHN_ONLY_TRUSTED_VENDORS" "SPAMHAUS_DQS_KEY" "SKIP_UNBOUND_HEALTHCHECK" + "DISABLE_NETFILTER_ISOLATION_RULE" ) detect_bad_asn @@ -754,6 +755,13 @@ for option in ${CONFIG_ARRAY[@]}; do echo '# Skip Unbound (DNS Resolver) Healthchecks (NOT Recommended!) - y/n' >> mailcow.conf echo 'SKIP_UNBOUND_HEALTHCHECK=n' >> mailcow.conf fi + elif [[ ${option} == "DISABLE_NETFILTER_ISOLATION_RULE" ]]; then + if ! grep -q ${option} mailcow.conf; then + echo "Adding new option \"${option}\" to mailcow.conf" + echo '# Prevent netfilter from setting an iptables/nftables rule to isolate the mailcow docker network - y/n' >> mailcow.conf + echo '# CAUTION: Disabling this may expose container ports to other neighbors on the same subnet, even if the ports are bound to localhost' >> mailcow.conf + echo 'DISABLE_NETFILTER_ISOLATION_RULE=n' >> mailcow.conf + fi elif ! grep -q ${option} mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo "${option}=n" >> mailcow.conf From 2072301d89683cdbe9a398150b199630d1109d81 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Fri, 2 Feb 2024 11:08:44 +0100 Subject: [PATCH 2/5] [Netfilter] only perform cleanup at exit if SIGTERM was recieved --- data/Dockerfiles/netfilter/main.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/data/Dockerfiles/netfilter/main.py b/data/Dockerfiles/netfilter/main.py index 8480c9ef..7f8dd9fb 100644 --- a/data/Dockerfiles/netfilter/main.py +++ b/data/Dockerfiles/netfilter/main.py @@ -376,6 +376,11 @@ def quit(signum, frame): global quit_now quit_now = True +def quit_clear(signum, frame): + global exit_code + clear() + sys.exit(exit_code) + if __name__ == '__main__': # init Logger @@ -474,8 +479,7 @@ if __name__ == '__main__': whitelistupdate_thread.daemon = True whitelistupdate_thread.start() - signal.signal(signal.SIGTERM, quit) - atexit.register(clear) + signal.signal(signal.SIGTERM, quit_clear) while not quit_now: time.sleep(0.5) From 2e57325dde15062fbecdf5ca49e29072f70a4814 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Fri, 2 Feb 2024 11:27:46 +0100 Subject: [PATCH 3/5] docker-compose.yml: Bump dovecot + netfilter version --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index fa92546a..31923d46 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -222,7 +222,7 @@ services: - sogo dovecot-mailcow: - image: mailcow/dovecot:1.27 + image: mailcow/dovecot:1.28 depends_on: - mysql-mailcow - netfilter-mailcow @@ -441,7 +441,7 @@ services: - acme netfilter-mailcow: - image: mailcow/netfilter:1.55 + image: mailcow/netfilter:1.56 stop_grace_period: 30s restart: always privileged: true From 39589bd441291c7068f6642782be6edff0bcb371 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Fri, 2 Feb 2024 12:46:50 +0100 Subject: [PATCH 4/5] [Netfilter] only perform cleanup at exit if SIGTERM was recieved --- data/Dockerfiles/netfilter/main.py | 37 +++++++++++++++++++----------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/data/Dockerfiles/netfilter/main.py b/data/Dockerfiles/netfilter/main.py index 7f8dd9fb..c3b19c4e 100644 --- a/data/Dockerfiles/netfilter/main.py +++ b/data/Dockerfiles/netfilter/main.py @@ -30,6 +30,8 @@ exit_code = 0 lock = Lock() chain_name = "MAILCOW" r = None +pubsub = None +clear_before_quit = False def refreshF2boptions(): @@ -218,10 +220,12 @@ def clear(): with lock: tables.clearIPv4Table() tables.clearIPv6Table() - if r: - r.delete('F2B_ACTIVE_BANS') - r.delete('F2B_PERM_BANS') - pubsub.unsubscribe() + try: + if r is not None: + r.delete('F2B_ACTIVE_BANS') + r.delete('F2B_PERM_BANS') + except Exception as ex: + logger.logWarn('Error clearing redis keys F2B_ACTIVE_BANS and F2B_PERM_BANS: %s' % ex) def watch(): logger.logInfo('Watching Redis channel F2B_CHANNEL') @@ -229,6 +233,7 @@ def watch(): global quit_now global exit_code + global pubsub while not quit_now: try: @@ -249,6 +254,7 @@ def watch(): ban(addr) except Exception as ex: logger.logWarn('Error reading log line from pubsub: %s' % ex) + pubsub = None quit_now = True exit_code = 2 @@ -372,17 +378,22 @@ def blacklistUpdate(): permBan(net=net, unban=True) time.sleep(60.0 - ((time.time() - start_time) % 60.0)) -def quit(signum, frame): - global quit_now - quit_now = True - -def quit_clear(signum, frame): - global exit_code - clear() +def sigterm_quit(signum, frame): + global clear_before_quit + clear_before_quit = True sys.exit(exit_code) +def berfore_quit(): + if clear_before_quit: + clear() + if pubsub is not None: + pubsub.unsubscribe() + if __name__ == '__main__': + atexit.register(berfore_quit) + signal.signal(signal.SIGTERM, sigterm_quit) + # init Logger logger = Logger(None) @@ -420,12 +431,12 @@ if __name__ == '__main__': else: r = redis.StrictRedis(host=redis_slaveof_ip, decode_responses=True, port=redis_slaveof_port, db=0) r.ping() + pubsub = r.pubsub() except Exception as ex: print('%s - trying again in 3 seconds' % (ex)) time.sleep(3) else: break - pubsub = r.pubsub() Logger.r = r # rename fail2ban to netfilter @@ -479,8 +490,6 @@ if __name__ == '__main__': whitelistupdate_thread.daemon = True whitelistupdate_thread.start() - signal.signal(signal.SIGTERM, quit_clear) - while not quit_now: time.sleep(0.5) From c941e802d4177a7d8278f3a80359d833d9770bec Mon Sep 17 00:00:00 2001 From: FreddleSpl0it Date: Fri, 2 Feb 2024 12:57:21 +0100 Subject: [PATCH 5/5] [Netfilter] only perform cleanup at exit if SIGTERM was recieved --- data/Dockerfiles/netfilter/main.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/Dockerfiles/netfilter/main.py b/data/Dockerfiles/netfilter/main.py index c3b19c4e..f4acd461 100644 --- a/data/Dockerfiles/netfilter/main.py +++ b/data/Dockerfiles/netfilter/main.py @@ -228,12 +228,12 @@ def clear(): logger.logWarn('Error clearing redis keys F2B_ACTIVE_BANS and F2B_PERM_BANS: %s' % ex) def watch(): - logger.logInfo('Watching Redis channel F2B_CHANNEL') - pubsub.subscribe('F2B_CHANNEL') - + global pubsub global quit_now global exit_code - global pubsub + + logger.logInfo('Watching Redis channel F2B_CHANNEL') + pubsub.subscribe('F2B_CHANNEL') while not quit_now: try: