mirror of https://github.com/fail2ban/fail2ban
Merge branch 'master' into debian
commit
9061536fb0
|
@ -9,4 +9,4 @@ check-hidden = true
|
||||||
ignore-regex = (\b([A-Z][A-Z][A-Z]+|gir\.st)\b)|\[[a-zA-Z]+\][a-z]+\b|[a-z]+://\S+|.*codespell-ignore.*
|
ignore-regex = (\b([A-Z][A-Z][A-Z]+|gir\.st)\b)|\[[a-zA-Z]+\][a-z]+\b|[a-z]+://\S+|.*codespell-ignore.*
|
||||||
# some oddly named variables, some names, etc
|
# some oddly named variables, some names, etc
|
||||||
# wee -- comes in regex etc for weeks
|
# wee -- comes in regex etc for weeks
|
||||||
ignore-words-list = theis,timere,alls,wee,wight,ans,re-use
|
ignore-words-list = assertIn,theis,timere,alls,wee,wight,ans,re-use
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# These are supported funding model platforms
|
# These are supported funding model platforms
|
||||||
|
|
||||||
github: [sebres]
|
github: [sebres]
|
||||||
custom: [paypal.me/sebres]
|
custom: [https://paypal.me/sebres]
|
||||||
|
liberapay: sebres
|
||||||
|
|
|
@ -22,7 +22,7 @@ jobs:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12', '3.13.0-alpha.2', pypy3.10]
|
python-version: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12', '3.13.0-beta.3', pypy3.10]
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||||
steps:
|
steps:
|
||||||
|
@ -79,7 +79,7 @@ jobs:
|
||||||
cd "$GITHUB_WORKSPACE"
|
cd "$GITHUB_WORKSPACE"
|
||||||
_debug() { echo -n "$1 "; err=$("${@:2}" 2>&1) && echo 'OK' || echo -e "FAIL\n$err"; }
|
_debug() { echo -n "$1 "; err=$("${@:2}" 2>&1) && echo 'OK' || echo -e "FAIL\n$err"; }
|
||||||
# (debug) output current preferred encoding:
|
# (debug) output current preferred encoding:
|
||||||
_debug 'Encodings:' python -c 'import locale, sys; from fail2ban.helpers import PREFER_ENC; print(PREFER_ENC, locale.getpreferredencoding(), (sys.stdout and sys.stdout.encoding))'
|
echo 'Encodings:' $(python -c 'import locale, sys; from fail2ban.helpers import PREFER_ENC; print(PREFER_ENC, locale.getpreferredencoding(), (sys.stdout and sys.stdout.encoding))')
|
||||||
# (debug) backend availabilities:
|
# (debug) backend availabilities:
|
||||||
echo 'Backends:'
|
echo 'Backends:'
|
||||||
_debug '- systemd:' python -c 'from fail2ban.server.filtersystemd import FilterSystemd'
|
_debug '- systemd:' python -c 'from fail2ban.server.filtersystemd import FilterSystemd'
|
||||||
|
|
27
ChangeLog
27
ChangeLog
|
@ -7,6 +7,33 @@
|
||||||
Fail2Ban: Changelog
|
Fail2Ban: Changelog
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
ver. 1.1.1-dev-1 (20??/??/??) - development nightly edition
|
||||||
|
-----------
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* `jail.conf`:
|
||||||
|
- default banactions need to be specified in `paths-*.conf` (maintainer level) now
|
||||||
|
- since stock fail2ban includes `paths-debian.conf` by default, banactions are `nftables`
|
||||||
|
(can be overwritten in `jail.local` by user)
|
||||||
|
* `paths-debian.conf`:
|
||||||
|
- default banactions are `nftables`
|
||||||
|
- sshd backend switched to `systemd` (gh-3292)
|
||||||
|
* `action.d/firewallcmd-ipset.conf`:
|
||||||
|
- rename `ipsettype` to `ipsetbackend` (gh-2620), parameter `ipsettype` will be used now to the real set type (gh-3760)
|
||||||
|
* `filter.d/apache-overflows.conf` - consider AH10244: invalid URI path (gh-3778)
|
||||||
|
* `filter.d/postfix.conf` - consider CONNECT and other rejected commands as a valid `_pref` (gh-3800)
|
||||||
|
* `filter.d/recidive.conf` - restore possibility to set jail name in the filter, _jailname is positive now (gh-3769)
|
||||||
|
* `filter.d/roundcube-auth.conf` - improved RE better matching log format of roundcube version 1.4+ (gh-3816)
|
||||||
|
* `filter.d/sshd.conf` - adapted to conform possible new daemon name sshd-session, since OpenSSH 9.8
|
||||||
|
several log messages will be tagged with as originating from a process named "sshd-session" rather than "sshd" (gh-3782)
|
||||||
|
|
||||||
|
### New Features and Enhancements
|
||||||
|
* `action.d/*-ipset.conf`:
|
||||||
|
- parameter `ipsettype` to set type of ipset, e. g. hash:ip, hash:net, etc (gh-3760)
|
||||||
|
* `action.d/firewallcmd-rich-*.conf` - fixed incorrect quoting, disabling port variable expansion
|
||||||
|
by substitution of rich rule (gh-3815)
|
||||||
|
* `filter.d/proxmox.conf` - add support to Proxmox Web GUI (gh-2966)
|
||||||
|
|
||||||
ver. 1.1.0 (2024/04/25) - object-found--norad-59479-cospar-2024-069a--altitude-36267km
|
ver. 1.1.0 (2024/04/25) - object-found--norad-59479-cospar-2024-069a--altitude-36267km
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|
|
@ -29,13 +29,13 @@ and the website: https://www.fail2ban.org
|
||||||
Installation:
|
Installation:
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Fail2Ban is likely already packaged for your Linux distribution and [can installed with a simple command](https://github.com/fail2ban/fail2ban/wiki/How-to-install-fail2ban-packages).
|
Fail2Ban is likely already packaged for your Linux distribution and [can be installed with a simple command](https://github.com/fail2ban/fail2ban/wiki/How-to-install-fail2ban-packages).
|
||||||
|
|
||||||
If your distribution is not listed, you can install from GitHub:
|
If your distribution is not listed, you can install from GitHub:
|
||||||
|
|
||||||
Required:
|
Required:
|
||||||
- [Python >= 3.5](https://www.python.org) or [PyPy3](https://pypy.org)
|
- [Python >= 3.5](https://www.python.org) or [PyPy3](https://pypy.org)
|
||||||
- python-setuptools, python-distutils (or python3-setuptools) for installation from source
|
- python-setuptools (or python3-setuptools) for installation from source
|
||||||
|
|
||||||
Optional:
|
Optional:
|
||||||
- [pyinotify >= 0.8.3](https://github.com/seb-m/pyinotify), may require:
|
- [pyinotify >= 0.8.3](https://github.com/seb-m/pyinotify), may require:
|
||||||
|
@ -52,7 +52,7 @@ To install:
|
||||||
cd fail2ban-master
|
cd fail2ban-master
|
||||||
sudo python setup.py install
|
sudo python setup.py install
|
||||||
|
|
||||||
Alternatively, you can clone the source from GitHub to a directory of Your choice, and do the install from there. Pick the correct branch, for example, master or 0.11
|
Alternatively, you can clone the source from GitHub to a directory of your choice, and do the install from there. Pick the correct branch, for example, master or 0.11
|
||||||
|
|
||||||
git clone https://github.com/fail2ban/fail2ban.git
|
git clone https://github.com/fail2ban/fail2ban.git
|
||||||
cd fail2ban
|
cd fail2ban
|
||||||
|
|
|
@ -80,7 +80,7 @@ actioncheck =
|
||||||
# use my (Shaun's) helper PHP script by commenting out the first #actionban
|
# use my (Shaun's) helper PHP script by commenting out the first #actionban
|
||||||
# line below, uncommenting the second one, and pointing the URL at
|
# line below, uncommenting the second one, and pointing the URL at
|
||||||
# wherever you install the helper script. For the PHP helper script, see
|
# wherever you install the helper script. For the PHP helper script, see
|
||||||
# <https://wiki.shaunc.com/wikka.php?wakka=ReportingToAbuseIPDBWithFail2Ban>
|
# <https://github.com/parseword/fail2ban-abuseipdb/>
|
||||||
#
|
#
|
||||||
# Tags: See jail.conf(5) man page
|
# Tags: See jail.conf(5) man page
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
|
# bypass reporting of restored (already reported) tickets:
|
||||||
|
norestored = 1
|
||||||
|
|
||||||
# Option: actionstart
|
# Option: actionstart
|
||||||
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
|
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
|
|
|
@ -18,24 +18,24 @@ before = firewallcmd-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
actionstart = <ipstype_<ipsettype>/actionstart>
|
actionstart = <ipsbackend_<ipsetbackend>/actionstart>
|
||||||
firewall-cmd --direct --add-rule <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype>
|
firewall-cmd --direct --add-rule <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype>
|
||||||
|
|
||||||
actionflush = <ipstype_<ipsettype>/actionflush>
|
actionflush = <ipsbackend_<ipsetbackend>/actionflush>
|
||||||
|
|
||||||
actionstop = firewall-cmd --direct --remove-rule <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype>
|
actionstop = firewall-cmd --direct --remove-rule <family> filter <chain> 0 <actiontype> -m set --match-set <ipmset> src -j <blocktype>
|
||||||
<actionflush>
|
<actionflush>
|
||||||
<ipstype_<ipsettype>/actionstop>
|
<ipsbackend_<ipsetbackend>/actionstop>
|
||||||
|
|
||||||
actionban = <ipstype_<ipsettype>/actionban>
|
actionban = <ipsbackend_<ipsetbackend>/actionban>
|
||||||
|
|
||||||
# actionprolong = %(actionban)s
|
# actionprolong = %(actionban)s
|
||||||
|
|
||||||
actionunban = <ipstype_<ipsettype>/actionunban>
|
actionunban = <ipsbackend_<ipsetbackend>/actionunban>
|
||||||
|
|
||||||
[ipstype_ipset]
|
[ipsbackend_ipset]
|
||||||
|
|
||||||
actionstart = ipset -exist create <ipmset> hash:ip timeout <default-ipsettime> maxelem <maxelem> <familyopt>
|
actionstart = ipset -exist create <ipmset> <ipsettype> timeout <default-ipsettime> maxelem <maxelem> <familyopt>
|
||||||
|
|
||||||
actionflush = ipset flush <ipmset>
|
actionflush = ipset flush <ipmset>
|
||||||
|
|
||||||
|
@ -45,9 +45,9 @@ actionban = ipset -exist add <ipmset> <ip> timeout <ipsettime>
|
||||||
|
|
||||||
actionunban = ipset -exist del <ipmset> <ip>
|
actionunban = ipset -exist del <ipmset> <ip>
|
||||||
|
|
||||||
[ipstype_firewalld]
|
[ipsbackend_firewalld]
|
||||||
|
|
||||||
actionstart = firewall-cmd --direct --new-ipset=<ipmset> --type=hash:ip --option=timeout=<default-ipsettime> --option=maxelem=<maxelem> <firewalld_familyopt>
|
actionstart = firewall-cmd --direct --new-ipset=<ipmset> --type=<ipsettype> --option=timeout=<default-ipsettime> --option=maxelem=<maxelem> <firewalld_familyopt>
|
||||||
|
|
||||||
# TODO: there doesn't seem to be an explicit way to invoke the ipset flush function using firewall-cmd
|
# TODO: there doesn't seem to be an explicit way to invoke the ipset flush function using firewall-cmd
|
||||||
actionflush =
|
actionflush =
|
||||||
|
@ -60,6 +60,11 @@ actionunban = firewall-cmd --ipset=<ipmset> --remove-entry=<ip>
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
|
# Option: ipsettype
|
||||||
|
# Notes: specifies type of set, see `man --pager='less -p "^SET TYPES"' ipset` for details
|
||||||
|
# Values: hash:ip, hash:net, etc... Default: hash:ip
|
||||||
|
ipsettype = hash:ip
|
||||||
|
|
||||||
# Option: chain
|
# Option: chain
|
||||||
# Notes specifies the iptables chain to which the fail2ban rules should be
|
# Notes specifies the iptables chain to which the fail2ban rules should be
|
||||||
# added
|
# added
|
||||||
|
@ -87,11 +92,11 @@ maxelem = 65536
|
||||||
# banaction = %(known/banaction)s[ipsettime='<timeout-bantime>']
|
# banaction = %(known/banaction)s[ipsettime='<timeout-bantime>']
|
||||||
timeout-bantime = $([ "<bantime>" -le 2147483 ] && echo "<bantime>" || echo 0)
|
timeout-bantime = $([ "<bantime>" -le 2147483 ] && echo "<bantime>" || echo 0)
|
||||||
|
|
||||||
# Option: ipsettype
|
# Option: ipsetbackend
|
||||||
# Notes.: defines type of ipset used for match-set (firewalld or ipset)
|
# Notes.: defines the backend of ipset used for match-set (firewalld or ipset)
|
||||||
# Values: firewalld or ipset
|
# Values: firewalld or ipset
|
||||||
# Default: ipset
|
# Default: ipset
|
||||||
ipsettype = ipset
|
ipsetbackend = ipset
|
||||||
|
|
||||||
# Option: actiontype
|
# Option: actiontype
|
||||||
# Notes.: defines additions to the blocking rule
|
# Notes.: defines additions to the blocking rule
|
||||||
|
|
|
@ -35,7 +35,7 @@ actioncheck =
|
||||||
#
|
#
|
||||||
# Because rich rules can only handle single or a range of ports we must split ports and execute the command for each port. Ports can be single and ranges separated by a comma or space for an example: http, https, 22-60, 18 smtp
|
# Because rich rules can only handle single or a range of ports we must split ports and execute the command for each port. Ports can be single and ranges separated by a comma or space for an example: http, https, 22-60, 18 smtp
|
||||||
|
|
||||||
fwcmd_rich_rule = rule family='<family>' source address='<ip>' port port='$p' protocol='<protocol>' %(rich-suffix)s
|
fwcmd_rich_rule = rule family=\"<family>\" source address=\"<ip>\" port port=\"$p\" protocol=\"<protocol>\" %(rich-suffix)s
|
||||||
|
|
||||||
actionban = ports="<port>"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="%(fwcmd_rich_rule)s"; done
|
actionban = ports="<port>"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="%(fwcmd_rich_rule)s"; done
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ before = iptables.conf
|
||||||
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
|
# Notes.: command executed on demand at the first ban (or at the start of Fail2Ban if actionstart_on_demand is set to false).
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstart = ipset -exist create <ipmset> hash:ip timeout <default-ipsettime> maxelem <maxelem> <familyopt>
|
actionstart = ipset -exist create <ipmset> <ipsettype> timeout <default-ipsettime> maxelem <maxelem> <familyopt>
|
||||||
<_ipt_add_rules>
|
<_ipt_add_rules>
|
||||||
|
|
||||||
# Option: actionflush
|
# Option: actionflush
|
||||||
|
@ -66,6 +66,11 @@ rule-jump = -m set --match-set <ipmset> src -j <blocktype>
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
|
# Option: ipsettype
|
||||||
|
# Notes: specifies type of set, see `man --pager='less -p "^SET TYPES"' ipset` for details
|
||||||
|
# Values: hash:ip, hash:net, etc... Default: hash:ip
|
||||||
|
ipsettype = hash:ip
|
||||||
|
|
||||||
# Option: default-ipsettime
|
# Option: default-ipsettime
|
||||||
# Notes: specifies default timeout in seconds (handled default ipset timeout only)
|
# Notes: specifies default timeout in seconds (handled default ipset timeout only)
|
||||||
# Values: [ NUM ] Default: 0 (no timeout, managed by fail2ban by unban)
|
# Values: [ NUM ] Default: 0 (no timeout, managed by fail2ban by unban)
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstart = if ! ipset -quiet -name list f2b-<name> >/dev/null;
|
actionstart = if ! ipset -quiet -name list f2b-<name> >/dev/null;
|
||||||
then ipset -quiet -exist create f2b-<name> hash:ip timeout <default-ipsettime> maxelem <maxelem>;
|
then ipset -quiet -exist create f2b-<name> <ipsettype> timeout <default-ipsettime> maxelem <maxelem>;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Option: actionstop
|
# Option: actionstop
|
||||||
|
@ -94,6 +94,11 @@ timeout-bantime = $([ "<bantime>" -le 2147483 ] && echo "<bantime>" || echo 0)
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
|
# Option: ipsettype
|
||||||
|
# Notes: specifies type of set, see `man --pager='less -p "^SET TYPES"' ipset` for details
|
||||||
|
# Values: hash:ip, hash:net, etc... Default: hash:ip
|
||||||
|
ipsettype = hash:ip
|
||||||
|
|
||||||
# Option: maxelem
|
# Option: maxelem
|
||||||
# Notes: maximal number of elements which can be stored in the ipset
|
# Notes: maximal number of elements which can be stored in the ipset
|
||||||
# You may want to increase this for long-duration/high-volume jails
|
# You may want to increase this for long-duration/high-volume jails
|
||||||
|
|
|
@ -8,7 +8,7 @@ before = apache-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
failregex = ^%(_apache_error_client)s (?:(?:AH001[23][456]: )?Invalid (method|URI) in request\b|(?:AH00565: )?request failed: URI too long \(longer than \d+\)|request failed: erroneous characters after protocol string:|(?:AH00566: )?request failed: invalid characters in URI\b)
|
failregex = ^%(_apache_error_client)s (?:(?:AH(?:001[23][456]|10244): )?[Ii]nvalid (method|URI)\b|(?:AH00565: )?request failed: URI too long \(longer than \d+\)|request failed: erroneous characters after protocol string:|(?:AH00566: )?request failed: invalid characters in URI\b)
|
||||||
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ before = common.conf
|
||||||
|
|
||||||
_daemon = postfix(-\w+)?/[^/\[:\s]+(?:/smtp[ds])?
|
_daemon = postfix(-\w+)?/[^/\[:\s]+(?:/smtp[ds])?
|
||||||
_port = (?::\d+)?
|
_port = (?::\d+)?
|
||||||
_pref = [A-Z]{4}
|
_pref = [A-Z]{4,}
|
||||||
|
|
||||||
prefregex = ^%(__prefix_line)s<mdpr-<mode>> <F-CONTENT>.+</F-CONTENT>$
|
prefregex = ^%(__prefix_line)s<mdpr-<mode>> <F-CONTENT>.+</F-CONTENT>$
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Fail2Ban filter for Proxmox Web GUI
|
||||||
|
#
|
||||||
|
# Jail example:
|
||||||
|
# [proxmox]
|
||||||
|
# enabled = true
|
||||||
|
# port = https,http,8006
|
||||||
|
# filter = proxmox
|
||||||
|
# logpath = /var/log/daemon.log
|
||||||
|
# maxretry = 3
|
||||||
|
# # 1 hour
|
||||||
|
# bantime = 3600
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
_daemon = pvedaemon
|
||||||
|
|
||||||
|
failregex = ^\s*\S+ %(_daemon)s\[\d+\]: authentication failure; rhost=<ADDR> user=<F-USER>\S+</F-USER>
|
||||||
|
|
||||||
|
ignoreregex =
|
||||||
|
|
|
@ -24,14 +24,15 @@ before = common.conf
|
||||||
_daemon = (?:fail2ban(?:-server|\.actions)\s*)
|
_daemon = (?:fail2ban(?:-server|\.actions)\s*)
|
||||||
|
|
||||||
# The name of the jail that this filter is used for. In jail.conf, name the jail using
|
# The name of the jail that this filter is used for. In jail.conf, name the jail using
|
||||||
# this filter 'recidive', or supply another name with `filter = recidive[_jailname="jail"]`
|
# this filter 'recidive', or supply another name with `filter = recidive[_jailname="jail"]`,
|
||||||
_jailname = recidive
|
# default all jails excepting recidive
|
||||||
|
_jailname = (?!recidive\])[^\]]*
|
||||||
|
|
||||||
failregex = ^%(__prefix_line)s(?:\s*fail2ban\.actions\s*%(__pid_re)s?:\s+)?NOTICE\s+\[(?!%(_jailname)s\])(?:.*)\]\s+Ban\s+<HOST>\s*$
|
failregex = ^%(__prefix_line)s(?:\s*fail2ban\.actions\s*%(__pid_re)s?:\s+)?NOTICE\s+\[<_jailname>\]\s+Ban\s+<HOST>
|
||||||
|
|
||||||
[lt_short]
|
[lt_short]
|
||||||
_daemon = (?:fail2ban(?:-server|\.actions)?\s*)
|
_daemon = (?:fail2ban(?:-server|\.actions)?\s*)
|
||||||
failregex = ^%(__prefix_line)s(?:\s*fail2ban(?:\.actions)?\s*%(__pid_re)s?:\s+)?(?:NOTICE\s+)?\[(?!%(_jailname)s\])(?:.*)\]\s+Ban\s+<HOST>\s*$
|
failregex = ^%(__prefix_line)s(?:\s*fail2ban(?:\.actions)?\s*%(__pid_re)s?:\s+)?(?:NOTICE\s+)?\[<_jailname>\]\s+Ban\s+<HOST>
|
||||||
|
|
||||||
[lt_journal]
|
[lt_journal]
|
||||||
_daemon = <lt_short/_daemon>
|
_daemon = <lt_short/_daemon>
|
||||||
|
|
|
@ -13,10 +13,9 @@ before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
prefregex = ^\s*(\[\])?(%(__hostname)s\s*(?:roundcube(?:\[(\d*)\])?:)?\s*(<[\w]+>)? IMAP Error)?: <F-CONTENT>.+</F-CONTENT>$
|
prefregex = ^\s*(\[\])?(%(__hostname)s\s*(?:roundcube(?:\[(\d*)\])?:)?\s*(<[\w]+>)? IMAP Error)?: (?:<[\w]+> )?<F-CONTENT>.+</F-CONTENT>$
|
||||||
|
|
||||||
failregex = ^(?:FAILED login|Login failed) for <F-USER>.*</F-USER> from <HOST>(?:(?:\([^\)]*\))?\. (?:(?! from ).)*(?: user=(?P=user))? in \S+\.php on line \d+ \(\S+ \S+\))?$
|
failregex = ^(?:Login failed|(?i:Failed) login) for <F-USER>(?:(?P<simple>\S+)|.*)</F-USER> (?:against \S+ )?from <ADDR>(?:(?:\([^\)]*\))?\.(?! from ) (?(simple)(?:\S+(?! from ) )*|(?:(?! from ).)*(?: user=(?P=user))? )in \S+\.php on line \d+| in session \w+)?(?: \([^\)]*\))?$
|
||||||
^(?:<[\w]+> )?Failed login for <F-USER>.*</F-USER> from <HOST> in session \w+( \(error: \d\))?$
|
|
||||||
|
|
||||||
ignoreregex = Could not connect to .* Connection refused
|
ignoreregex = Could not connect to .* Connection refused
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ before = common.conf
|
||||||
|
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
|
|
||||||
_daemon = sshd
|
_daemon = sshd(?:-session)?
|
||||||
|
|
||||||
# optional prefix (logged from several ssh versions) like "error: ", "error: PAM: " or "fatal: "
|
# optional prefix (logged from several ssh versions) like "error: ", "error: PAM: " or "fatal: "
|
||||||
__pref = (?:(?:error|fatal): (?:PAM: )?)?
|
__pref = (?:(?:error|fatal): (?:PAM: )?)?
|
||||||
|
|
|
@ -990,3 +990,6 @@ logpath = /var/log/monitorix-httpd
|
||||||
port = 1080
|
port = 1080
|
||||||
logpath = %(syslog_daemon)s
|
logpath = %(syslog_daemon)s
|
||||||
|
|
||||||
|
[proxmox]
|
||||||
|
port = https,http,8006
|
||||||
|
logpath = /var/log/daemon.log
|
||||||
|
|
|
@ -47,12 +47,9 @@ copyright = u'2014'
|
||||||
#
|
#
|
||||||
|
|
||||||
from fail2ban.version import version as fail2ban_version
|
from fail2ban.version import version as fail2ban_version
|
||||||
from distutils.version import LooseVersion
|
|
||||||
|
|
||||||
fail2ban_loose_version = LooseVersion(fail2ban_version)
|
|
||||||
|
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = ".".join(str(_) for _ in fail2ban_loose_version.version[:2])
|
version = ".".join(str(_) for _ in fail2ban_version.split(".")[:2])
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = fail2ban_version
|
release = fail2ban_version
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,10 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2013- Yaroslav Halchenko"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2013- Yaroslav Halchenko"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
from ..exceptions import UnknownJailException, DuplicateJailException
|
from ..exceptions import UnknownJailException, DuplicateJailException
|
||||||
from ..helpers import getLogger, logging
|
from ..helpers import getLogger, logging, PREFER_ENC
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
@ -36,6 +38,11 @@ logSys = getLogger(__name__)
|
||||||
|
|
||||||
class Beautifier:
|
class Beautifier:
|
||||||
|
|
||||||
|
stdoutEnc = PREFER_ENC
|
||||||
|
if sys.stdout and sys.stdout.encoding is not None:
|
||||||
|
stdoutEnc = sys.stdout.encoding
|
||||||
|
encUtf = 1 if stdoutEnc.lower() == 'utf-8' else 0
|
||||||
|
|
||||||
def __init__(self, cmd = None):
|
def __init__(self, cmd = None):
|
||||||
self.__inputCmd = cmd
|
self.__inputCmd = cmd
|
||||||
|
|
||||||
|
@ -104,7 +111,11 @@ class Beautifier:
|
||||||
jail_stat(j, " " if i == len(jstat) else " | ")
|
jail_stat(j, " " if i == len(jstat) else " | ")
|
||||||
msg = "\n".join(msg)
|
msg = "\n".join(msg)
|
||||||
elif inC[0:1] == ['stats'] or inC[0:1] == ['statistics']:
|
elif inC[0:1] == ['stats'] or inC[0:1] == ['statistics']:
|
||||||
def _statstable(response):
|
chrTable = [
|
||||||
|
['|', '-', '|', 'x', 'x', '-', '|', '-'], ## ascii
|
||||||
|
["\u2551", "\u2550", "\u255F", "\u256B", "\u256C", "\u2569", "\u2502", "\u2500"] ## utf-8
|
||||||
|
];
|
||||||
|
def _statstable(response, ct):
|
||||||
tophead = ["Jail", "Backend", "Filter", "Actions"]
|
tophead = ["Jail", "Backend", "Filter", "Actions"]
|
||||||
headers = ["", "", "cur", "tot", "cur", "tot"]
|
headers = ["", "", "cur", "tot", "cur", "tot"]
|
||||||
minlens = [8, 8, 3, 3, 3, 3]
|
minlens = [8, 8, 3, 3, 3, 3]
|
||||||
|
@ -120,29 +131,31 @@ class Beautifier:
|
||||||
f = "%%%ds" if ralign[i] else "%%-%ds"
|
f = "%%%ds" if ralign[i] else "%%-%ds"
|
||||||
rfmt.append(f % lens[i])
|
rfmt.append(f % lens[i])
|
||||||
hfmt.append(f % lens[i])
|
hfmt.append(f % lens[i])
|
||||||
rfmt = [rfmt[0], rfmt[1], "%s \u2502 %s" % (rfmt[2], rfmt[3]), "%s \u2502 %s" % (rfmt[4], rfmt[5])]
|
rfmt = [rfmt[0], rfmt[1], "%s %s %s" % (rfmt[2], ct[6], rfmt[3]), "%s %s %s" % (rfmt[4], ct[6], rfmt[5])]
|
||||||
hfmt = [hfmt[0], hfmt[1], "%s \u2502 %s" % (hfmt[2], hfmt[3]), "%s \u2502 %s" % (hfmt[4], hfmt[5])]
|
hfmt = [hfmt[0], hfmt[1], "%s %s %s" % (hfmt[2], ct[6], hfmt[3]), "%s %s %s" % (hfmt[4], ct[6], hfmt[5])]
|
||||||
tlens = [lens[0], lens[1], 3 + lens[2] + lens[3], 3 + lens[4] + lens[5]]
|
tlens = [lens[0], lens[1], 3 + lens[2] + lens[3], 3 + lens[4] + lens[5]]
|
||||||
tfmt = [hfmt[0], hfmt[1], "%%-%ds" % (tlens[2],), "%%-%ds" % (tlens[3],)]
|
tfmt = [hfmt[0], hfmt[1], "%%-%ds" % (tlens[2],), "%%-%ds" % (tlens[3],)]
|
||||||
tsep = tfmt[0:2]
|
tsep = tfmt[0:2]
|
||||||
rfmt = " \u2551 ".join(rfmt)
|
rfmt = (" "+ct[0]+" ").join(rfmt)
|
||||||
hfmt = " \u2551 ".join(hfmt)
|
hfmt = (" "+ct[0]+" ").join(hfmt)
|
||||||
tfmt = " \u2551 ".join(tfmt)
|
tfmt = (" "+ct[0]+" ").join(tfmt)
|
||||||
tsep = " \u2551 ".join(tsep)
|
tsep = (" "+ct[0]+" ").join(tsep)
|
||||||
separator = ((tsep % tuple(tophead[0:2])) + " \u255F\u2500" +
|
separator = ((tsep % tuple(tophead[0:2])) + " "+ct[2]+ct[7] +
|
||||||
("\u2500\u256B\u2500".join(['\u2500' * n for n in tlens[2:]])) + '\u2500')
|
((ct[7]+ct[3]+ct[7]).join([ct[7] * n for n in tlens[2:]])) + ct[7])
|
||||||
ret = []
|
ret = []
|
||||||
ret.append(tfmt % tuple(["", ""]+tophead[2:]))
|
ret.append(" "+tfmt % tuple(["", ""]+tophead[2:]))
|
||||||
ret.append(separator)
|
ret.append(" "+separator)
|
||||||
ret.append(hfmt % tuple(headers))
|
ret.append(" "+hfmt % tuple(headers))
|
||||||
separator = "\u2550\u256C\u2550".join(['\u2550' * n for n in tlens]) + '\u2550'
|
separator = (ct[1]+ct[4]+ct[1]).join([ct[1] * n for n in tlens]) + ct[1]
|
||||||
ret.append(separator)
|
ret.append(ct[1]+separator)
|
||||||
for row in rows:
|
for row in rows:
|
||||||
ret.append(rfmt % tuple(row))
|
ret.append(" "+rfmt % tuple(row))
|
||||||
separator = "\u2550\u2569\u2550".join(['\u2550' * n for n in tlens]) + '\u2550'
|
separator = (ct[1]+ct[5]+ct[1]).join([ct[1] * n for n in tlens]) + ct[1]
|
||||||
ret.append(separator)
|
ret.append(ct[1]+separator)
|
||||||
return ret
|
return ret
|
||||||
msg = "\n".join(_statstable(response))
|
if not response:
|
||||||
|
return "No jails found."
|
||||||
|
msg = "\n".join(_statstable(response, chrTable[self.encUtf]))
|
||||||
elif len(inC) < 2:
|
elif len(inC) < 2:
|
||||||
pass # to few cmd args for below
|
pass # to few cmd args for below
|
||||||
elif inC[1] == "syslogsocket":
|
elif inC[1] == "syslogsocket":
|
||||||
|
|
|
@ -40,6 +40,14 @@ except:
|
||||||
_libcap = None
|
_libcap = None
|
||||||
|
|
||||||
|
|
||||||
|
# some modules (like pyinotify, see #3487) may have dependency to asyncore, so ensure we've a path
|
||||||
|
# to compat folder, otherwise python 3.12+ could miss them:
|
||||||
|
def __extend_compat_path():
|
||||||
|
cp = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'compat')
|
||||||
|
if cp not in sys.path:
|
||||||
|
sys.path.append(cp)
|
||||||
|
__extend_compat_path()
|
||||||
|
|
||||||
PREFER_ENC = locale.getpreferredencoding()
|
PREFER_ENC = locale.getpreferredencoding()
|
||||||
# correct preferred encoding if lang not set in environment:
|
# correct preferred encoding if lang not set in environment:
|
||||||
if PREFER_ENC.startswith('ANSI_'): # pragma: no cover
|
if PREFER_ENC.startswith('ANSI_'): # pragma: no cover
|
||||||
|
|
|
@ -25,14 +25,6 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
from pickle import dumps, loads, HIGHEST_PROTOCOL
|
from pickle import dumps, loads, HIGHEST_PROTOCOL
|
||||||
try:
|
|
||||||
import asynchat
|
|
||||||
except ImportError:
|
|
||||||
from ..compat import asynchat
|
|
||||||
try:
|
|
||||||
import asyncore
|
|
||||||
except ImportError:
|
|
||||||
from ..compat import asyncore
|
|
||||||
import errno
|
import errno
|
||||||
import fcntl
|
import fcntl
|
||||||
import os
|
import os
|
||||||
|
@ -45,6 +37,13 @@ from .utils import Utils
|
||||||
from ..protocol import CSPROTO
|
from ..protocol import CSPROTO
|
||||||
from ..helpers import logging, getLogger, formatExceptionInfo
|
from ..helpers import logging, getLogger, formatExceptionInfo
|
||||||
|
|
||||||
|
# load asyncore and asynchat after helper to ensure we've a path to compat folder:
|
||||||
|
import asynchat
|
||||||
|
if asynchat.asyncore:
|
||||||
|
asyncore = asynchat.asyncore
|
||||||
|
else: # pragma: no cover - normally unreachable
|
||||||
|
import asyncore
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -24,22 +24,18 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2012 Lee Clemens, 2012 Y
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from distutils.version import LooseVersion
|
|
||||||
import os
|
import os
|
||||||
from os.path import dirname, sep as pathsep
|
from os.path import dirname, sep as pathsep
|
||||||
|
|
||||||
import pyinotify
|
|
||||||
|
|
||||||
from .failmanager import FailManagerEmpty
|
from .failmanager import FailManagerEmpty
|
||||||
from .filter import FileFilter
|
from .filter import FileFilter
|
||||||
from .mytime import MyTime, time
|
from .mytime import MyTime, time
|
||||||
from .utils import Utils
|
from .utils import Utils
|
||||||
from ..helpers import getLogger
|
from ..helpers import getLogger
|
||||||
|
|
||||||
|
# pyinotify may have dependency to asyncore, so import it after helper to ensure
|
||||||
if not hasattr(pyinotify, '__version__') \
|
# we've a path to compat folder:
|
||||||
or LooseVersion(pyinotify.__version__) < '0.8.3': # pragma: no cover
|
import pyinotify
|
||||||
raise ImportError("Fail2Ban requires pyinotify >= 0.8.3")
|
|
||||||
|
|
||||||
# Verify that pyinotify is functional on this system
|
# Verify that pyinotify is functional on this system
|
||||||
# Even though imports -- might be dysfunctional, e.g. as on kfreebsd
|
# Even though imports -- might be dysfunctional, e.g. as on kfreebsd
|
||||||
|
|
|
@ -24,11 +24,8 @@ __license__ = "GPL"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from distutils.version import LooseVersion
|
|
||||||
|
|
||||||
from systemd import journal
|
from systemd import journal
|
||||||
if LooseVersion(getattr(journal, '__version__', "0")) < '204':
|
|
||||||
raise ImportError("Fail2Ban requires systemd >= 204")
|
|
||||||
|
|
||||||
from .failmanager import FailManagerEmpty
|
from .failmanager import FailManagerEmpty
|
||||||
from .filter import JournalFilter, Filter
|
from .filter import JournalFilter, Filter
|
||||||
|
|
|
@ -34,6 +34,7 @@ class BeautifierTest(unittest.TestCase):
|
||||||
""" Call before every test case """
|
""" Call before every test case """
|
||||||
super(BeautifierTest, self).setUp()
|
super(BeautifierTest, self).setUp()
|
||||||
self.b = Beautifier()
|
self.b = Beautifier()
|
||||||
|
self.b.encUtf = 0; ## we prefer ascii in test suite (see #3750)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
""" Call after every test case """
|
""" Call after every test case """
|
||||||
|
@ -170,22 +171,25 @@ class BeautifierTest(unittest.TestCase):
|
||||||
|
|
||||||
def testStatusStats(self):
|
def testStatusStats(self):
|
||||||
self.b.setInputCmd(["stats"])
|
self.b.setInputCmd(["stats"])
|
||||||
|
## no jails:
|
||||||
|
self.assertEqual(self.b.beautify({}), "No jails found.")
|
||||||
|
## 3 jails:
|
||||||
response = {
|
response = {
|
||||||
"ssh": ["systemd", (3, 6), (12, 24)],
|
"ssh": ["systemd", (3, 6), (12, 24)],
|
||||||
"exim4": ["pyinotify", (6, 12), (20, 20)],
|
"exim4": ["pyinotify", (6, 12), (20, 20)],
|
||||||
"jail-with-long-name": ["polling", (0, 0), (0, 0)]
|
"jail-with-long-name": ["polling", (0, 0), (0, 0)]
|
||||||
}
|
}
|
||||||
output = (""
|
output = (""
|
||||||
+ " ? ? Filter ? Actions \n"
|
+ " | | Filter | Actions \n"
|
||||||
+ "Jail ? Backend ????????????????????????\n"
|
+ " Jail | Backend |-----------x-----------\n"
|
||||||
+ " ? ? cur ? tot ? cur ? tot\n"
|
+ " | | cur | tot | cur | tot\n"
|
||||||
+ "????????????????????????????????????????????????????????\n"
|
+ "---------------------x-----------x-----------x-----------\n"
|
||||||
+ "ssh ? systemd ? 3 ? 6 ? 12 ? 24\n"
|
+ " ssh | systemd | 3 | 6 | 12 | 24\n"
|
||||||
+ "exim4 ? pyinotify ? 6 ? 12 ? 20 ? 20\n"
|
+ " exim4 | pyinotify | 6 | 12 | 20 | 20\n"
|
||||||
+ "jail-with-long-name ? polling ? 0 ? 0 ? 0 ? 0\n"
|
+ " jail-with-long-name | polling | 0 | 0 | 0 | 0\n"
|
||||||
+ "????????????????????????????????????????????????????????"
|
+ "---------------------------------------------------------"
|
||||||
)
|
)
|
||||||
response = self.b.beautify(response).encode('ascii', 'replace').decode('ascii')
|
response = self.b.beautify(response)
|
||||||
self.assertEqual(response, output)
|
self.assertEqual(response, output)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ before = ../../../../config/filter.d/common.conf
|
||||||
|
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
|
|
||||||
_daemon = sshd
|
_daemon = sshd(?:-session)?
|
||||||
|
|
||||||
# optional prefix (logged from several ssh versions) like "error: ", "error: PAM: " or "fatal: "
|
# optional prefix (logged from several ssh versions) like "error: ", "error: PAM: " or "fatal: "
|
||||||
__pref = (?:(?:error|fatal): (?:PAM: )?)?
|
__pref = (?:(?:error|fatal): (?:PAM: )?)?
|
||||||
|
|
|
@ -25,3 +25,6 @@
|
||||||
# https://issues.apache.org/bugzilla/show_bug.cgi?id=46123
|
# https://issues.apache.org/bugzilla/show_bug.cgi?id=46123
|
||||||
# failJSON: { "time": "2008-10-29T11:55:14", "match": true , "host": "127.0.0.1" }
|
# failJSON: { "time": "2008-10-29T11:55:14", "match": true , "host": "127.0.0.1" }
|
||||||
[Wed Oct 29 11:55:14 2008] [error] [client 127.0.0.1] Invalid method in request \x16\x03\x01 - possible attempt to establish SSL connection when the server isn't expecting it
|
[Wed Oct 29 11:55:14 2008] [error] [client 127.0.0.1] Invalid method in request \x16\x03\x01 - possible attempt to establish SSL connection when the server isn't expecting it
|
||||||
|
|
||||||
|
# failJSON: { "time": "2024-06-26T05:20:26", "match": true , "host": "192.0.2.39", "desc": "AH10244: invalid URI path, gh-3778" }
|
||||||
|
[Wed Jun 26 05:20:26.182799 2024] [core:error] [pid 2928] [client 192.0.2.39:37924] AH10244: invalid URI path (/cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh)
|
||||||
|
|
|
@ -70,6 +70,9 @@ Jun 12 08:58:35 xxx postfix/smtpd[13533]: improper command pipelining after AUTH
|
||||||
# failJSON: { "time": "2005-05-05T15:51:11", "match": true , "host": "216.245.194.173", "desc": "postfix postscreen / gh-1764" }
|
# failJSON: { "time": "2005-05-05T15:51:11", "match": true , "host": "216.245.194.173", "desc": "postfix postscreen / gh-1764" }
|
||||||
May 5 15:51:11 xxx postfix/postscreen[1148]: NOQUEUE: reject: RCPT from [216.245.194.173]:60591: 550 5.7.1 Service unavailable; client [216.245.194.173] blocked using rbl.example.com; from=<spammer@example.com>, to=<goodguy@example.com>, proto=ESMTP, helo=<badguy.example.com>
|
May 5 15:51:11 xxx postfix/postscreen[1148]: NOQUEUE: reject: RCPT from [216.245.194.173]:60591: 550 5.7.1 Service unavailable; client [216.245.194.173] blocked using rbl.example.com; from=<spammer@example.com>, to=<goodguy@example.com>, proto=ESMTP, helo=<badguy.example.com>
|
||||||
|
|
||||||
|
# failJSON: { "time": "2005-06-01T19:00:55", "match": true , "host": "192.0.2.114", "desc": "postfix client restriction / gh-3800" }
|
||||||
|
Jun 1 19:00:55 mail postfix/smtpd[7749]: NOQUEUE: reject: CONNECT from unknown[192.0.2.114]: 450 4.7.25 Client host rejected: cannot find your hostname, [178.215.236.114]; proto=SMTP
|
||||||
|
|
||||||
# failJSON: { "time": "2005-06-03T06:25:43", "match": true , "host": "192.0.2.11", "desc": "too many errors / gh-2439" }
|
# failJSON: { "time": "2005-06-03T06:25:43", "match": true , "host": "192.0.2.11", "desc": "too many errors / gh-2439" }
|
||||||
Jun 3 06:25:43 srv postfix/smtpd[29306]: too many errors after RCPT from example.com[192.0.2.11]
|
Jun 3 06:25:43 srv postfix/smtpd[29306]: too many errors after RCPT from example.com[192.0.2.11]
|
||||||
|
|
||||||
|
@ -148,6 +151,9 @@ Jan 14 16:18:16 xxx postfix/smtpd[14933]: warning: host[192.0.2.5]: SASL CRAM-MD
|
||||||
# failJSON: { "time": "2005-01-14T16:18:16", "match": true , "host": "192.0.2.5", "desc": "aggressive only" }
|
# failJSON: { "time": "2005-01-14T16:18:16", "match": true , "host": "192.0.2.5", "desc": "aggressive only" }
|
||||||
Jan 14 16:18:16 xxx postfix/smtpd[14933]: warning: host[192.0.2.5]: SASL CRAM-MD5 authentication failed: Invalid authentication mechanism
|
Jan 14 16:18:16 xxx postfix/smtpd[14933]: warning: host[192.0.2.5]: SASL CRAM-MD5 authentication failed: Invalid authentication mechanism
|
||||||
|
|
||||||
|
# failJSON: { "time": "2004-11-04T09:11:01", "match": true , "host": "192.0.2.152", "desc": "reason unavailable" }
|
||||||
|
Nov 4 09:11:01 mail postfix/smtpd[1234]: warning: unknown[192.0.2.152]: SASL LOGIN authentication failed: (reason unavailable), sasl_username=admin
|
||||||
|
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
# Test-cases of postfix DDOS mode:
|
# Test-cases of postfix DDOS mode:
|
||||||
# ---------------------------------------
|
# ---------------------------------------
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
# failJSON: { "time": "2005-03-08T09:37:44", "match": true , "host": "192.0.2.123" }
|
||||||
|
Mar 8 09:37:44 HOSTNAME pvedaemon[12021]: authentication failure; rhost=192.0.2.123 user=root@pam msg=Authentication failure
|
||||||
|
|
||||||
|
# failJSON: { "time": "2005-03-09T03:32:27", "match": true , "host": "192.0.2.124" }
|
||||||
|
Mar 9 03:32:27 HOSTNAME pvedaemon[8961]: authentication failure; rhost=192.0.2.124 user=jose@pve msg=invalid credentials
|
|
@ -54,3 +54,8 @@ Jul 11 03:06:37 myhostname roundcube: IMAP Error: Login failed for admin from 12
|
||||||
|
|
||||||
# failJSON: { "time": "2005-05-19T06:07:48", "match": true , "host": "192.0.2.1", "desc": "Roundcube logged to journald instead to a local file."}
|
# failJSON: { "time": "2005-05-19T06:07:48", "match": true , "host": "192.0.2.1", "desc": "Roundcube logged to journald instead to a local file."}
|
||||||
May 19 06:07:48 server roundcube[21296]: <crk9n97i> IMAP Error: Login failed for test from 192.0.2.1. AUTHENTICATE PLAIN: Authentication failed. in /usr/share/php5/Roundcube/rcube_imap.php on line 193 (POST /mail/?_task=login&_action=login)
|
May 19 06:07:48 server roundcube[21296]: <crk9n97i> IMAP Error: Login failed for test from 192.0.2.1. AUTHENTICATE PLAIN: Authentication failed. in /usr/share/php5/Roundcube/rcube_imap.php on line 193 (POST /mail/?_task=login&_action=login)
|
||||||
|
|
||||||
|
# Roundcube 1.5.0 (/var/log/roundcubemail/errors)
|
||||||
|
# failJSON: { "time": "2014-12-30T19:02:34", "match": true , "host": "1.2.3.4" }
|
||||||
|
[30-Dec-2014 13:02:34 -0500]: <3z506z6r> IMAP Error: Login failed for admin@example.com against localhost from 1.2.3.4. AUTHENTICATE PLAIN: Authentication failed. in /docroot/path/program/lib/Roundcube/rcube_imap.php on line 221 (POST /?_task=login?_task=login&_action=login)
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,9 @@ Feb 25 14:34:10 belka sshd[31603]: Failed password for invalid user ROOT from aa
|
||||||
# failJSON: { "time": "2005-02-25T14:34:11", "match": true , "host": "aaaa:bbbb:cccc:1234::1:1" }
|
# failJSON: { "time": "2005-02-25T14:34:11", "match": true , "host": "aaaa:bbbb:cccc:1234::1:1" }
|
||||||
Feb 25 14:34:11 belka sshd[31603]: Failed password for invalid user ROOT from aaaa:bbbb:cccc:1234::1:1
|
Feb 25 14:34:11 belka sshd[31603]: Failed password for invalid user ROOT from aaaa:bbbb:cccc:1234::1:1
|
||||||
|
|
||||||
|
# failJSON: { "time": "2005-07-03T14:59:17", "match": true , "host": "192.0.2.1", "desc": "new log with session in daemon prefix, gh-3782" }
|
||||||
|
Jul 3 14:59:17 host sshd-session[1571]: Failed password for root from 192.0.2.1 port 56502 ssh2
|
||||||
|
|
||||||
#3
|
#3
|
||||||
# failJSON: { "time": "2005-01-05T01:31:41", "match": true , "host": "1.2.3.4" }
|
# failJSON: { "time": "2005-01-05T01:31:41", "match": true , "host": "1.2.3.4" }
|
||||||
Jan 5 01:31:41 www sshd[1643]: ROOT LOGIN REFUSED FROM 1.2.3.4
|
Jan 5 01:31:41 www sshd[1643]: ROOT LOGIN REFUSED FROM 1.2.3.4
|
||||||
|
|
|
@ -120,7 +120,7 @@ class SetupTest(unittest.TestCase):
|
||||||
# suppress stdout (and stderr) if not heavydebug
|
# suppress stdout (and stderr) if not heavydebug
|
||||||
supdbgout = ' >/dev/null' if unittest.F2B.log_level >= logging.DEBUG else '' # HEAVYDEBUG
|
supdbgout = ' >/dev/null' if unittest.F2B.log_level >= logging.DEBUG else '' # HEAVYDEBUG
|
||||||
try:
|
try:
|
||||||
self.assertEqual(os.system("%s %s install --root=%s%s"
|
self.assertEqual(os.system("%s -W 'ignore:setup.py install is deprecated' %s install --root=%s%s"
|
||||||
% (sys.executable, self.setup, tmp, supdbgout)), 0)
|
% (sys.executable, self.setup, tmp, supdbgout)), 0)
|
||||||
|
|
||||||
def strippath(l):
|
def strippath(l):
|
||||||
|
|
|
@ -2034,32 +2034,32 @@ class ServerConfigReaderTests(LogCaptureTestCase):
|
||||||
('j-fwcmd-rr', 'firewallcmd-rich-rules[port="22:24", protocol="tcp"]', {
|
('j-fwcmd-rr', 'firewallcmd-rich-rules[port="22:24", protocol="tcp"]', {
|
||||||
'ip4': ("family='ipv4'", "icmp-port-unreachable",), 'ip6': ("family='ipv6'", 'icmp6-port-unreachable',),
|
'ip4': ("family='ipv4'", "icmp-port-unreachable",), 'ip6': ("family='ipv6'", 'icmp6-port-unreachable',),
|
||||||
'ip4-ban': (
|
'ip4-ban': (
|
||||||
"""`ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="rule family='ipv4' source address='192.0.2.1' port port='$p' protocol='tcp' reject type='icmp-port-unreachable'"; done`""",
|
r"""`ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="rule family=\"ipv4\" source address=\"192.0.2.1\" port port=\"$p\" protocol=\"tcp\" reject type='icmp-port-unreachable'"; done`""",
|
||||||
),
|
),
|
||||||
'ip4-unban': (
|
'ip4-unban': (
|
||||||
"""`ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --remove-rich-rule="rule family='ipv4' source address='192.0.2.1' port port='$p' protocol='tcp' reject type='icmp-port-unreachable'"; done`""",
|
r"""`ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --remove-rich-rule="rule family=\"ipv4\" source address=\"192.0.2.1\" port port=\"$p\" protocol=\"tcp\" reject type='icmp-port-unreachable'"; done`""",
|
||||||
),
|
),
|
||||||
'ip6-ban': (
|
'ip6-ban': (
|
||||||
""" `ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="rule family='ipv6' source address='2001:db8::' port port='$p' protocol='tcp' reject type='icmp6-port-unreachable'"; done`""",
|
r""" `ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="rule family=\"ipv6\" source address=\"2001:db8::\" port port=\"$p\" protocol=\"tcp\" reject type='icmp6-port-unreachable'"; done`""",
|
||||||
),
|
),
|
||||||
'ip6-unban': (
|
'ip6-unban': (
|
||||||
"""`ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --remove-rich-rule="rule family='ipv6' source address='2001:db8::' port port='$p' protocol='tcp' reject type='icmp6-port-unreachable'"; done`""",
|
r"""`ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --remove-rich-rule="rule family=\"ipv6\" source address=\"2001:db8::\" port port=\"$p\" protocol=\"tcp\" reject type='icmp6-port-unreachable'"; done`""",
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
# firewallcmd-rich-logging --
|
# firewallcmd-rich-logging --
|
||||||
('j-fwcmd-rl', 'firewallcmd-rich-logging[port="22:24", protocol="tcp"]', {
|
('j-fwcmd-rl', 'firewallcmd-rich-logging[port="22:24", protocol="tcp"]', {
|
||||||
'ip4': ("family='ipv4'", "icmp-port-unreachable",), 'ip6': ("family='ipv6'", 'icmp6-port-unreachable',),
|
'ip4': ("family='ipv4'", "icmp-port-unreachable",), 'ip6': ("family='ipv6'", 'icmp6-port-unreachable',),
|
||||||
'ip4-ban': (
|
'ip4-ban': (
|
||||||
"""`ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="rule family='ipv4' source address='192.0.2.1' port port='$p' protocol='tcp' log prefix='f2b-j-fwcmd-rl' level='info' limit value='1/m' reject type='icmp-port-unreachable'"; done`""",
|
r"""`ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="rule family=\"ipv4\" source address=\"192.0.2.1\" port port=\"$p\" protocol=\"tcp\" log prefix='f2b-j-fwcmd-rl' level='info' limit value='1/m' reject type='icmp-port-unreachable'"; done`""",
|
||||||
),
|
),
|
||||||
'ip4-unban': (
|
'ip4-unban': (
|
||||||
"""`ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --remove-rich-rule="rule family='ipv4' source address='192.0.2.1' port port='$p' protocol='tcp' log prefix='f2b-j-fwcmd-rl' level='info' limit value='1/m' reject type='icmp-port-unreachable'"; done`""",
|
r"""`ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --remove-rich-rule="rule family=\"ipv4\" source address=\"192.0.2.1\" port port=\"$p\" protocol=\"tcp\" log prefix='f2b-j-fwcmd-rl' level='info' limit value='1/m' reject type='icmp-port-unreachable'"; done`""",
|
||||||
),
|
),
|
||||||
'ip6-ban': (
|
'ip6-ban': (
|
||||||
""" `ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="rule family='ipv6' source address='2001:db8::' port port='$p' protocol='tcp' log prefix='f2b-j-fwcmd-rl' level='info' limit value='1/m' reject type='icmp6-port-unreachable'"; done`""",
|
r""" `ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="rule family=\"ipv6\" source address=\"2001:db8::\" port port=\"$p\" protocol=\"tcp\" log prefix='f2b-j-fwcmd-rl' level='info' limit value='1/m' reject type='icmp6-port-unreachable'"; done`""",
|
||||||
),
|
),
|
||||||
'ip6-unban': (
|
'ip6-unban': (
|
||||||
"""`ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --remove-rich-rule="rule family='ipv6' source address='2001:db8::' port port='$p' protocol='tcp' log prefix='f2b-j-fwcmd-rl' level='info' limit value='1/m' reject type='icmp6-port-unreachable'"; done`""",
|
r"""`ports="22:24"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --remove-rich-rule="rule family=\"ipv6\" source address=\"2001:db8::\" port port=\"$p\" protocol=\"tcp\" log prefix='f2b-j-fwcmd-rl' level='info' limit value='1/m' reject type='icmp6-port-unreachable'"; done`""",
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
|
@ -24,7 +24,7 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko, Steven Hiscocks, Daniel Black"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2005-2016 Yaroslav Halchenko, 2013-2014 Steven Hiscocks, Daniel Black"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2005-2016 Yaroslav Halchenko, 2013-2014 Steven Hiscocks, Daniel Black"
|
||||||
__license__ = "GPL-v2+"
|
__license__ = "GPL-v2+"
|
||||||
|
|
||||||
version = "1.1.0"
|
version = "1.1.1.dev1"
|
||||||
|
|
||||||
def normVersion():
|
def normVersion():
|
||||||
""" Returns fail2ban version in normalized machine-readable format"""
|
""" Returns fail2ban version in normalized machine-readable format"""
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||||
.TH FAIL2BAN-CLIENT "1" "April 2024" "Fail2Ban v1.1.0" "User Commands"
|
.TH FAIL2BAN-CLIENT "1" "April 2024" "Fail2Ban v1.1.1.dev1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
fail2ban-client \- configure and control the server
|
fail2ban-client \- configure and control the server
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B fail2ban-client
|
.B fail2ban-client
|
||||||
[\fI\,OPTIONS\/\fR] \fI\,<COMMAND>\/\fR
|
[\fI\,OPTIONS\/\fR] \fI\,<COMMAND>\/\fR
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Fail2Ban v1.1.0 reads log file that contains password failure report
|
Fail2Ban v1.1.1.dev1 reads log file that contains password failure report
|
||||||
and bans the corresponding IP addresses using firewall rules.
|
and bans the corresponding IP addresses using firewall rules.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||||
.TH FAIL2BAN-PYTHON "1" "April 2024" "fail2ban-python 1.1.0" "User Commands"
|
.TH FAIL2BAN-PYTHON "1" "April 2024" "fail2ban-python 1.1.1.1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
fail2ban-python \- a helper for Fail2Ban to assure that the same Python is used
|
fail2ban-python \- a helper for Fail2Ban to assure that the same Python is used
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||||
.TH FAIL2BAN-REGEX "1" "April 2024" "fail2ban-regex 1.1.0" "User Commands"
|
.TH FAIL2BAN-REGEX "1" "April 2024" "fail2ban-regex 1.1.1.dev1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
fail2ban-regex \- test Fail2ban "failregex" option
|
fail2ban-regex \- test Fail2ban "failregex" option
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||||
.TH FAIL2BAN-SERVER "1" "April 2024" "Fail2Ban v1.1.0" "User Commands"
|
.TH FAIL2BAN-SERVER "1" "April 2024" "Fail2Ban v1.1.1.dev1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
fail2ban-server \- start the server
|
fail2ban-server \- start the server
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B fail2ban-server
|
.B fail2ban-server
|
||||||
[\fI\,OPTIONS\/\fR]
|
[\fI\,OPTIONS\/\fR]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Fail2Ban v1.1.0 reads log file that contains password failure report
|
Fail2Ban v1.1.1.dev1 reads log file that contains password failure report
|
||||||
and bans the corresponding IP addresses using firewall rules.
|
and bans the corresponding IP addresses using firewall rules.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||||
.TH FAIL2BAN-TESTCASES "1" "April 2024" "fail2ban-testcases 1.1.0" "User Commands"
|
.TH FAIL2BAN-TESTCASES "1" "April 2024" "fail2ban-testcases 1.1.1.dev1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
fail2ban-testcases \- run Fail2Ban unit-tests
|
fail2ban-testcases \- run Fail2Ban unit-tests
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
|
25
setup.py
25
setup.py
|
@ -24,23 +24,10 @@ __license__ = "GPL"
|
||||||
|
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
try:
|
import setuptools
|
||||||
import setuptools
|
from setuptools import setup
|
||||||
from setuptools import setup
|
from setuptools.command.install import install
|
||||||
from setuptools.command.install import install
|
from setuptools.command.install_scripts import install_scripts
|
||||||
from setuptools.command.install_scripts import install_scripts
|
|
||||||
from setuptools.command.build_py import build_py
|
|
||||||
build_scripts = None
|
|
||||||
except ImportError:
|
|
||||||
setuptools = None
|
|
||||||
from distutils.core import setup
|
|
||||||
|
|
||||||
# older versions
|
|
||||||
if setuptools is None:
|
|
||||||
from distutils.command.build_py import build_py
|
|
||||||
from distutils.command.build_scripts import build_scripts
|
|
||||||
from distutils.command.install import install
|
|
||||||
from distutils.command.install_scripts import install_scripts
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from os.path import isfile, join, isdir, realpath
|
from os.path import isfile, join, isdir, realpath
|
||||||
|
@ -207,9 +194,9 @@ setup(
|
||||||
url = "http://www.fail2ban.org",
|
url = "http://www.fail2ban.org",
|
||||||
license = "GPL",
|
license = "GPL",
|
||||||
platforms = "Posix",
|
platforms = "Posix",
|
||||||
cmdclass = dict({'build_py': build_py, 'build_scripts': build_scripts} if build_scripts else {}, **{
|
cmdclass = {
|
||||||
'install_scripts': install_scripts_f2b, 'install': install_command_f2b
|
'install_scripts': install_scripts_f2b, 'install': install_command_f2b
|
||||||
}),
|
},
|
||||||
scripts = [
|
scripts = [
|
||||||
'bin/fail2ban-client',
|
'bin/fail2ban-client',
|
||||||
'bin/fail2ban-server',
|
'bin/fail2ban-server',
|
||||||
|
|
Loading…
Reference in New Issue