From 768ad2c8e1feed87581371d01ec3410c5de5fc03 Mon Sep 17 00:00:00 2001 From: Spitap Date: Thu, 9 Feb 2023 14:07:10 +0100 Subject: [PATCH 1/3] Added postfix and dovecot for f2b --- modoboa_installer/config_dict_template.py | 8 ++ modoboa_installer/scripts/fail2ban.py | 10 +++ .../filter.d/dovecot-modoboa.conf.tpl | 51 ++++++++++++ .../filter.d/postfix-modoboa.conf.tpl | 81 +++++++++++++++++++ .../files/fail2ban/jail.d/dovecot.conf.tpl | 9 +++ .../files/fail2ban/jail.d/modoboa.conf.tpl | 2 +- .../files/fail2ban/jail.d/postfix.conf.tpl | 9 +++ 7 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 modoboa_installer/scripts/files/fail2ban/filter.d/dovecot-modoboa.conf.tpl create mode 100644 modoboa_installer/scripts/files/fail2ban/filter.d/postfix-modoboa.conf.tpl create mode 100644 modoboa_installer/scripts/files/fail2ban/jail.d/dovecot.conf.tpl create mode 100644 modoboa_installer/scripts/files/fail2ban/jail.d/postfix.conf.tpl diff --git a/modoboa_installer/config_dict_template.py b/modoboa_installer/config_dict_template.py index 73256d6d..ce975c48 100644 --- a/modoboa_installer/config_dict_template.py +++ b/modoboa_installer/config_dict_template.py @@ -141,6 +141,14 @@ def is_email(user_input): "option": "find_time", "default": "30" }, + { + "option": "ports_blocked", + "default": "http,https,pop3,pop3s,imap,imaps,587" + }, + { + "option": "postfix_dovecot_filter", + "default": True + } ] }, { diff --git a/modoboa_installer/scripts/fail2ban.py b/modoboa_installer/scripts/fail2ban.py index 7faa9172..9d5d023d 100644 --- a/modoboa_installer/scripts/fail2ban.py +++ b/modoboa_installer/scripts/fail2ban.py @@ -15,3 +15,13 @@ class Fail2ban(base.Installer): "jail.d/modoboa.conf", "filter.d/modoboa-auth.conf", ] + + def get_config_files(self): + config_files = super().get_config_files() + + if self.app_config["postfix_dovecot_filter"]: + config_files += ["jail.d/postfix.conf", + "jail.d/dovecot.conf", + "filter.d/postfix-modoboa.conf", + "filter.d/dovecot-modoboa.conf"] + return config_files diff --git a/modoboa_installer/scripts/files/fail2ban/filter.d/dovecot-modoboa.conf.tpl b/modoboa_installer/scripts/files/fail2ban/filter.d/dovecot-modoboa.conf.tpl new file mode 100644 index 00000000..6704e6d6 --- /dev/null +++ b/modoboa_installer/scripts/files/fail2ban/filter.d/dovecot-modoboa.conf.tpl @@ -0,0 +1,51 @@ +# Fail2Ban filter Dovecot authentication and pop3/imap server +# +# Author: Martin Waschbuesch +# Daniel Black (rewrote with begin and end anchors) +# Martin O'Neal (added LDAP authentication failure regex) +# Sergey G. Brester aka sebres (reviewed, optimized, IPv6-compatibility) + +[INCLUDES] + +before = common.conf + +[Definition] + +_auth_worker = (?:dovecot: )?auth(?:-worker)? +_daemon = (?:dovecot(?:-auth)?|auth) + +prefregex = ^%(__prefix_line)s(?:%(_auth_worker)s(?:\([^\)]+\))?: )?(?:%(__pam_auth)s(?:\(dovecot:auth\))?: |(?:pop3|imap|managesieve|submission)-login: )?(?:Info: )?.+$ + +failregex = ^authentication failure; logname=\S* uid=\S* euid=\S* tty=dovecot ruser=\S* rhost=(?:\s+user=\S*)?\s*$ + ^(?:Aborted login|Disconnected|Remote closed connection|Client has quit the connection)(?::(?: [^ \(]+)+)? \((?:auth failed, \d+ attempts(?: in \d+ secs)?|tried to use (?:disabled|disallowed) \S+ auth|proxy dest auth failed)\):(?: user=<[^>]*>,)?(?: method=\S+,)? rip=(?:[^>]*(?:, session=<\S+>)?)\s*$ + ^pam\(\S+,(?:,\S*)?\): pam_authenticate\(\) failed: (?:User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \(password mismatch\?\)|Permission denied)\s*$ + ^[a-z\-]{3,15}\(\S*,(?:,\S*)?\): (?:unknown user|invalid credentials|Password mismatch) + > + +mdre-aggressive = ^(?:Aborted login|Disconnected|Remote closed connection|Client has quit the connection)(?::(?: [^ \(]+)+)? \((?:no auth attempts|disconnected before auth was ready,|client didn't finish \S+ auth,)(?: (?:in|waited) \d+ secs)?\):(?: user=<[^>]*>,)?(?: method=\S+,)? rip=(?:[^>]*(?:, session=<\S+>)?)\s*$ + +mdre-normal = + +# Parameter `mode` - `normal` or `aggressive`. +# Aggressive mode can be used to match log-entries like: +# 'no auth attempts', 'disconnected before auth was ready', 'client didn't finish SASL auth'. +# Note it may produce lots of false positives on misconfigured MTAs. +# Ex.: +# filter = dovecot[mode=aggressive] +mode = normal + +ignoreregex = + +journalmatch = _SYSTEMD_UNIT=dovecot.service + +datepattern = {^LN-BEG}TAI64N + {^LN-BEG} + +# DEV Notes: +# * the first regex is essentially a copy of pam-generic.conf +# * Probably doesn't do dovecot sql/ldap backends properly (resolved in edit 21/03/2016) +# +# Author: Martin Waschbuesch +# Daniel Black (rewrote with begin and end anchors) +# Martin O'Neal (added LDAP authentication failure regex) +# Sergey G. Brester aka sebres (reviewed, optimized, IPv6-compatibility) diff --git a/modoboa_installer/scripts/files/fail2ban/filter.d/postfix-modoboa.conf.tpl b/modoboa_installer/scripts/files/fail2ban/filter.d/postfix-modoboa.conf.tpl new file mode 100644 index 00000000..b746b87e --- /dev/null +++ b/modoboa_installer/scripts/files/fail2ban/filter.d/postfix-modoboa.conf.tpl @@ -0,0 +1,81 @@ +# Fail2Ban filter for selected Postfix SMTP rejections +# +# +# Author: Cyril Jaquier + +[INCLUDES] + +# Read common prefixes. If any customizations available -- read them from +# common.local +before = common.conf + +[Definition] + +_daemon = postfix(-\w+)?/\w+(?:/smtp[ds])? +_port = (?::\d+)? + +prefregex = ^%(__prefix_line)s> .+$ + +mdpr-normal = (?:\w+: reject:|(?:improper command pipelining|too many errors) after \S+) +mdre-normal=^RCPT from [^[]*\[\]%(_port)s: 55[04] 5\.7\.1\s + ^RCPT from [^[]*\[\]%(_port)s: 45[04] 4\.7\.\d+ (?:Service unavailable\b|Client host rejected: cannot find your (reverse )?hostname\b) + ^RCPT from [^[]*\[\]%(_port)s: 450 4\.7\.\d+ (<[^>]*>)?: Helo command rejected: Host not found\b + ^EHLO from [^[]*\[\]%(_port)s: 504 5\.5\.\d+ (<[^>]*>)?: Helo command rejected: need fully-qualified hostname\b + ^(RCPT|VRFY) from [^[]*\[\]%(_port)s: 550 5\.1\.1\s + ^RCPT from [^[]*\[\]%(_port)s: 450 4\.1\.\d+ (<[^>]*>)?: Sender address rejected: Domain not found\b + ^from [^[]*\[\]%(_port)s:? + +mdpr-auth = warning: +mdre-auth = ^[^[]*\[\]%(_port)s: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server| Invalid authentication mechanism) +mdre-auth2= ^[^[]*\[\]%(_port)s: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server) +# todo: check/remove "Invalid authentication mechanism" from ignore list, if gh-1243 will get finished (see gh-1297). + +# Mode "rbl" currently included in mode "normal", but if needed for jail "postfix-rbl" only: +mdpr-rbl = %(mdpr-normal)s +mdre-rbl = ^RCPT from [^[]*\[\]%(_port)s: [45]54 [45]\.7\.1 Service unavailable; Client host \[\S+\] blocked\b + +# Mode "rbl" currently included in mode "normal" (within 1st rule) +mdpr-more = %(mdpr-normal)s +mdre-more = %(mdre-normal)s + +mdpr-ddos = (?:lost connection after(?! DATA) [A-Z]+|disconnect(?= from \S+(?: \S+=\d+)* auth=0/(?:[1-9]|\d\d+))) +mdre-ddos = ^from [^[]*\[\]%(_port)s:? + +mdpr-extra = (?:%(mdpr-auth)s|%(mdpr-normal)s) +mdre-extra = %(mdre-auth)s + %(mdre-normal)s + +mdpr-aggressive = (?:%(mdpr-auth)s|%(mdpr-normal)s|%(mdpr-ddos)s) +mdre-aggressive = %(mdre-auth2)s + %(mdre-normal)s + +mdpr-errors = too many errors after \S+ +mdre-errors = ^from [^[]*\[\]%(_port)s$ + + +failregex = > + +# Parameter "mode": more (default combines normal and rbl), auth, normal, rbl, ddos, extra or aggressive (combines all) +# Usage example (for jail.local): +# [postfix] +# mode = aggressive +# +# # or another jail (rewrite filter parameters of jail): +# [postfix-rbl] +# filter = postfix[mode=rbl] +# +# # jail to match "too many errors", related postconf `smtpd_hard_error_limit`: +# # (normally included in other modes (normal, more, extra, aggressive), but this jail'd allow to ban on the first message) +# [postfix-many-errors] +# filter = postfix[mode=errors] +# maxretry = 1 +# +mode = more + +ignoreregex = + +[Init] + +journalmatch = _SYSTEMD_UNIT=postfix.service + +# Author: Cyril Jaquier \ No newline at end of file diff --git a/modoboa_installer/scripts/files/fail2ban/jail.d/dovecot.conf.tpl b/modoboa_installer/scripts/files/fail2ban/jail.d/dovecot.conf.tpl new file mode 100644 index 00000000..9adb6e3c --- /dev/null +++ b/modoboa_installer/scripts/files/fail2ban/jail.d/dovecot.conf.tpl @@ -0,0 +1,9 @@ +[dovecot] +enabled = true +port = %ports_blocked +filter = dovecot +logpath = /var/log/mail.log +maxretry = %max_retry +bantime = %ban_time +findtime = %find_time +ignoreip = ::1 127.0.01/8 diff --git a/modoboa_installer/scripts/files/fail2ban/jail.d/modoboa.conf.tpl b/modoboa_installer/scripts/files/fail2ban/jail.d/modoboa.conf.tpl index 4b265b6c..2a09f6b1 100644 --- a/modoboa_installer/scripts/files/fail2ban/jail.d/modoboa.conf.tpl +++ b/modoboa_installer/scripts/files/fail2ban/jail.d/modoboa.conf.tpl @@ -1,6 +1,6 @@ [modoboa] enabled = true -port = http,https +port = %ports_blocked protocol = tcp filter = modoboa-auth maxretry = %max_retry diff --git a/modoboa_installer/scripts/files/fail2ban/jail.d/postfix.conf.tpl b/modoboa_installer/scripts/files/fail2ban/jail.d/postfix.conf.tpl new file mode 100644 index 00000000..2f00339a --- /dev/null +++ b/modoboa_installer/scripts/files/fail2ban/jail.d/postfix.conf.tpl @@ -0,0 +1,9 @@ +[postfix] +enabled = true +port = %ports_blocked +maxretry = %max_retry +bantime = %ban_time +findtime = %find_time +filter = postfix[mode=aggressive] +logpath = /var/log/mail.log +ignoreip = ::1 127.0.0.1/8 From 4269c38e63492a0c9ae657b15d1b45b1be3ba15a Mon Sep 17 00:00:00 2001 From: Spitap Date: Thu, 9 Feb 2023 14:13:01 +0100 Subject: [PATCH 2/3] fix string issue --- modoboa_installer/config_dict_template.py | 2 +- modoboa_installer/scripts/fail2ban.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modoboa_installer/config_dict_template.py b/modoboa_installer/config_dict_template.py index ce975c48..f7672332 100644 --- a/modoboa_installer/config_dict_template.py +++ b/modoboa_installer/config_dict_template.py @@ -147,7 +147,7 @@ def is_email(user_input): }, { "option": "postfix_dovecot_filter", - "default": True + "default": "true" } ] }, diff --git a/modoboa_installer/scripts/fail2ban.py b/modoboa_installer/scripts/fail2ban.py index 9d5d023d..9d0e804e 100644 --- a/modoboa_installer/scripts/fail2ban.py +++ b/modoboa_installer/scripts/fail2ban.py @@ -19,7 +19,7 @@ class Fail2ban(base.Installer): def get_config_files(self): config_files = super().get_config_files() - if self.app_config["postfix_dovecot_filter"]: + if self.app_config["postfix_dovecot_filter"].lower() == "true": config_files += ["jail.d/postfix.conf", "jail.d/dovecot.conf", "filter.d/postfix-modoboa.conf", From 3113eafb98e3bea125d013e1c2ff2347ff9a6d49 Mon Sep 17 00:00:00 2001 From: Spitap Date: Fri, 10 Feb 2023 15:18:01 +0100 Subject: [PATCH 3/3] Fix configuration file limiter --- modoboa_installer/scripts/fail2ban.py | 20 ++++++++++++++++--- ...-modoboa.conf.tpl => dovecot-modoboa.conf} | 0 ...-modoboa.conf.tpl => postfix-modoboa.conf} | 0 3 files changed, 17 insertions(+), 3 deletions(-) rename modoboa_installer/scripts/files/fail2ban/filter.d/{dovecot-modoboa.conf.tpl => dovecot-modoboa.conf} (100%) rename modoboa_installer/scripts/files/fail2ban/filter.d/{postfix-modoboa.conf.tpl => postfix-modoboa.conf} (100%) diff --git a/modoboa_installer/scripts/fail2ban.py b/modoboa_installer/scripts/fail2ban.py index 9d0e804e..73bdf59e 100644 --- a/modoboa_installer/scripts/fail2ban.py +++ b/modoboa_installer/scripts/fail2ban.py @@ -1,6 +1,9 @@ """fail2ban related functions.""" +import os + from . import base +from .. import utils class Fail2ban(base.Installer): @@ -17,11 +20,22 @@ class Fail2ban(base.Installer): ] def get_config_files(self): + """Add dovecot and postfix jails if enabled.""" + config_files = super().get_config_files() if self.app_config["postfix_dovecot_filter"].lower() == "true": config_files += ["jail.d/postfix.conf", - "jail.d/dovecot.conf", - "filter.d/postfix-modoboa.conf", - "filter.d/dovecot-modoboa.conf"] + "jail.d/dovecot.conf"] return config_files + + def install_config_files(self): + """Installer postfix and dovecot filters if enabled.""" + + if self.app_config["postfix_dovecot_filter"].lower() == "true": + for config_file in ["filter.d/postfix-modoboa.conf", + "filter.d/dovecot-modoboa.conf"]: + src = self.get_file_path(config_file) + dst = os.path.join(self.config_dir, config_file) + utils.copy_file(src, dst) + super().install_config_files() diff --git a/modoboa_installer/scripts/files/fail2ban/filter.d/dovecot-modoboa.conf.tpl b/modoboa_installer/scripts/files/fail2ban/filter.d/dovecot-modoboa.conf similarity index 100% rename from modoboa_installer/scripts/files/fail2ban/filter.d/dovecot-modoboa.conf.tpl rename to modoboa_installer/scripts/files/fail2ban/filter.d/dovecot-modoboa.conf diff --git a/modoboa_installer/scripts/files/fail2ban/filter.d/postfix-modoboa.conf.tpl b/modoboa_installer/scripts/files/fail2ban/filter.d/postfix-modoboa.conf similarity index 100% rename from modoboa_installer/scripts/files/fail2ban/filter.d/postfix-modoboa.conf.tpl rename to modoboa_installer/scripts/files/fail2ban/filter.d/postfix-modoboa.conf