diff --git a/data/Dockerfiles/netfilter/server.py b/data/Dockerfiles/netfilter/server.py index 90a055be..0bf9dc19 100644 --- a/data/Dockerfiles/netfilter/server.py +++ b/data/Dockerfiles/netfilter/server.py @@ -33,16 +33,6 @@ while True: pubsub = r.pubsub() -RULES = {} -RULES[1] = 'warning: .*\[([0-9a-f\.:]+)\]: SASL .+ authentication failed' -RULES[2] = '-login: Disconnected \(auth failed, .+\): user=.*, method=.+, rip=([0-9a-f\.:]+),' -RULES[3] = '-login: Aborted login \(tried to use disallowed .+\): user=.+, rip=([0-9a-f\.:]+), lip.+' -RULES[4] = 'SOGo.+ Login from \'([0-9a-f\.:]+)\' for user .+ might not have worked' -RULES[5] = 'mailcow UI: Invalid password for .+ by ([0-9a-f\.:]+)' -RULES[6] = '([0-9a-f\.:]+) \"GET \/SOGo\/.* HTTP.+\" 403 .+' -RULES[7] = 'Rspamd UI: Invalid password by ([0-9a-f\.:]+)' -RULES[8] = '-login: Aborted login \(auth failed .+\): user=.+, rip=([0-9a-f\.:]+), lip.+' - WHITELIST = [] BLACKLIST= [] @@ -92,6 +82,28 @@ def refreshF2boptions(): print('Error loading F2B options: F2B_OPTIONS is not json') quit_now = True +def refreshF2bregex(): + global f2bregex + global quit_now + if not r.get('F2B_REGEX'): + f2bregex = {} + f2bregex[1] = 'warning: .*\[([0-9a-f\.:]+)\]: SASL .+ authentication failed' + f2bregex[2] = '-login: Disconnected \(auth failed, .+\): user=.*, method=.+, rip=([0-9a-f\.:]+),' + f2bregex[3] = '-login: Aborted login \(tried to use disallowed .+\): user=.+, rip=([0-9a-f\.:]+), lip.+' + f2bregex[4] = 'SOGo.+ Login from \'([0-9a-f\.:]+)\' for user .+ might not have worked' + f2bregex[5] = 'mailcow UI: Invalid password for .+ by ([0-9a-f\.:]+)' + f2bregex[6] = '([0-9a-f\.:]+) \"GET \/SOGo\/.* HTTP.+\" 403 .+' + f2bregex[7] = 'Rspamd UI: Invalid password by ([0-9a-f\.:]+)' + f2bregex[8] = '-login: Aborted login \(auth failed .+\): user=.+, rip=([0-9a-f\.:]+), lip.+' + r.set('F2B_REGEX', json.dumps(f2bregex, ensure_ascii=False)) + else: + try: + f2bregex = {} + f2bregex = json.loads(r.get('F2B_REGEX')) + except ValueError: + print('Error loading F2B options: F2B_REGEX is not json') + quit_now = True + if r.exists('F2B_LOG'): r.rename('F2B_LOG', 'NETFILTER_LOG') @@ -290,7 +302,8 @@ def watch(): while not quit_now: for item in pubsub.listen(): - for rule_id, rule_regex in RULES.items(): + refreshF2bregex() + for rule_id, rule_regex in f2bregex.items(): if item['data'] and item['type'] == 'message': result = re.search(rule_regex, item['data']) if result: @@ -298,7 +311,7 @@ def watch(): ip = ipaddress.ip_address(addr) if ip.is_private or ip.is_loopback: continue - logWarn('%s matched rule id %d (%s)' % (addr, rule_id, item['data'])) + logWarn('%s matched rule id %s (%s)' % (addr, rule_id, item['data'])) ban(addr) def snat4(snat_target): @@ -322,7 +335,7 @@ def snat4(snat_target): chain = iptc.Chain(table, 'POSTROUTING') table.autocommit = False if get_snat4_rule() not in chain.rules: - logCrit('Added POSTROUTING rule for source network %s to SNAT target %s' % (get_snat4_rule().src, snat_target)) + logCrit('Added POSTROUTING rule for source network %s to SNAT target %s' % (get_snat4_rule().src, snat_target)) chain.insert_rule(get_snat4_rule()) table.commit() else: