mirror of https://github.com/fail2ban/fail2ban
Merge branch '0.11' into master
commit
f5ea40c7da
|
@ -55,7 +55,10 @@ ver. 1.0.1-dev-1 (20??/??/??) - development nightly edition
|
|||
* parsing of action in jail-configs considers space between action-names as separator also
|
||||
(previously only new-line was allowed), for example `action = a b` would specify 2 actions `a` and `b`
|
||||
* new filter and jail for GitLab recognizing failed application logins (gh-2689)
|
||||
* new filter and jail for Grafana recognizing failed application logins (gh-2855)
|
||||
* new filter and jail for SoftEtherVPN recognizing failed application logins (gh-2723)
|
||||
* `filter.d/guacamole.conf` extended with `logging` parameter to follow webapp-logging if it's configured (gh-2631)
|
||||
* `filter.d/bitwarden.conf` enhanced to support syslog (gh-2778)
|
||||
* introduced new prefix `{UNB}` for `datepattern` to disable word boundaries in regex;
|
||||
* datetemplate: improved anchor detection for capturing groups `(^...)`;
|
||||
* datepattern: improved handling with wrong recognized timestamps (timezones, no datepattern, etc)
|
||||
|
|
|
@ -2,5 +2,12 @@
|
|||
# Detecting failed login attempts
|
||||
# Logged in bwdata/logs/identity/Identity/log.txt
|
||||
|
||||
[INCLUDES]
|
||||
before = common.conf
|
||||
|
||||
[Definition]
|
||||
failregex = ^\s*\[WRN\]\s+Failed login attempt(?:, 2FA invalid)?\. <HOST>$
|
||||
_daemon = Bitwarden-Identity
|
||||
failregex = ^%(__prefix_line)s\s*\[(?:W(?:RN|arning)|Bit\.Core\.[^\]]+)\]\s+Failed login attempt(?:, 2FA invalid)?\. <ADDR>$
|
||||
|
||||
# DEV Notes:
|
||||
# __prefix_line can result to an empty string, so it can support syslog and non-syslog at once.
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# Fail2Ban filter for Grafana
|
||||
# Detecting unauthorized access
|
||||
# Typically logged in /var/log/grafana/grafana.log
|
||||
|
||||
[Init]
|
||||
datepattern = ^t=%%Y-%%m-%%dT%%H:%%M:%%S%%z
|
||||
|
||||
[Definition]
|
||||
failregex = ^(?: lvl=err?or)? msg="Invalid username or password"(?: uname=(?:"<F-ALT_USER>[^"]+</F-ALT_USER>"|<F-USER>\S+</F-USER>)| error="<F-ERROR>[^"]+</F-ERROR>"| \S+=(?:\S*|"[^"]+"))* remote_addr=<ADDR>$
|
|
@ -0,0 +1,9 @@
|
|||
# Fail2Ban filter for SoftEtherVPN
|
||||
# Detecting unauthorized access to SoftEtherVPN
|
||||
# typically logged in /usr/local/vpnserver/security_log/*/sec.log, or in syslog, depending on configuration
|
||||
|
||||
[INCLUDES]
|
||||
before = common.conf
|
||||
|
||||
[Definition]
|
||||
failregex = ^%(__prefix_line)s(?:(?:\([\d\-]+ [\d:.]+\) )?<SECURITY_LOG>: )?Connection "[^"]+": User authentication failed. The user name that has been provided was "<F-USER>(?:[^"]+|.+)</F-USER>", from <ADDR>\.$
|
|
@ -857,10 +857,19 @@ udpport = 1200,27000,27001,27002,27003,27004,27005,27006,27007,27008,27009,27010
|
|||
action_ = %(default/action_)s[name=%(__name__)s-tcp, port="%(tcpport)s", protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, port="%(udpport)s", protocol="udp"]
|
||||
|
||||
[softethervpn]
|
||||
port = 500,4500
|
||||
protocol = udp
|
||||
logpath = /usr/local/vpnserver/security_log/*/sec.log
|
||||
|
||||
[gitlab]
|
||||
port = http,https
|
||||
logpath = /var/log/gitlab/gitlab-rails/application.log
|
||||
|
||||
[grafana]
|
||||
port = http,https
|
||||
logpath = /var/log/grafana/grafana.log
|
||||
|
||||
[bitwarden]
|
||||
port = http,https
|
||||
logpath = /home/*/bwdata/logs/identity/Identity/log.txt
|
||||
|
|
|
@ -455,7 +455,18 @@ class CommandAction(ActionBase):
|
|||
ret = True
|
||||
# avoid double execution of same command for both families:
|
||||
if cmd and cmd not in self._operationExecuted(tag, lambda f: f != famoper):
|
||||
ret = self.executeCmd(cmd, self.timeout)
|
||||
realCmd = cmd
|
||||
if self._jail:
|
||||
# simulate action info with "empty" ticket:
|
||||
aInfo = getattr(self._jail.actions, 'actionInfo', None)
|
||||
if not aInfo:
|
||||
aInfo = self._jail.actions._getActionInfo(None)
|
||||
setattr(self._jail.actions, 'actionInfo', aInfo)
|
||||
aInfo['time'] = MyTime.time()
|
||||
aInfo['family'] = famoper
|
||||
# replace dynamical tags, important - don't cache, no recursion and auto-escape here
|
||||
realCmd = self.replaceDynamicTags(cmd, aInfo)
|
||||
ret = self.executeCmd(realCmd, self.timeout)
|
||||
res &= ret
|
||||
if afterExec: afterExec(famoper, ret)
|
||||
self._operationExecuted(tag, famoper, cmd if ret else None)
|
||||
|
|
|
@ -457,7 +457,9 @@ class Actions(JailThread, Mapping):
|
|||
return mi[idx] if mi[idx] is not None else self.__ticket
|
||||
|
||||
|
||||
def __getActionInfo(self, ticket):
|
||||
def _getActionInfo(self, ticket):
|
||||
if not ticket:
|
||||
ticket = BanTicket("", MyTime.time())
|
||||
aInfo = Actions.ActionInfo(ticket, self._jail)
|
||||
return aInfo
|
||||
|
||||
|
@ -491,7 +493,7 @@ class Actions(JailThread, Mapping):
|
|||
bTicket = BanTicket.wrap(ticket)
|
||||
btime = ticket.getBanTime(self.__banManager.getBanTime())
|
||||
ip = bTicket.getIP()
|
||||
aInfo = self.__getActionInfo(bTicket)
|
||||
aInfo = self._getActionInfo(bTicket)
|
||||
reason = {}
|
||||
if self.__banManager.addBanTicket(bTicket, reason=reason):
|
||||
cnt += 1
|
||||
|
@ -568,7 +570,7 @@ class Actions(JailThread, Mapping):
|
|||
"""
|
||||
actions = actions or self._actions
|
||||
ip = ticket.getIP()
|
||||
aInfo = self.__getActionInfo(ticket)
|
||||
aInfo = self._getActionInfo(ticket)
|
||||
if log:
|
||||
logSys.notice("[%s] Reban %s%s", self._jail.name, aInfo["ip"], (', action %r' % actions.keys()[0] if len(actions) == 1 else ''))
|
||||
for name, action in actions.iteritems():
|
||||
|
@ -602,7 +604,7 @@ class Actions(JailThread, Mapping):
|
|||
if not action._prolongable:
|
||||
continue
|
||||
if aInfo is None:
|
||||
aInfo = self.__getActionInfo(ticket)
|
||||
aInfo = self._getActionInfo(ticket)
|
||||
if not aInfo.immutable: aInfo.reset()
|
||||
action.prolong(aInfo)
|
||||
except Exception as e:
|
||||
|
@ -696,7 +698,7 @@ class Actions(JailThread, Mapping):
|
|||
else:
|
||||
unbactions = actions
|
||||
ip = ticket.getIP()
|
||||
aInfo = self.__getActionInfo(ticket)
|
||||
aInfo = self._getActionInfo(ticket)
|
||||
if log:
|
||||
logSys.notice("[%s] Unban %s", self._jail.name, aInfo["ip"])
|
||||
for name, action in unbactions.iteritems():
|
||||
|
|
|
@ -3,3 +3,9 @@
|
|||
|
||||
# failJSON: { "time": "2019-11-25T21:39:58", "match": true , "host": "192.168.0.21" }
|
||||
2019-11-25 21:39:58.464 +01:00 [WRN] Failed login attempt, 2FA invalid. 192.168.0.21
|
||||
|
||||
# failJSON: { "time": "2019-11-25T21:39:58", "match": true , "host": "192.168.0.21" }
|
||||
2019-11-25 21:39:58.464 +01:00 [Warning] Failed login attempt, 2FA invalid. 192.168.0.21
|
||||
|
||||
# failJSON: { "time": "2019-09-24T13:16:50", "match": true , "host": "192.168.0.23" }
|
||||
2019-09-24T13:16:50 e5a81dbf7fd1 Bitwarden-Identity[1]: [Bit.Core.IdentityServer.ResourceOwnerPasswordValidator] Failed login attempt. 192.168.0.23
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# Access of unauthorized host in /var/log/grafana/grafana.log
|
||||
# failJSON: { "time": "2020-10-19T17:44:33", "match": true , "host": "182.56.23.12" }
|
||||
t=2020-10-19T17:44:33+0200 lvl=eror msg="Invalid username or password" logger=context userId=0 orgId=0 uname= error="Invalid Username or Password" remote_addr=182.56.23.12
|
||||
# failJSON: { "time": "2020-10-19T18:44:33", "match": true , "host": "182.56.23.13" }
|
||||
t=2020-10-19T18:44:33+0200 lvl=eror msg="Invalid username or password" logger=context userId=0 orgId=0 uname= error="User not found" remote_addr=182.56.23.13
|
|
@ -0,0 +1,7 @@
|
|||
# Access of unauthorized host in /usr/local/vpnserver/security_log/*/sec.log
|
||||
# failJSON: { "time": "2020-05-12T10:53:19", "match": true , "host": "80.10.11.12" }
|
||||
2020-05-12 10:53:19.781 Connection "CID-72": User authentication failed. The user name that has been provided was "bob", from 80.10.11.12.
|
||||
|
||||
# Access of unauthorized host in syslog
|
||||
# failJSON: { "time": "2020-05-13T10:53:19", "match": true , "host": "80.10.11.13" }
|
||||
2020-05-13T10:53:19 localhost [myserver.com/VPN/defaultvpn] (2020-05-13 10:53:19.591) <SECURITY_LOG>: Connection "CID-594": User authentication failed. The user name that has been provided was "alice", from 80.10.11.13.
|
|
@ -1448,9 +1448,10 @@ class ServerConfigReaderTests(LogCaptureTestCase):
|
|||
),
|
||||
}),
|
||||
# dummy --
|
||||
('j-dummy', 'dummy[name=%(__name__)s, init="==", target="/tmp/fail2ban.dummy"]', {
|
||||
('j-dummy', '''dummy[name=%(__name__)s, init="=='<family>/<ip>'==bt:<bantime>==bc:<bancount>==", target="/tmp/fail2ban.dummy"]''', {
|
||||
'ip4': ('family: inet4',), 'ip6': ('family: inet6',),
|
||||
'start': (
|
||||
'''`printf %b "=='/'==bt:600==bc:0==\\n"''', ## empty family (independent in this action, same for both), no ip on start, initial bantime and bancount
|
||||
'`echo "[j-dummy] dummy /tmp/fail2ban.dummy -- started"`',
|
||||
),
|
||||
'flush': (
|
||||
|
|
Loading…
Reference in New Issue