Fail2ban does not process messages with unsuccessful ssh rsa authentication.
Log file example:
sshd[5754]: Unable to negotiate with <HOST> port 1401: no matching key exchange method found. Their offer: diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,rsa2048-sha256,rsa1024-sha1 [preauth]
sshd[5778]: Unable to negotiate with <HOST> port 37576: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1 [preauth]
fail2ban-client -d | grep sshd
['add', 'sshd-auth', 'polling']
['set', 'sshd-auth', 'maxlines', 1]
['set', 'sshd-auth', 'prefregex', '^<F-MLFID>(?:\\[\\])?\\s*(?:<[^.]+\\.[^.]+>\\s+)?(?:\\S+\\s+)?(?:kernel:\\s?\\[ *\\d+\\.\\d+\\]:?\\s+)?(?:@vserver_\\S+\\s+)?(?:(?:(?:\\[\\d+\\])?:\\s+[\\[\\(]?sshd(?:\\(\\S+\\))?[\\]\\)]?:?|[\\[\\(]?sshd(?:\\(\\S+\\))?[\\]\\)]?:?(?:\\[\\d+\\])?:?)\\s+)?(?:\\[ID \\d+ \\S+\\]\\s+)?</F-MLFID>(?:(?:error|fatal): (?:PAM: )?)?<F-CONTENT>.+</F-CONTENT>$']
['set', 'sshd-auth', 'datepattern', '{^LN-BEG}']
['multi-set', 'sshd-auth', 'addfailregex', ['^[aA]uthentication (?:failure|error|failed) for <F-USER>.*</F-USER> from <HOST>( via \\S+)?(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$', '^User not known to the underlying authentication module for <F-USER>.*</F-USER> from <HOST>(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$', '^Failed publickey for invalid user <F-USER>(?P<cond_user>\\S+)|(?:(?! from ).)*?</F-USER> from <HOST>(?: (?:port \\d+|on \\S+)){0,2}(?: ssh\\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)', '^Failed \\b(?!publickey)\\S+ for (?P<cond_inv>invalid user )?<F-USER>(?P<cond_user>\\S+)|(?(cond_inv)(?:(?! from ).)*?|[^:]+)</F-USER> from <HOST>(?: (?:port \\d+|on \\S+)){0,2}(?: ssh\\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)', '^<F-USER>ROOT</F-USER> LOGIN REFUSED FROM <HOST>', '^[iI](?:llegal|nvalid) user <F-USER>.*?</F-USER> from <HOST>(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$', '^User <F-USER>.+</F-USER> from <HOST> not allowed because not listed in AllowUsers(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$', '^User <F-USER>.+</F-USER> from <HOST> not allowed because listed in DenyUsers(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$', '^User <F-USER>.+</F-USER> from <HOST> not allowed because not in any group(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$', '^refused connect from \\S+ \\(<HOST>\\)', '^Received <F-MLFFORGET>disconnect</F-MLFFORGET> from <HOST>(?: (?:port \\d+|on \\S+)){0,2}:\\s*3: .*: Auth fail(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$', '^User <F-USER>.+</F-USER> from <HOST> not allowed because a group is listed in DenyGroups(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$', "^User <F-USER>.+</F-USER> from <HOST> not allowed because none of user's groups are listed in AllowGroups(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$", '^<F-NOFAIL>pam_[a-z]+\\(sshd:auth\\):\\s+authentication failure;</F-NOFAIL>(?:\\s+(?:(?:logname|e?uid|tty)=\\S*)){0,4}\\s+ruser=<F-ALT_USER>\\S*</F-ALT_USER>\\s+rhost=<HOST>(?:\\s+user=<F-USER>\\S*</F-USER>)?(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$', '^(error: )?maximum authentication attempts exceeded for <F-USER>.*</F-USER> from <HOST>(?: (?:port \\d+|on \\S+)){0,2}(?: ssh\\d*)?(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$', '^User <F-USER>.+</F-USER> not allowed because account is locked(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*', '^<F-MLFFORGET>Disconnecting</F-MLFFORGET>(?: from)?(?: (?:invalid|authenticating)) user <F-USER>\\S+</F-USER> <HOST>(?: (?:port \\d+|on \\S+)){0,2}:\\s*Change of username or service not allowed:\\s*.*\\[preauth\\]\\s*$', '^<F-MLFFORGET>Disconnecting</F-MLFFORGET>: Too many authentication failures(?: for <F-USER>.+?</F-USER>)?(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$', '^<F-NOFAIL>Received <F-MLFFORGET>disconnect</F-MLFFORGET></F-NOFAIL> from <HOST>(?: (?:port \\d+|on \\S+)){0,2}:\\s*11:', '^<F-NOFAIL>Connection <F-MLFFORGET>closed</F-MLFFORGET></F-NOFAIL> by(?: authenticating user <F-USER>\\S+|.+?</F-USER>)? <HOST>(?:(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*|\\s*)$', '^<F-MLFFORGET><F-MLFGAINED>Accepted \\w+</F-MLFGAINED></F-MLFFORGET> for <F-USER>\\S+</F-USER> from <HOST>(?:\\s|$)', '^<F-NOFAIL>Connection from</F-NOFAIL> <HOST>']]
['set', 'sshd-auth', 'addjournalmatch', '_SYSTEMD_UNIT=sshd.service', '+', '_COMM=sshd']
['set', 'sshd-auth', 'usedns', 'warn']
['set', 'sshd-auth', 'bantime.multipliers', '1 2 4 8 16 32 64']
['set', 'sshd-auth', 'bantime.increment', True]
['set', 'sshd-auth', 'bantime.overalljails', False]
['set', 'sshd-auth', 'addlogpath', '/var/log/sshd/auth.log', 'head']
['set', 'sshd-auth', 'bantime.formula', 'ban.Time * (1<<(ban.Count if ban.Count<20 else 20)) * banFactor']
['set', 'sshd-auth', 'maxretry', 1]
['set', 'sshd-auth', 'bantime.rndtime', '4m']
['set', 'sshd-auth', 'addignoreip', '192.168.0.0/16', '91.216.72.209', '176.121.190.17']
['set', 'sshd-auth', 'bantime.maxtime', '10h']
['set', 'sshd-auth', 'bantime.factor', '1']
['set', 'sshd-auth', 'logencoding', 'auto']
['set', 'sshd-auth', 'bantime', '10m']
['set', 'sshd-auth', 'findtime', '10m']
['set', 'sshd-auth', 'maxmatches', 1]
['set', 'sshd-auth', 'addaction', 'nftables-multiport']
['multi-set', 'sshd-auth', 'action', 'nftables-multiport', [['actionunban', 'nft delete element inet filter <set_name> \\{ <ip> \\}'], ['actionstop', "HANDLE_ID=$(nft --handle --numeric list chain inet filter input | grep -m1 '<address_family> saddr @<set_name> reject # handle' | grep -oe ' handle [0-9]*')\nnft delete rule inet filter input $HANDLE_ID\nnft delete set inet filter <set_name>"], ['actionstart', 'nft add set inet filter <set_name> \\{ type <nftables_type>\\; \\}\nnft insert rule inet filter input tcp dport \\{ 22 \\} <address_family> saddr @<set_name> reject'], ['actionban', 'nft add element inet filter <set_name> \\{ <ip> \\}'], ['actioncheck', "nft list chain inet filter input | grep -q '@<set_name>[ \\t]'"], ['nftables_type', 'ipv4_addr'], ['protocol', 'tcp'], ['chain', '<known/chain>'], ['set_name?family=inet6', 'f2b-<name>6'], ['port', '22'], ['nftables', 'nft'], ['nftables_type?family=inet6', 'ipv6_addr'], ['nftables_table', 'filter'], ['actname', 'nftables-multiport'], ['bantime', '10m'], ['address_family?family=inet6', 'ip6'], ['nftables_family', 'inet'], ['blocktype', 'reject'], ['address_family', 'ip'], ['set_name', 'f2b-<name>'], ['name', 'sshd-auth']]]
['start', 'sshd-auth']
Openssh configuration:
UsePAM yes
AddressFamily inet
Port 22
XAuthLocation /nix/store/gx6v3mv601wnnk95kvqxry3knrw6w98d-xauth-1.0.10/bin/xauth
X11Forwarding yes
Subsystem sftp /nix/store/jb36i8a19kcfi9anni580i8afz9j9c96-openssh-7.9p1/libexec/sftp-server
PermitRootLogin yes
GatewayPorts no
PasswordAuthentication no
ChallengeResponseAuthentication no
PrintMotd no # handled by pam_motd
AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 /etc/ssh/authorized_keys.d/%u
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
KexAlgorithms [email protected]
Ciphers [email protected]
MACs [email protected]
LogLevel INFO
UseDNS no
AllowGroups ssh-users web-sftp
ListenAddress 0.0.0.0
ClientAliveCountMax 10
ClientAliveInterval 30
Compression no
TCPKeepAlive no
LoginGraceTime 40
MaxAuthTries 3
MaxSessions 1
MaxStartups 3:30:9
RekeyLimit 256m 30m
Banner none
PrintLastLog yes
AllowAgentForwarding no
AllowTcpForwarding no
FingerprintHash sha256
GSSAPIAuthentication no
HostbasedAuthentication no
IgnoreRhosts yes
KerberosAuthentication no
PermitEmptyPasswords no
PermitTTY yes
PermitTunnel no
PermitUserEnvironment no
PubkeyAuthentication yes
StrictModes yes
SyslogFacility AUTHPRIV
fail2ban.conf
[Definition]
loglevel = INFO
logtarget = SYSLOG
syslogsocket = auto
socket = /run/fail2ban/fail2ban.sock
pidfile = /run/fail2ban/fail2ban.pid
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 86400
jail.conf
[DEFAULT]
bantime.increment = true
bantime.rndtime = 4m
bantime.maxtime = 10h
bantime.factor = 1
bantime.formula = ban.Time * (1<<(ban.Count if ban.Count<20 else 20)) * banFactor
bantime.multipliers = 1 2 4 8 16 32 64
bantime.overalljails = false
ignoreip = 127.0.0.1/8
bantime = 10m
findtime = 10m
maxretry = 3
maxmatches = %(maxretry)s
backend = systemd
usedns = warn
logencoding = auto
enabled = true
mode = normal
filter = %(__name__)s[mode=%(mode)s]
protocol = tcp
chain = <known/chain>
port = 0:65535
banaction = nftables-multiport
action_ = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
action = %(action_)s
[sshd-auth]
enabled = true
filter = sshd
port = 22
backend = polling
bantime = 10m
maxretry = 3
logpath = /var/log/sshd/auth.log
Fail2ban - 0.11.0.dev3 019-08-22
OS - NixOS 19.09 (Loris)
Fail2ban does not process messages with unsuccessful ssh rsa authentication.
Shortly - this is not directly an authentication failure.
So this rule is implemented since 159957ab883efc151a2dddf53197153ba41576c2 but not enabled per default, you should specify mode = extra
or mode = aggressive
in the jail to enable the rule, like this example in jail.local
:
[sshd]
mode = aggressive
enabled = true
Added to config
maxretry = 1
mode = aggressive
auth log
Sep 3 12:54:49 Test sshd[29165]: Unable to negotiate with <HOST> port 60753: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1 [preauth]
Sep 3 12:55:34 Test sshd[29172]: Unable to negotiate with <HOST> port 21830: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1 [preauth]
Sep 3 12:56:18 Test sshd[29180]: Unable to negotiate with <HOST> port 26116: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1 [preauth]
Host not banned
Added to config ...
I hope you have also made fail2ban-client reload
? :smile:
auth log
Sep 3 12:54:49 Test sshd[29165]: Unable to negotiate with <HOST> ...
Do you really have <HOST>
instead of some address in your tests? :man_facepalming:
If yes, change it to the IP address.
Anyway it works pretty well on my side (of course with real IP from the test subnet):
$ msg='Sep 3 12:54:49 Test sshd[29165]: Unable to negotiate with 192.0.2.1 port 60753: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1 [preauth]'
$ fail2ban-regex -vv "$msg" 'sshd[mode=aggressive]'
Running tests
=============
Use failregex filter file : sshd, basedir: /etc/fail2ban/
Use filter options : {'mode': 'aggressive'}
Real filter options : {'logtype': 'file', 'mode': 'aggressive', 'datepattern': '{^LN-BEG}'}
Use maxlines : 1
Use datepattern : Default Detectors
Use single line : Sep 3 12:54:49 Test sshd[29165]: Unable to negoti...
Results
=======
Failregex: 1 total
|- #) [# of hits] regular expression
| ...
| 29) [1] ^Unable to negotiate with <HOST>(?: (?:port \d+|on \S+)){0,2}: no matching (?:(?:\w+ (?!found\b)){0,2}\w+) found.
| 192.0.2.1 Mon Sep 03 12:54:49 2018
| ...
`-
...
Lines: 1 lines, 0 ignored, 1 matched, 0 missed
[processed in 0.00 sec]
After rebooting the server does not work. Error activate aggressive mode.
fail2ban-client get sshd-auth failregex
The following regular expression are defined:
|- [0]: ^[aA]uthentication (?:failure|error|failed) for (?P<user>.*) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))( via \S+)?(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*$
|- [1]: ^User not known to the underlying authentication module for (?P<user>.*) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*$
|- [2]: ^Failed publickey for invalid user (?P<user>(?P<cond_user>\S+)|(?:(?! from ).)*?) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))(?: (?:port \d+|on \S+)){0,2}(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)
|- [3]: ^Failed \b(?!publickey)\S+ for (?P<cond_inv>invalid user )?(?P<user>(?P<cond_user>\S+)|(?(cond_inv)(?:(?! from ).)*?|[^:]+)) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))(?: (?:port \d+|on \S+)){0,2}(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)
|- [4]: ^(?P<user>ROOT) LOGIN REFUSED FROM (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))
|- [5]: ^[iI](?:llegal|nvalid) user (?P<user>.*?) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*$
|- [6]: ^User (?P<user>.+) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w)) not allowed because not listed in AllowUsers(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*$
|- [7]: ^User (?P<user>.+) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w)) not allowed because listed in DenyUsers(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*$
|- [8]: ^User (?P<user>.+) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w)) not allowed because not in any group(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*$
|- [9]: ^refused connect from \S+ \((?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))\)
|- [10]: ^Received (?P<mlfforget>disconnect) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))(?: (?:port \d+|on \S+)){0,2}:\s*3: .*: Auth fail(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*$
|- [11]: ^User (?P<user>.+) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w)) not allowed because a group is listed in DenyGroups(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*$
|- [12]: ^User (?P<user>.+) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w)) not allowed because none of user's groups are listed in AllowGroups(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*$
|- [13]: ^(?P<nofail>pam_[a-z]+\(sshd:auth\):\s+authentication failure;)(?:\s+(?:(?:logname|e?uid|tty)=\S*)){0,4}\s+ruser=(?P<alt_user>\S*)\s+rhost=(?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))(?:\s+user=(?P<user>\S*))?(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*$
|- [14]: ^(error: )?maximum authentication attempts exceeded for (?P<user>.*) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))(?: (?:port \d+|on \S+)){0,2}(?: ssh\d*)?(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*$
|- [15]: ^User (?P<user>.+) not allowed because account is locked(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*
|- [16]: ^(?P<mlfforget>Disconnecting)(?: from)?(?: (?:invalid|authenticating)) user (?P<user>\S+) (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))(?: (?:port \d+|on \S+)){0,2}:\s*Change of username or service not allowed:\s*.*\[preauth\]\s*$
|- [17]: ^(?P<mlfforget>Disconnecting): Too many authentication failures(?: for (?P<user>.+?))?(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*$
|- [18]: ^(?P<nofail>Received (?P<mlfforget>disconnect)) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))(?: (?:port \d+|on \S+)){0,2}:\s*11:
|- [19]: ^(?P<nofail>Connection (?P<mlfforget>closed)) by(?: authenticating user (?P<user>\S+|.+?))? (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))(?:(?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*|\s*)$
|- [20]: ^(?P<mlfforget>(?P<mlfgained>Accepted \w+)) for (?P<user>\S+) from (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))(?:\s|$)
`- [21]: ^(?P<nofail>Connection from) (?:(?:::f{4,6}:)?(?P<ip4>(?:\d{1,3}\.){3}\d{1,3})|\[?(?P<ip6>(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):))\]?|(?P<dns>[\w\-.^_]*\w))
jail.conf
[sshd-auth]
enabled = true
filter = sshd
port = 22
bantime = 10m
maxretry = 1
mode = aggressive
fail2ban-client reload
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: INFO Reload all jails
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.filtersystemd [4803]: DEBUG [sshd-auth] Flushed all journal matches
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.filtersystemd [4803]: DEBUG Journal matches restored
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.filtersystemd [4803]: INFO [sshd-auth] Removed journal match for: '*'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: INFO Reload jail 'sshd-auth'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.filter [4803]: INFO maxLines: 1
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG prefregex: '^<F-MLFID>\\s*(?:\\S+\\s+)?(?:sshd(?:\\[\\d+\\])?:?\\s+)?(?:kernel:\\s?\\[ *\\d+\\.\\d+\\]:?\\s+)?</F-MLFID>(?:(?:error|fatal): (?:PAM: )?)?<F-CONTENT>.+</F-CONTENT>$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^[aA]uthentication (?:failure|error|failed) for <F-USER>.*</F-USER> from <HOST>( via \\S+)?(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^User not known to the underlying authentication module for <F-USER>.*</F-USER> from <HOST>(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^Failed publickey for invalid user <F-USER>(?P<cond_user>\\S+)|(?:(?! from ).)*?</F-USER> from <HOST>(?: (?:port \\d+|on \\S+)){0,2}(?: ssh\\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^Failed \\b(?!publickey)\\S+ for (?P<cond_inv>invalid user )?<F-USER>(?P<cond_user>\\S+)|(?(cond_inv)(?:(?! from ).)*?|[^:]+)</F-USER> from <HOST>(?: (?:port \\d+|on \\S+)){0,2}(?: ssh\\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$)'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^<F-USER>ROOT</F-USER> LOGIN REFUSED FROM <HOST>'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^[iI](?:llegal|nvalid) user <F-USER>.*?</F-USER> from <HOST>(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^User <F-USER>.+</F-USER> from <HOST> not allowed because not listed in AllowUsers(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^User <F-USER>.+</F-USER> from <HOST> not allowed because listed in DenyUsers(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^User <F-USER>.+</F-USER> from <HOST> not allowed because not in any group(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^refused connect from \\S+ \\(<HOST>\\)'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^Received <F-MLFFORGET>disconnect</F-MLFFORGET> from <HOST>(?: (?:port \\d+|on \\S+)){0,2}:\\s*3: .*: Auth fail(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^User <F-USER>.+</F-USER> from <HOST> not allowed because a group is listed in DenyGroups(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: "^User <F-USER>.+</F-USER> from <HOST> not allowed because none of user's groups are listed in AllowGroups(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$"
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^<F-NOFAIL>pam_[a-z]+\\(sshd:auth\\):\\s+authentication failure;</F-NOFAIL>(?:\\s+(?:(?:logname|e?uid|tty)=\\S*)){0,4}\\s+ruser=<F-ALT_USER>\\S*</F-ALT_USER>\\s+rhost=<HOST>(?:\\s+user=<F-USER>\\S*</F-USER>)?(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^(error: )?maximum authentication attempts exceeded for <F-USER>.*</F-USER> from <HOST>(?: (?:port \\d+|on \\S+)){0,2}(?: ssh\\d*)?(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^User <F-USER>.+</F-USER> not allowed because account is locked(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^<F-MLFFORGET>Disconnecting</F-MLFFORGET>(?: from)?(?: (?:invalid|authenticating)) user <F-USER>\\S+</F-USER> <HOST>(?: (?:port \\d+|on \\S+)){0,2}:\\s*Change of username or service not allowed:\\s*.*\\[preauth\\]\\s*$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^<F-MLFFORGET>Disconnecting</F-MLFFORGET>: Too many authentication failures(?: for <F-USER>.+?</F-USER>)?(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^<F-NOFAIL>Received <F-MLFFORGET>disconnect</F-MLFFORGET></F-NOFAIL> from <HOST>(?: (?:port \\d+|on \\S+)){0,2}:\\s*11:'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^<F-NOFAIL>Connection <F-MLFFORGET>closed</F-MLFFORGET></F-NOFAIL> by(?: authenticating user <F-USER>\\S+|.+?</F-USER>)? <HOST>(?:(?: (?:port \\d+|on \\S+|\\[preauth\\])){0,3}\\s*|\\s*)$'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^<F-MLFFORGET><F-MLFGAINED>Accepted \\w+</F-MLFGAINED></F-MLFFORGET> for <F-USER>\\S+</F-USER> from <HOST>(?:\\s|$)'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: DEBUG failregex: '^<F-NOFAIL>Connection from</F-NOFAIL> <HOST>'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.filtersystemd [4803]: INFO [sshd-auth] Added journal match for: '_SYSTEMD_UNIT=sshd.service + _COMM=sshd'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.filter [4803]: DEBUG Setting usedns = warn for FilterSystemd(Jail('sshd-auth'))
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.jail [4803]: INFO Set banTime.multipliers = 1 2 4 8 16 32 64
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.jail [4803]: INFO Set banTime.increment = True
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.jail [4803]: INFO Set banTime.overalljails = False
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.jail [4803]: INFO Set banTime.formula = ban.Time * (1<<(ban.Count if ban.Count<20 else 20)) * banFactor
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.filter [4803]: INFO maxRetry: 1
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.jail [4803]: INFO Set banTime.rndtime = 4m
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.filter [4803]: DEBUG Add '192.168.0.0/16' to ignore list ('192.168.0.0/16')
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.filter [4803]: DEBUG Add '91.216.72.209' to ignore list ('91.216.72.209')
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.filter [4803]: DEBUG Add '176.121.190.17' to ignore list ('176.121.190.17')
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.jail [4803]: INFO Set banTime.maxtime = 10h
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.jail [4803]: INFO Set banTime.factor = 1
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.filter [4803]: INFO encoding: UTF-8
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.actions [4803]: INFO banTime: 600
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.filter [4803]: INFO findtime: 600
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set actionunban = 'nft delete element inet filter <set_name> \\{ <ip> \\}'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set actionstop = "HANDLE_ID=$(nft --handle --numeric list chain inet filter input | grep -m1 '<address_family> saddr @<set_name> reject # handle' | grep -oe ' handle [0-9]*')\nnft delete rule inet filter input $HANDLE_ID\nnft delete set inet filter <set_name>"
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set actionstart = 'nft add set inet filter <set_name> \\{ type <nftables_type>\\; \\}\nnft insert rule inet filter input tcp dport \\{ 22 \\} <address_family> saddr @<set_name> reject'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set actionban = 'nft add element inet filter <set_name> \\{ <ip> \\}'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set actioncheck = "nft list chain inet filter input | grep -q '@<set_name>[ \\t]'"
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set nftables_type = 'ipv4_addr'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set protocol = 'tcp'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set chain = '<known/chain>'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set set_name?family=inet6 = 'f2b-<name>6'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set port = '22'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set nftables = 'nft'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set nftables_type?family=inet6 = 'ipv6_addr'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set nftables_table = 'filter'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set actname = 'nftables-multiport'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set address_family?family=inet6 = 'ip6'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set nftables_family = 'inet'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set blocktype = 'reject'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set address_family = 'ip'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set set_name = 'f2b-<name>'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.CommandAction [4803]: DEBUG Set name = 'sshd-auth'
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: INFO Jail 'sshd-auth' reloaded
ัะตะฝ 03 15:37:15 Test .fail2ban-serve[4803]: fail2ban.server [4803]: INFO Reload finished.
Change jail.conf to
[DEFAULT]
...
mode = aggressive
...
does not help
After rebooting the server does not work. Error activate aggressive mode.
You don't need reboot to reload fail2ban config.
Where you see the error?... I don't see any error in your excerpt.
Just aggressive rules have been not applying, because of that:
[sshd-auth]
filter = sshd
Substitution of mode
will be used in default filter
interpolation.
https://github.com/fail2ban/fail2ban/blob/5045c4bb00c522c3691e7e47a706c24d8950f58e/config/jail.conf#L167
But you overwrite this in config of your new jail, so your variant would not work, because you use another filter value (sshd without parameters).
Either you'd use default jail (which use default filter interpolation):
[sshd]
enabled = true
mode = aggressive
Or if you want your own jail at all costs, then supply this parameter manually to the filter:
[sshd-auth]
enabled = true
filter = sshd[mode=aggressive]
# or this one:
# filter = sshd[mode=%(mode)s]
# mode = aggressive
Change jail.conf to ... does not help
Don't change jail.conf
- all local modification should be done in jail.local
(and your changes only... it will overwrite or append related entries of jail.conf
).
See wiki for more info.
In the NixOS distro, all changes are written right into jail.conf and fail2ban.conf files.
Thank you for the help.
In the NixOS distro, all changes are written right into jail.conf and fail2ban.conf files.
I'm not sure this would make review/merge process more difficult by modifications of stock jail.
Just to show you another way (how it made by maintainers of some other distributions)...
You can provide a new config file(s) (paths-nixos.conf
and/or jail-nixos.conf
) containing only distribution related parameters and/or rewriting some basic interpolations (you may need to rewrite).
And replace the includes in jail.conf
like here:
- before = paths-debian.conf
+ before = paths-nixos.conf
+ after = jail-nixos.conf
This way you could have clearer overview of all yours parameters and don't necessary need to modify/merge every time by some small changes on jail.conf
in stock version of fail2ban.
I created this PR - https://github.com/NixOS/nixpkgs/pull/67931
In PR created symlinks to files:
/etc/fail2ban/fail2ban.conf
/etc/fail2ban/jail.conf
/etc/fail2ban/paths-common.conf
/etc/fail2ban/paths-debian.conf
/etc/fail2ban/action.d/*.conf
/etc/fail2ban/filter.d/*.conf
And all changes are generated to files:
/etc/fail2ban/fail2ban/fail2ban.local
/etc/fail2ban/fail2ban/jail.local
With this config fail2ban.local
[Definition]
loglevel = DEBUG
logtarget = SYSLOG
socket = /run/fail2ban/fail2ban.sock
pidfile = /run/fail2ban/fail2ban.pid
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
jail.local
[DEFAULT]
bantime.increment = true
bantime.rndtime = 4m
bantime.maxtime = 10h
bantime.factor = 1
bantime.formula = ban.Time * (1<<(ban.Count if ban.Count<20 else 20)) * banFactor
bantime.multipliers = 1 2 4 8 16 32 64
bantime.overalljails = false
# Miscellaneous options
ignoreip = 127.0.0.1/8
maxretry = 3
backend = systemd
# Actions
banaction = nftables-multiport
banaction_allports = nftables-allport
[sshd]
enabled = true
port = 22
maxretry = 1
mode = aggressive
correct work
Firstly I don't think /etc/fail2ban/fail2ban/fail2ban.local
and /etc/fail2ban/fail2ban/jail.local
would do something - it is a level too deeply (either /etc/fail2ban/fail2ban/
should be /etc/fail2ban/
there).
Secondly I really don't think this is a good idea at all, because *.local
files are intended for user own customization, not for distribution/package related stuff.
This way you force user to change released configs (which can be rewritten with the next update).
In nixos, the user writes such a example configuration
services.fail2ban = {
enable = false;
package = pkgs.fail2ban_0_11;
packageFirewall = pkgs.nftables;
banaction = "nftables-multiport";
banaction-allports = "nftables-allport";
bantime-increment = true;
daemonConfig = ''
[Definition]
loglevel = DEBUG
logtarget = SYSLOG
socket = /run/fail2ban/fail2ban.sock
pidfile = /run/fail2ban/fail2ban.pid
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
'';
jails = {
sshd = ''
maxretry = 2
mode = aggressive
'';
};
};
As a result, the system generates files
fail2ban.local
[Definition]
loglevel = DEBUG
logtarget = SYSLOG
socket = /run/fail2ban/fail2ban.sock
pidfile = /run/fail2ban/fail2ban.pid
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
jail.local
[DEFAULT]
bantime.increment = true
bantime.rndtime = 4m
bantime.maxtime = 10h
bantime.factor = 1
bantime.formula = ban.Time * (1<<(ban.Count if ban.Count<20 else 20)) * banFactor
bantime.multipliers = 1 2 4 8 16 32 64
bantime.overalljails = false
# Miscellaneous options
ignoreip = 127.0.0.1/8
maxretry = 3
backend = systemd
# Actions
banaction = nftables-multiport
banaction_allports = nftables-allport
[sshd]
enabled = true
port = 22
maxretry = 1
mode = aggressive
If a change is required, user changes content services.fail2ban.
This is because NixOS has a declarative configuration model: you create or edit a description of the desired configuration of your system, and then NixOS takes care of making it happen.
Understand. I thought you wanted to write some dist-related stuff into local-configs.
If user would never touch it directly (and anyway don't mix own changes with dist changes), I've no objections so far.
@sebres 3 filters didnโt work for me.
murmurd systemd
:
ัะตะฝ 08 13:00:05 Test murmurd[2064]: <W>2019-09-08 13:00:05.283 1 => <10:(-1)> New connection: 31.13.144.65:31752
ัะตะฝ 08 13:00:05 Test murmurd[2064]: <W>2019-09-08 13:00:05.602 1 => <10:(-1)> Client version 1.2.5 (Android: Plumble Free 3.2.0)
ัะตะฝ 08 13:00:05 Test murmurd[2064]: <W>2019-09-08 13:00:05.615 1 => <10:Test(-1)> Rejected connection from 31.13.144.65:31752: Invalid server password
ัะตะฝ 08 13:00:05 Test murmurd[2064]: <W>2019-09-08 13:00:05.627 1 => <10:Test(-1)> Connection closed: [-1]
znc-adminlog systemd
:
ัะตะฝ 08 15:53:19 Test znc[37232]: [admin] failed to login from 46.165.230.5:65009
znc-adminlog moddata/adminlog/znc.log
[2019-09-08 15:53:19] [admin] failed to login from 46.165.230.5:65009
sieve systemd
:
ัะตะฝ 08 10:16:11 Test dovecot[2170]: managesieve-login: Disconnected (auth failed, 1 attempts in 67 secs): user=<test>, method=LOGIN, rip=<HOST>, lip=192.168.0.202, TLS: Connection closed, session=<6B0pbgWSaMRb2EjR>
ัะตะฝ 08 10:16:38 Test dovecot[2170]: managesieve-login: Disconnected (no auth attempts in 14 secs): user=<>, rip=<HOST>, lip=192.168.0.202, session=<aP/EcwWSWcdb2EjR>
ัะตะฝ 08 10:16:58 Test dovecot[2170]: managesieve-login: Disconnected: Too many invalid commands. (no auth attempts in 2 secs): user=<>, rip=<HOST>, lip=192.168.0.202, session=<vF7+dAWSl8hb2EjR>
ัะตะฝ 08 10:20:06 Test dovecot[2170]: managesieve-login: Disconnected: Inactivity (no auth attempts in 180 secs): user=<>, rip=<HOST>, lip=192.168.0.202, session=<wfgugAWS8chb2EjR>
ัะตะฝ 08 16:14:21 Test dovecot[2170]: managesieve-login: Aborted login (auth failed, 1 attempts in 2 secs): user=<test>, method=PLAIN, rip=<HOST>, lip=192.168.0.202, TLS, session=<WqzycgqSKeRb2EjR>
fail2ban-regex -vv "$msg" 'murmur'
Running tests
=============
Use failregex filter file : murmur, basedir: /etc/fail2ban
Real filter options : {'logtype': 'file', 'datepattern': '^<W>{DATE}'}
Use datepattern : Default Detectors
Use single line : ัะตะฝ 08 13:00:05 Test murmurd[2064]: <W>2019-09-...
Results
=======
Failregex: 0 total
|- #) [# of hits] regular expression
| 1) [0] ^Invalid server password$
| 2) [0] ^Wrong certificate or password for existing user$
`-
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
| [0] ^<W>ExYear(?P<_sep>[-/.])Month(?P=_sep)Day(?:T| ?)24hour:Minute:Second(?:[.,]Microseconds)?(?:\s*Zone offset)?
| [0] ^<W>(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] ^<W>(?:DAY )?MON Day ExYear %k:Minute:Second(?:\.Microseconds)?
| [0] ^<W>Day(?P<_sep>[-/])Month(?P=_sep)(?:ExYear|ExYear2) %k:Minute:Second
| [0] ^<W>Day(?P<_sep>[-/])MON(?P=_sep)ExYear[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?
| [0] ^<W>Month/Day/ExYear:24hour:Minute:Second
| [0] ^<W>Month-Day-ExYear %k:Minute:Second(?:\.Microseconds)?
| [0] ^<W>Epoch
| [0] ^<W>24hour:Minute:Second
| [0] ^<W>^<Month/Day/ExYear2@24hour:Minute:Second>
| [0] ^<W>ExYear2ExMonthExDay ?24hour:Minute:Second
| [0] ^<W>MON Day, ExYear 12hour:Minute:Second AMPM
| [0] ^<W>^MON-Day-ExYear2 %k:Minute:Second
| [0] ^<W>ExYearExMonthExDay(?:T| ?)Ex24hourExMinuteExSecond(?:[.,]Microseconds)?(?:\s*Zone offset)?
| [0] ^<W>(?:Zone name )?(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] ^<W>(?:Zone offset )?(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] ^<W>TAI64N
`-
Lines: 1 lines, 0 ignored, 0 matched, 1 missed
[processed in 0.01 sec]
|- Missed line(s):
| ัะตะฝ 08 13:00:05 Test murmurd[2064]: <W>2019-09-08 13:00:05.615 1 => <10:Test(-1)> Rejected connection from 31.13.144.65:31752: Invalid server password
`-
fail2ban-regex -vv "$msg" 'znc-adminlog[backend=systemd]'
Running tests
=============
Use failregex filter file : znc-adminlog, basedir: /etc/fail2ban
Use filter options : {'backend': 'systemd'}
Real filter options : {'logtype': 'file', 'backend': 'systemd'}
Use single line : ัะตะฝ 08 15:53:19 Test znc[37232]: [admin...
Results
=======
Failregex: 0 total
|- #) [# of hits] regular expression
| 1) [0] ^\[\] \[[^]]+\] failed to login from <ADDR>$
`-
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
| [0] {^LN-BEG}ExYear(?P<_sep>[-/.])Month(?P=_sep)Day(?:T| ?)24hour:Minute:Second(?:[.,]Microseconds)?(?:\s*Zone offset)?
| [0] {^LN-BEG}(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] {^LN-BEG}(?:DAY )?MON Day ExYear %k:Minute:Second(?:\.Microseconds)?
| [0] {^LN-BEG}Day(?P<_sep>[-/])Month(?P=_sep)(?:ExYear|ExYear2) %k:Minute:Second
| [0] {^LN-BEG}Day(?P<_sep>[-/])MON(?P=_sep)ExYear[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?
| [0] {^LN-BEG}Month/Day/ExYear:24hour:Minute:Second
| [0] {^LN-BEG}Month-Day-ExYear %k:Minute:Second(?:\.Microseconds)?
| [0] {^LN-BEG}Epoch
| [0] {^LN-BEG}ExYear2ExMonthExDay ?24hour:Minute:Second
| [0] {^LN-BEG}MON Day, ExYear 12hour:Minute:Second AMPM
| [0] {^LN-BEG}ExYearExMonthExDay(?:T| ?)Ex24hourExMinuteExSecond(?:[.,]Microseconds)?(?:\s*Zone offset)?
| [0] {^LN-BEG}(?:Zone name )?(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] {^LN-BEG}(?:Zone offset )?(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] {^LN-BEG}TAI64N
| [0] ExYear(?P<_sep>[-/.])Month(?P=_sep)Day(?:T| ?)24hour:Minute:Second(?:[.,]Microseconds)?(?:\s*Zone offset)?
| [0] (?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] (?:DAY )?MON Day ExYear %k:Minute:Second(?:\.Microseconds)?
| [0] Day(?P<_sep>[-/])Month(?P=_sep)(?:ExYear|ExYear2) %k:Minute:Second
| [0] Day(?P<_sep>[-/])MON(?P=_sep)ExYear[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?
| [0] Month/Day/ExYear:24hour:Minute:Second
| [0] Month-Day-ExYear %k:Minute:Second(?:\.Microseconds)?
| [0] Epoch
| [0] {^LN-BEG}24hour:Minute:Second
| [0] ^<Month/Day/ExYear2@24hour:Minute:Second>
| [0] ExYear2ExMonthExDay ?24hour:Minute:Second
| [0] MON Day, ExYear 12hour:Minute:Second AMPM
| [0] ^MON-Day-ExYear2 %k:Minute:Second
| [0] ExYearExMonthExDay(?:T| ?)Ex24hourExMinuteExSecond(?:[.,]Microseconds)?(?:\s*Zone offset)?
| [0] (?:Zone name )?(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] (?:Zone offset )?(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] TAI64N
`-
Lines: 1 lines, 0 ignored, 0 matched, 1 missed
[processed in 0.03 sec]
|- Missed line(s):
| ัะตะฝ 08 15:53:19 Test znc[37232]: [admin] failed to login from 46.165.230.5:65009
`-
fail2ban-regex -vv "$msg" 'znc-adminlog[backend=polling]'
Running tests
=============
Use failregex filter file : znc-adminlog, basedir: /etc/fail2ban
Use filter options : {'backend': 'polling'}
Real filter options : {'logtype': 'file', 'backend': 'polling'}
Use single line : [2019-09-08 15:53:19] [admin] failed to login from...
Results
=======
Failregex: 0 total
|- #) [# of hits] regular expression
| 1) [0] ^\[\] \[[^]]+\] failed to login from <ADDR>$
`-
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
| [1] {^LN-BEG}ExYear(?P<_sep>[-/.])Month(?P=_sep)Day(?:T| ?)24hour:Minute:Second(?:[.,]Microseconds)?(?:\s*Zone offset)?
| [0] {^LN-BEG}(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] {^LN-BEG}(?:DAY )?MON Day ExYear %k:Minute:Second(?:\.Microseconds)?
| [0] {^LN-BEG}Day(?P<_sep>[-/])Month(?P=_sep)(?:ExYear|ExYear2) %k:Minute:Second
| [0] {^LN-BEG}Day(?P<_sep>[-/])MON(?P=_sep)ExYear[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?
| [0] {^LN-BEG}Month/Day/ExYear:24hour:Minute:Second
| [0] {^LN-BEG}Month-Day-ExYear %k:Minute:Second(?:\.Microseconds)?
| [0] {^LN-BEG}Epoch
| [0] {^LN-BEG}ExYear2ExMonthExDay ?24hour:Minute:Second
| [0] {^LN-BEG}MON Day, ExYear 12hour:Minute:Second AMPM
| [0] {^LN-BEG}ExYearExMonthExDay(?:T| ?)Ex24hourExMinuteExSecond(?:[.,]Microseconds)?(?:\s*Zone offset)?
| [0] {^LN-BEG}(?:Zone name )?(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] {^LN-BEG}(?:Zone offset )?(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] {^LN-BEG}TAI64N
| [0] ExYear(?P<_sep>[-/.])Month(?P=_sep)Day(?:T| ?)24hour:Minute:Second(?:[.,]Microseconds)?(?:\s*Zone offset)?
| [0] (?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] (?:DAY )?MON Day ExYear %k:Minute:Second(?:\.Microseconds)?
| [0] Day(?P<_sep>[-/])Month(?P=_sep)(?:ExYear|ExYear2) %k:Minute:Second
| [0] Day(?P<_sep>[-/])MON(?P=_sep)ExYear[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?
| [0] Month/Day/ExYear:24hour:Minute:Second
| [0] Month-Day-ExYear %k:Minute:Second(?:\.Microseconds)?
| [0] Epoch
| [0] {^LN-BEG}24hour:Minute:Second
| [0] ^<Month/Day/ExYear2@24hour:Minute:Second>
| [0] ExYear2ExMonthExDay ?24hour:Minute:Second
| [0] MON Day, ExYear 12hour:Minute:Second AMPM
| [0] ^MON-Day-ExYear2 %k:Minute:Second
| [0] ExYearExMonthExDay(?:T| ?)Ex24hourExMinuteExSecond(?:[.,]Microseconds)?(?:\s*Zone offset)?
| [0] (?:Zone name )?(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] (?:Zone offset )?(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] TAI64N
`-
Lines: 1 lines, 0 ignored, 0 matched, 1 missed
[processed in 0.00 sec]
|- Missed line(s):
| [2019-09-08 15:53:19] [admin] failed to login from 46.165.230.5:65009
`-
fail2ban-regex -vv "$msg" 'sieve[backend=systemd]'
Running tests
=============
Use failregex filter file : sieve, basedir: /etc/fail2ban
Use filter options : {'backend': 'systemd'}
Real filter options : {'logtype': 'file', 'backend': 'systemd', 'datepattern': '{^LN-BEG}'}
Use datepattern : Default Detectors
Use single line : ัะตะฝ 08 16:14:21 Test dovecot[2170]: ma...
Results
=======
Failregex: 0 total
|- #) [# of hits] regular expression
| 1) [0] ^(?:\[\])?\s*(?:<[^.]+\.[^.]+>\s+)?(?:\S+\s+)?(?:kernel:\s?\[ *\d+\.\d+\]:?\s+)?(?:@vserver_\S+\s+)?(?:(?:(?:\[\d+\])?:\s+[\[\(]?\S*(?:\(\S+\))?[\]\)]?:?|[\[\(]?\S*(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:?)\s+)?(?:\[ID \d+ \S+\]\s+)?badlogin: \S+ ?\[<HOST>\] \S+ authentication failure$
`-
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
| [0] {^LN-BEG}ExYear(?P<_sep>[-/.])Month(?P=_sep)Day(?:T| ?)24hour:Minute:Second(?:[.,]Microseconds)?(?:\s*Zone offset)?
| [0] {^LN-BEG}(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] {^LN-BEG}(?:DAY )?MON Day ExYear %k:Minute:Second(?:\.Microseconds)?
| [0] {^LN-BEG}Day(?P<_sep>[-/])Month(?P=_sep)(?:ExYear|ExYear2) %k:Minute:Second
| [0] {^LN-BEG}Day(?P<_sep>[-/])MON(?P=_sep)ExYear[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?
| [0] {^LN-BEG}Month/Day/ExYear:24hour:Minute:Second
| [0] {^LN-BEG}Month-Day-ExYear %k:Minute:Second(?:\.Microseconds)?
| [0] {^LN-BEG}Epoch
| [0] {^LN-BEG}ExYear2ExMonthExDay ?24hour:Minute:Second
| [0] {^LN-BEG}MON Day, ExYear 12hour:Minute:Second AMPM
| [0] {^LN-BEG}ExYearExMonthExDay(?:T| ?)Ex24hourExMinuteExSecond(?:[.,]Microseconds)?(?:\s*Zone offset)?
| [0] {^LN-BEG}(?:Zone name )?(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] {^LN-BEG}(?:Zone offset )?(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
| [0] {^LN-BEG}TAI64N
| [0] {^LN-BEG}24hour:Minute:Second
| [0] ^<Month/Day/ExYear2@24hour:Minute:Second>
| [0] ^MON-Day-ExYear2 %k:Minute:Second
`-
Lines: 1 lines, 0 ignored, 0 matched, 1 missed
[processed in 0.01 sec]
|- Missed line(s):
| ัะตะฝ 08 16:14:21 Test dovecot[2170]: managesieve-login: Aborted login (auth failed, 1 attempts in 2 secs): user=<test>, method=PLAIN, rip=<HOST>, lip=192.168.0.202, TLS, session=<WqzycgqSKeRb2EjR>
`-
You date-time seems to have localized timestamp like ัะตะฝ 08 15:53:19
(see https://github.com/fail2ban/fail2ban/issues/2477#issuecomment-514190185 for similar issue).
Although it is relevant for file backends only. But you said it is journal (systemd backend), right?
Several filters of fail2ban are not systemd journal capable per default and must be updated (sometimes they also have some system- or distribution-related stuff).
As for murmur, I don't think the filter is capable at the moment - but also your log-excerpt of murmurd show double timestamp logged (what should be extended).
Localization is available. I'll try to check the patch later.
znc-adminlog cheked with backend systemd and polling.
murmur and sieve cheked with systemd backend.
I'll try to check the patch later.
You don't need it for systemd-backend related jails (the timestamp is read directly via systemd API as pythonic datetime and must be not "localized" at all).
@sebres need wait for filters updates?
Is it really to add such filters? - https://github.com/Izorkin/nur-packages/tree/master/pkgs/tools/fail2ban/filter.d
Found on the Internet.
https://gist.github.com/dale3h/660fe549df8232d1902f338e6d3b39ed - updated nginx-badbots.conf
fail2ban-regex -vv "$msg" 'murmur'
fail2ban-regex -vv "$msg" 'znc-adminlog[backend=systemd]'
It looks like you are testing not quit correctly:
backend=systemd
would do nothing - although since #2387, backend systemd
would set logtype
to journal
automatically, but it does not occur using this parameter for fail2ban-regex
):fail2ban-regex systemd-journal murmur
logtype=journal
as parameter - fail2ban-regex "$msg" murmur[logtype=journal]
"$msg"
(use some standard ISO pattern like 2019-09-08 13:00:05
instead), because fail2ban cannot parse it at the moment... (although systemd backend does not require it, but fail2ban-regex
would use default datepattern in case of direct message, so quasi file-filter is used.Also related to 19a5a2f8c03d2c3b1fd3e7622db12619a1488ade (#2043) filter for murmur should be already systemd capable. I'll extend test-cases to cover your message format.
Could you try it also over your journal?
fail2ban-regex systemd-journal murmur
Well it should indeed work (fbd4bfc595f995d924ef108d335fb0ac67550514 pass the test to me)...
Can you also test other filters you meant above and provide a feedback which working and which don't?
As for nginx filters - I think a new issue (or even PR) would be better.
Well as for znc-adminlog, it would not work... Additionally to systemd info (unit etc), it seems to have new part with port :65009
which is unexpected by filter at the moment.
I could fix it with adding (?::\d+)
after <ADDR>
or removing end anchor $
, but it may be not IPv6 conform... don't know how it would look in this case, but some ports (up-to 4 digits) can be mistakenly captured as part of Ipv6, for example in the first line is 1234 a port or part of address:
-::1:2:3:1234
+[::1:2:3]:1234
In order to fix it properly, would be nice if someone could test znc against IPv6 and provide a message generated by IPv6 address.
Found my error on murmur filter
Work with this command
fail2ban-client set murmur addjournalmatch _SYSTEMD_UNIT=murmur.service + _COMM=murmurd
Not work with this config /etc/fail2ban/jail.local
[murmur]
enabled = true
journalmatch = _SYSTEMD_UNIT=murmur.service + _COMM=murmurd
fail2ban-client -v -d | grep "journalmatch"
2019-09-10 21:44:37,488 fail2ban.configreader [44267]: INFO Loading configs for fail2ban under /etc/fail2ban
2019-09-10 21:44:37,489 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/fail2ban.conf']
2019-09-10 21:44:37,489 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/fail2ban.local']
2019-09-10 21:44:37,490 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/fail2ban.conf', '/etc/fail2ban/fail2ban.local']
2019-09-10 21:44:37,490 fail2ban [44267]: INFO Using socket file /run/fail2ban/fail2ban.sock
2019-09-10 21:44:37,491 fail2ban [44267]: INFO Using pid file /run/fail2ban/fail2ban.pid, [DEBUG] logging to SYSLOG
2019-09-10 21:44:37,491 fail2ban.configreader [44267]: INFO Loading configs for jail under /etc/fail2ban
2019-09-10 21:44:37,492 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/jail.conf']
2019-09-10 21:44:37,496 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/paths-debian.conf']
2019-09-10 21:44:37,497 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/paths-common.conf']
2019-09-10 21:44:37,498 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/paths-overrides.local']
2019-09-10 21:44:37,498 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/jail.local']
2019-09-10 21:44:37,499 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/paths-common.conf', '/etc/fail2ban/paths-debian.conf', '/etc/fail2ban/jail.conf', '/etc/fail2ban/jail.local']
2019-09-10 21:44:37,505 fail2ban.configreader [44267]: INFO Loading configs for filter.d/murmur under /etc/fail2ban
2019-09-10 21:44:37,506 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/filter.d/murmur.conf']
2019-09-10 21:44:37,507 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/filter.d/murmur.conf']
2019-09-10 21:44:37,508 fail2ban.configreader [44267]: INFO Loading configs for action.d/nftables-multiport under /etc/fail2ban
2019-09-10 21:44:37,509 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/action.d/nftables-multiport.conf']
2019-09-10 21:44:37,509 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/action.d/nftables-common.conf']
2019-09-10 21:44:37,511 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/action.d/nftables-common.local']
2019-09-10 21:44:37,511 fail2ban.configparserin [44267]: INFO Loading files: ['/etc/fail2ban/action.d/nftables-common.conf', '/etc/fail2ban/action.d/nftables-multiport.conf']
['set', 'murmur', 'addjournalmatch', '_SYSTEMD_UNIT=murmurd.service', '+', '_COMM=murmurd']
znc-adminlog with this config /etc/fail2ban/jail.local
[znc-adminlog]
enabled = true
logpath = /var/data/znc/moddata/adminlog/znc.log
backend = polling
failregex = ^\[\] \[[^]]+\] failed to login from <ADDR>(?::\d+1)$
correct work.
There is no way to check with ipv6
Thanks to help.
Not work with this config /etc/fail2ban/jail.local
journalmatch = _SYSTEMD_UNIT=murmur.service + _COMM=murmurd
Hmm... why you should supply it in your jail (it is part of filter).
Also note the jail should get backend = systemd
in order to activate systemd-backend, otherwise your default backend (e. g. auto
, which trying file-backends only) would be used.
failregex = ^\[\] \[[^]]+\] failed to login from <ADDR>(?::\d+1)$
I think there is a typo (in port part - 1
before $
).
Anyway, a36b70c7b54c0c780f2de132d3b6ff57eefa7109 should fix that also.
Default used systemd backend
Manually added not work
[murmur]
enabled = true
backend = systemd
journalmatch = _SYSTEMD_UNIT=murmur.service + _COMM=murmurd
I think there is a typo (in port part -
1
before$
).
This is fixed. Added to check rule work.
Default systemd service name = murmur
not murmurd
https://github.com/mumble-voip/mumble/blob/master/scripts/murmur.service
Oh... you want to overwrite this?
Anyway journalmatch
is parameter of the filter at the moment, to overwrite it properly one should write:
jail.local
:[murmur]
filter = murmur[journalmatch="_SYSTEMD_UNIT=murmur.service + _COMM=murmurd"]
filter.d/murmur.local
:[Definition]
journalmatch = _SYSTEMD_UNIT=murmur.service + _COMM=murmurd
Default systemd service name = murmur not murmurd
The question is - is it valid for each distribution?
[murmur]
filter = murmur[journalmatch="_SYSTEMD_UNIT=murmur.service + _COMM=murmurd"]
Thanks, worked :)
looked in debian 10 - used mumble-server
sieve
filter left )
As for overwriting of journalmatch
etc in jail (https://github.com/fail2ban/fail2ban/issues/2520#issuecomment-530086101):
since 7b3ee3dadcd0e73742466659c2f1f70512862d67 (0.10) and 990c41087749e07545bd68c19ba05160abf8e16b (0.11) it is basically allowed to set all standard filter options directly in jail (without supplying of them as parameters to the filter as well as without filter at all).
So your approach from https://github.com/fail2ban/fail2ban/issues/2520#issuecomment-530081828 would work now.
The list of such options we supporting directly can be found here:
https://github.com/fail2ban/fail2ban/blob/7b3ee3dadcd0e73742466659c2f1f70512862d67/fail2ban/client/filterreader.py#L40-L45
and will be now automatically extended (supported) if filter-reader would get new options (or some forks have that extended).
This variant working
/etc/fail2ban/jail.local
[murmur]
enabled = true
journalmatch = _SYSTEMD_UNIT=murmur.service + _COMM=murmurd
[znc-adminlog]
enabled = true
port = http,https,5010