mirror of https://github.com/fail2ban/fail2ban
Merge remote-tracking branch 'remotes/upstream/master', fix test cases (see bellow)
Conflicts resolved: ChangeLog fail2ban/server/filter.py fail2ban/server/jail.py fail2ban/tests/actionstestcase.py Test cases fixed: testBanActionsAInfo - fail ticket with current time (otherwise ticket will be ignored - ban time too old) testFail2BanExceptHook - use local sys.__excepthook__ to check was really executed and prevent write error in stderr.pull/716/head
commit
00b7205a3c
14
ChangeLog
14
ChangeLog
|
@ -10,6 +10,11 @@ Fail2Ban (version 0.9.0.dev) 2014/xx/xx
|
||||||
ver. 0.9.1 (2014/xx/xx) - better, faster, stronger
|
ver. 0.9.1 (2014/xx/xx) - better, faster, stronger
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
- Refactoring (IMPORTANT -- Please review your setup and configuration):
|
||||||
|
* iptables-common.conf replaced iptables-blocktype.conf
|
||||||
|
(iptables-blocktype.local should still be read) and now also
|
||||||
|
provides defaults for the chain, port, protocol and name tags
|
||||||
|
|
||||||
- Fixes:
|
- Fixes:
|
||||||
* systemd backend error on bad utf-8 in python3
|
* systemd backend error on bad utf-8 in python3
|
||||||
* badips.py action error when logging HTTP error raised with badips request
|
* badips.py action error when logging HTTP error raised with badips request
|
||||||
|
@ -27,18 +32,23 @@ ver. 0.9.1 (2014/xx/xx) - better, faster, stronger
|
||||||
* Database now returns persistent bans on restart (bantime < 0)
|
* Database now returns persistent bans on restart (bantime < 0)
|
||||||
* Recursive action tags now fully processed. Fixes issue with bsd-ipfw
|
* Recursive action tags now fully processed. Fixes issue with bsd-ipfw
|
||||||
action
|
action
|
||||||
* Correct times for non-timezone date times formats during DST.
|
|
||||||
* Fixed TypeError with "ipfailures" and "ipjailfailures" action tags.
|
* Fixed TypeError with "ipfailures" and "ipjailfailures" action tags.
|
||||||
Thanks Serg G. Brester (sebres)
|
Thanks Serg G. Brester (sebres)
|
||||||
|
* Correct times for non-timezone date times formats during DST
|
||||||
|
Thanks Serg G. Brester (sebres)
|
||||||
|
* Pass a copy of, not original, aInfo into actions to avoid side-effects
|
||||||
|
|
||||||
- New features:
|
- New features:
|
||||||
- Added monit filter thanks Jason H Martin.
|
- Added monit filter thanks Jason H Martin.
|
||||||
|
|
||||||
|
|
||||||
- Enhancements
|
- Enhancements
|
||||||
* Fail2ban-regex - add print-all-matched option. Closes gh-652
|
* Fail2ban-regex - add print-all-matched option. Closes gh-652
|
||||||
* Suppress fail2ban-client warnings for non-critical config options
|
* Suppress fail2ban-client warnings for non-critical config options
|
||||||
* Match non "Bye Bye" disconnect messages for sshd locked account regex
|
* Match non "Bye Bye" disconnect messages for sshd locked account regex
|
||||||
|
* Add <chain> tag to iptables-ipsets
|
||||||
|
* Realign fail2ban log output with white space to improve readability. Does
|
||||||
|
not affect SYSLOG output
|
||||||
|
* Log unhandled exceptions
|
||||||
|
|
||||||
ver. 0.9.0 (2014/03/14) - beta
|
ver. 0.9.0 (2014/03/14) - beta
|
||||||
----------
|
----------
|
||||||
|
|
2
MANIFEST
2
MANIFEST
|
@ -258,7 +258,7 @@ config/action.d/dummy.conf
|
||||||
config/action.d/firewallcmd-new.conf
|
config/action.d/firewallcmd-new.conf
|
||||||
config/action.d/firewallcmd-ipset.conf
|
config/action.d/firewallcmd-ipset.conf
|
||||||
config/action.d/iptables-ipset-proto6-allports.conf
|
config/action.d/iptables-ipset-proto6-allports.conf
|
||||||
config/action.d/iptables-blocktype.conf
|
config/action.d/iptables-common.conf
|
||||||
config/action.d/iptables-ipset-proto4.conf
|
config/action.d/iptables-ipset-proto4.conf
|
||||||
config/action.d/iptables-ipset-proto6.conf
|
config/action.d/iptables-ipset-proto6.conf
|
||||||
config/action.d/iptables-xt_recent-echo.conf
|
config/action.d/iptables-xt_recent-echo.conf
|
||||||
|
|
1
THANKS
1
THANKS
|
@ -87,6 +87,7 @@ Robert Edeker
|
||||||
Rolf Fokkens
|
Rolf Fokkens
|
||||||
Roman Gelfand
|
Roman Gelfand
|
||||||
Russell Odom
|
Russell Odom
|
||||||
|
SATO Kentaro
|
||||||
Sebastian Arcus
|
Sebastian Arcus
|
||||||
Serg G. Brester (sebres)
|
Serg G. Brester (sebres)
|
||||||
Sireyessire
|
Sireyessire
|
||||||
|
|
|
@ -30,9 +30,10 @@ from fail2ban.protocol import printFormatted
|
||||||
from fail2ban.client.csocket import CSocket
|
from fail2ban.client.csocket import CSocket
|
||||||
from fail2ban.client.configurator import Configurator
|
from fail2ban.client.configurator import Configurator
|
||||||
from fail2ban.client.beautifier import Beautifier
|
from fail2ban.client.beautifier import Beautifier
|
||||||
|
from fail2ban.helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger("fail2ban.client")
|
logSys = getLogger("fail2ban")
|
||||||
|
|
||||||
##
|
##
|
||||||
#
|
#
|
||||||
|
|
|
@ -45,9 +45,9 @@ from fail2ban.client.filterreader import FilterReader
|
||||||
from fail2ban.server.filter import Filter
|
from fail2ban.server.filter import Filter
|
||||||
from fail2ban.server.failregex import RegexException
|
from fail2ban.server.failregex import RegexException
|
||||||
|
|
||||||
from fail2ban.helpers import FormatterWithTraceBack
|
from fail2ban.helpers import FormatterWithTraceBack, getLogger
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger("fail2ban")
|
logSys = getLogger("fail2ban")
|
||||||
|
|
||||||
def debuggexURL(sample, regex):
|
def debuggexURL(sample, regex):
|
||||||
q = urllib.urlencode({ 're': regex.replace('<HOST>', '(?&.ipv4)'),
|
q = urllib.urlencode({ 're': regex.replace('<HOST>', '(?&.ipv4)'),
|
||||||
|
|
|
@ -22,13 +22,14 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import getopt, sys, logging, os
|
import getopt, sys, os
|
||||||
|
|
||||||
from fail2ban.version import version
|
from fail2ban.version import version
|
||||||
from fail2ban.server.server import Server
|
from fail2ban.server.server import Server
|
||||||
|
from fail2ban.helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger("fail2ban")
|
logSys = getLogger("fail2ban")
|
||||||
|
|
||||||
##
|
##
|
||||||
# \mainpage Fail2Ban
|
# \mainpage Fail2Ban
|
||||||
|
|
|
@ -24,8 +24,8 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2012- Yaroslav Halchenko"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2012- Yaroslav Halchenko"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
|
import logging
|
||||||
import unittest, logging, sys, time, os
|
import unittest, sys, time, os
|
||||||
|
|
||||||
# Check if local fail2ban module exists, and use if it exists by
|
# Check if local fail2ban module exists, and use if it exists by
|
||||||
# modifying the path. This is such that tests can be used in dev
|
# modifying the path. This is such that tests can be used in dev
|
||||||
|
@ -35,7 +35,7 @@ if os.path.exists("fail2ban/__init__.py"):
|
||||||
from fail2ban.version import version
|
from fail2ban.version import version
|
||||||
|
|
||||||
from fail2ban.tests.utils import gatherTests
|
from fail2ban.tests.utils import gatherTests
|
||||||
from fail2ban.helpers import FormatterWithTraceBack
|
from fail2ban.helpers import FormatterWithTraceBack, getLogger
|
||||||
from fail2ban.server.mytime import MyTime
|
from fail2ban.server.mytime import MyTime
|
||||||
|
|
||||||
from optparse import OptionParser, Option
|
from optparse import OptionParser, Option
|
||||||
|
@ -70,7 +70,7 @@ parser = get_opt_parser()
|
||||||
#
|
#
|
||||||
# Logging
|
# Logging
|
||||||
#
|
#
|
||||||
logSys = logging.getLogger("fail2ban")
|
logSys = getLogger("fail2ban")
|
||||||
|
|
||||||
# Numerical level of verbosity corresponding to a log "level"
|
# Numerical level of verbosity corresponding to a log "level"
|
||||||
verbosity = {'heavydebug': 4,
|
verbosity = {'heavydebug': 4,
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
before = iptables-blocktype.conf
|
before = iptables-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
|
@ -31,22 +31,6 @@ actionunban = ipset del fail2ban-<name> <ip> -exist
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
# Default name of the chain
|
|
||||||
#
|
|
||||||
name = default
|
|
||||||
|
|
||||||
# Option: port
|
|
||||||
# Notes.: specifies port to monitor
|
|
||||||
# Values: [ NUM | STRING ]
|
|
||||||
#
|
|
||||||
port = ssh
|
|
||||||
|
|
||||||
# Option: protocol
|
|
||||||
# Notes.: internally used by config reader for interpolations.
|
|
||||||
# Values: [ tcp | udp | icmp | all ]
|
|
||||||
#
|
|
||||||
protocol = tcp
|
|
||||||
|
|
||||||
# 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
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
before = iptables-blocktype.conf
|
before = iptables-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
|
@ -24,22 +24,6 @@ actionunban = firewall-cmd --direct --remove-rule ipv4 filter f2b-<name> 0 -s <i
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
# Default name of the chain
|
|
||||||
#
|
|
||||||
name = default
|
|
||||||
|
|
||||||
# Option: port
|
|
||||||
# Notes.: specifies port to monitor
|
|
||||||
# Values: [ NUM | STRING ]
|
|
||||||
#
|
|
||||||
port = ssh
|
|
||||||
|
|
||||||
# Option: protocol
|
|
||||||
# Notes.: internally used by config reader for interpolations.
|
|
||||||
# Values: [ tcp | udp | icmp | all ]
|
|
||||||
#
|
|
||||||
protocol = tcp
|
|
||||||
|
|
||||||
# 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
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
before = iptables-blocktype.conf
|
before = iptables-common.conf
|
||||||
|
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
@ -53,18 +53,3 @@ actionunban = iptables -D f2b-<name> -s <ip> -j <blocktype>
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
# Default name of the chain
|
|
||||||
#
|
|
||||||
name = default
|
|
||||||
|
|
||||||
# Option: protocol
|
|
||||||
# Notes.: internally used by config reader for interpolations.
|
|
||||||
# Values: [ tcp | udp | icmp | all ] Default: tcp
|
|
||||||
#
|
|
||||||
protocol = tcp
|
|
||||||
|
|
||||||
# Option: chain
|
|
||||||
# Notes specifies the iptables chain to which the fail2ban rules should be
|
|
||||||
# added
|
|
||||||
# Values: STRING Default: INPUT
|
|
||||||
chain = INPUT
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
# Fail2Ban configuration file
|
|
||||||
#
|
|
||||||
# Author: Daniel Black
|
|
||||||
#
|
|
||||||
# This is a included configuration file and includes the defination for the blocktype
|
|
||||||
# used in all iptables based actions by default.
|
|
||||||
#
|
|
||||||
# The user can override the default in iptables-blocktype.local
|
|
||||||
|
|
||||||
[INCLUDES]
|
|
||||||
|
|
||||||
after = iptables-blocktype.local
|
|
||||||
|
|
||||||
[Init]
|
|
||||||
|
|
||||||
# Option: blocktype
|
|
||||||
# Note: This is what the action does with rules. This can be any jump target
|
|
||||||
# as per the iptables man page (section 8). Common values are DROP
|
|
||||||
# REJECT, REJECT --reject-with icmp-port-unreachable
|
|
||||||
# Values: STRING
|
|
||||||
blocktype = REJECT --reject-with icmp-port-unreachable
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
# Fail2Ban configuration file
|
||||||
|
#
|
||||||
|
# Author: Daniel Black
|
||||||
|
#
|
||||||
|
# This is a included configuration file and includes the definitions for the iptables
|
||||||
|
# used in all iptables based actions by default.
|
||||||
|
#
|
||||||
|
# The user can override the defaults in iptables-common.local
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
after = iptables-blocktype.local
|
||||||
|
iptables-common.local
|
||||||
|
# iptables-blocktype.local is obsolete
|
||||||
|
|
||||||
|
[Init]
|
||||||
|
|
||||||
|
# Option: chain
|
||||||
|
# Notes specifies the iptables chain to which the Fail2Ban rules should be
|
||||||
|
# added
|
||||||
|
# Values: STRING Default: INPUT
|
||||||
|
chain = INPUT
|
||||||
|
|
||||||
|
# Default name of the chain
|
||||||
|
#
|
||||||
|
name = default
|
||||||
|
|
||||||
|
# Option: port
|
||||||
|
# Notes.: specifies port to monitor
|
||||||
|
# Values: [ NUM | STRING ] Default:
|
||||||
|
#
|
||||||
|
port = ssh
|
||||||
|
|
||||||
|
# Option: protocol
|
||||||
|
# Notes.: internally used by config reader for interpolations.
|
||||||
|
# Values: [ tcp | udp | icmp | all ] Default: tcp
|
||||||
|
#
|
||||||
|
protocol = tcp
|
||||||
|
|
||||||
|
# Option: blocktype
|
||||||
|
# Note: This is what the action does with rules. This can be any jump target
|
||||||
|
# as per the iptables man page (section 8). Common values are DROP
|
||||||
|
# REJECT, REJECT --reject-with icmp-port-unreachable
|
||||||
|
# Values: STRING
|
||||||
|
blocktype = REJECT --reject-with icmp-port-unreachable
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
before = iptables-blocktype.conf
|
before = iptables-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
|
@ -28,13 +28,13 @@ before = iptables-blocktype.conf
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstart = ipset --create f2b-<name> iphash
|
actionstart = ipset --create f2b-<name> iphash
|
||||||
iptables -I INPUT -p <protocol> -m multiport --dports <port> -m set --match-set f2b-<name> src -j <blocktype>
|
iptables -I <chain> -p <protocol> -m multiport --dports <port> -m set --match-set f2b-<name> src -j <blocktype>
|
||||||
|
|
||||||
# Option: actionstop
|
# Option: actionstop
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstop = iptables -D INPUT -p <protocol> -m multiport --dports <port> -m set --match-set f2b-<name> src -j <blocktype>
|
actionstop = iptables -D <chain> -p <protocol> -m multiport --dports <port> -m set --match-set f2b-<name> src -j <blocktype>
|
||||||
ipset --flush f2b-<name>
|
ipset --flush f2b-<name>
|
||||||
ipset --destroy f2b-<name>
|
ipset --destroy f2b-<name>
|
||||||
|
|
||||||
|
@ -56,18 +56,3 @@ actionunban = ipset --test f2b-<name> <ip> && ipset --del f2b-<name> <ip>
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
# Default name of the ipset
|
|
||||||
#
|
|
||||||
name = default
|
|
||||||
|
|
||||||
# Option: port
|
|
||||||
# Notes.: specifies port to monitor
|
|
||||||
# Values: [ NUM | STRING ] Default: ssh
|
|
||||||
#
|
|
||||||
port = ssh
|
|
||||||
|
|
||||||
# Option: protocol
|
|
||||||
# Notes.: internally used by config reader for interpolations.
|
|
||||||
# Values: [ tcp | udp | icmp | all ] Default: tcp
|
|
||||||
#
|
|
||||||
protocol = tcp
|
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
before = iptables-blocktype.conf
|
before = iptables-common.conf
|
||||||
|
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
|
@ -25,13 +24,13 @@ before = iptables-blocktype.conf
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstart = ipset create f2b-<name> hash:ip timeout <bantime>
|
actionstart = ipset create f2b-<name> hash:ip timeout <bantime>
|
||||||
iptables -I INPUT -m set --match-set f2b-<name> src -j <blocktype>
|
iptables -I <chain> -m set --match-set f2b-<name> src -j <blocktype>
|
||||||
|
|
||||||
# Option: actionstop
|
# Option: actionstop
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstop = iptables -D INPUT -m set --match-set f2b-<name> src -j <blocktype>
|
actionstop = iptables -D <chain> -m set --match-set f2b-<name> src -j <blocktype>
|
||||||
ipset flush f2b-<name>
|
ipset flush f2b-<name>
|
||||||
ipset destroy f2b-<name>
|
ipset destroy f2b-<name>
|
||||||
|
|
||||||
|
@ -53,12 +52,8 @@ actionunban = ipset del f2b-<name> <ip> -exist
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
# Default name of the ipset
|
|
||||||
#
|
|
||||||
name = default
|
|
||||||
|
|
||||||
# Option: bantime
|
# Option: bantime
|
||||||
# Notes: specifies the bantime in seconds (handled internally rather than by fail2ban)
|
# Notes: specifies the bantime in seconds (handled internally rather than by fail2ban)
|
||||||
# Values: [ NUM ] Default: 600
|
# Values: [ NUM ] Default: 600
|
||||||
|
#
|
||||||
bantime = 600
|
bantime = 600
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
before = iptables-blocktype.conf
|
before = iptables-common.conf
|
||||||
|
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
|
@ -25,13 +24,13 @@ before = iptables-blocktype.conf
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstart = ipset create f2b-<name> hash:ip timeout <bantime>
|
actionstart = ipset create f2b-<name> hash:ip timeout <bantime>
|
||||||
iptables -I INPUT -p <protocol> -m multiport --dports <port> -m set --match-set f2b-<name> src -j <blocktype>
|
iptables -I <chain> -p <protocol> -m multiport --dports <port> -m set --match-set f2b-<name> src -j <blocktype>
|
||||||
|
|
||||||
# Option: actionstop
|
# Option: actionstop
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstop = iptables -D INPUT -p <protocol> -m multiport --dports <port> -m set --match-set f2b-<name> src -j <blocktype>
|
actionstop = iptables -D <chain> -p <protocol> -m multiport --dports <port> -m set --match-set f2b-<name> src -j <blocktype>
|
||||||
ipset flush f2b-<name>
|
ipset flush f2b-<name>
|
||||||
ipset destroy f2b-<name>
|
ipset destroy f2b-<name>
|
||||||
|
|
||||||
|
@ -53,24 +52,8 @@ actionunban = ipset del f2b-<name> <ip> -exist
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
# Default name of the ipset
|
|
||||||
#
|
|
||||||
name = default
|
|
||||||
|
|
||||||
# Option: port
|
|
||||||
# Notes.: specifies port to monitor
|
|
||||||
# Values: [ NUM | STRING ] Default: ssh
|
|
||||||
#
|
|
||||||
port = ssh
|
|
||||||
|
|
||||||
# Option: protocol
|
|
||||||
# Notes.: internally used by config reader for interpolations.
|
|
||||||
# Values: [ tcp | udp | icmp | all ] Default: tcp
|
|
||||||
#
|
|
||||||
protocol = tcp
|
|
||||||
|
|
||||||
# Option: bantime
|
# Option: bantime
|
||||||
# Notes: specifies the bantime in seconds (handled internally rather than by fail2ban)
|
# Notes: specifies the bantime in seconds (handled internally rather than by fail2ban)
|
||||||
# Values: [ NUM ] Default: 600
|
# Values: [ NUM ] Default: 600
|
||||||
|
#
|
||||||
bantime = 600
|
bantime = 600
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
before = iptables-blocktype.conf
|
before = iptables-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
|
@ -60,24 +60,3 @@ actionunban = iptables -D f2b-<name> -s <ip> -j f2b-<name>-log
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
# Default name of the chain
|
|
||||||
#
|
|
||||||
name = default
|
|
||||||
|
|
||||||
# Option: port
|
|
||||||
# Notes.: specifies port to monitor
|
|
||||||
# Values: [ NUM | STRING ] Default:
|
|
||||||
#
|
|
||||||
port = ssh
|
|
||||||
|
|
||||||
# Option: protocol
|
|
||||||
# Notes.: internally used by config reader for interpolations.
|
|
||||||
# Values: [ tcp | udp | icmp | all ] Default: tcp
|
|
||||||
#
|
|
||||||
protocol = tcp
|
|
||||||
|
|
||||||
# Option: chain
|
|
||||||
# Notes specifies the iptables chain to which the fail2ban rules should be
|
|
||||||
# added
|
|
||||||
# Values: STRING Default: INPUT
|
|
||||||
chain = INPUT
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
before = iptables-blocktype.conf
|
before = iptables-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
|
@ -50,24 +50,3 @@ actionunban = iptables -D f2b-<name> -s <ip> -j <blocktype>
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
# Default name of the chain
|
|
||||||
#
|
|
||||||
name = default
|
|
||||||
|
|
||||||
# Option: port
|
|
||||||
# Notes.: specifies port to monitor
|
|
||||||
# Values: [ NUM | STRING ] Default:
|
|
||||||
#
|
|
||||||
port = ssh
|
|
||||||
|
|
||||||
# Option: protocol
|
|
||||||
# Notes.: internally used by config reader for interpolations.
|
|
||||||
# Values: [ tcp | udp | icmp | all ] Default: tcp
|
|
||||||
#
|
|
||||||
protocol = tcp
|
|
||||||
|
|
||||||
# Option: chain
|
|
||||||
# Notes specifies the iptables chain to which the fail2ban rules should be
|
|
||||||
# added
|
|
||||||
# Values: STRING Default: INPUT
|
|
||||||
chain = INPUT
|
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
before = iptables-blocktype.conf
|
before = iptables-common.conf
|
||||||
|
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
|
@ -53,24 +52,3 @@ actionunban = iptables -D f2b-<name> -s <ip> -j <blocktype>
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
# Default name of the chain
|
|
||||||
#
|
|
||||||
name = default
|
|
||||||
|
|
||||||
# Option: port
|
|
||||||
# Notes.: specifies port to monitor
|
|
||||||
# Values: [ NUM | STRING ] Default:
|
|
||||||
#
|
|
||||||
port = ssh
|
|
||||||
|
|
||||||
# Option: protocol
|
|
||||||
# Notes.: internally used by config reader for interpolations.
|
|
||||||
# Values: [ tcp | udp | icmp | all ] Default: tcp
|
|
||||||
#
|
|
||||||
protocol = tcp
|
|
||||||
|
|
||||||
# Option: chain
|
|
||||||
# Notes specifies the iptables chain to which the fail2ban rules should be
|
|
||||||
# added
|
|
||||||
# Values: STRING Default: INPUT
|
|
||||||
chain = INPUT
|
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
before = iptables-blocktype.conf
|
before = iptables-common.conf
|
||||||
|
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
|
@ -33,14 +32,14 @@ before = iptables-blocktype.conf
|
||||||
# own rules. The 3600 second timeout is independent and acts as a
|
# own rules. The 3600 second timeout is independent and acts as a
|
||||||
# safeguard in case the fail2ban process dies unexpectedly. The
|
# safeguard in case the fail2ban process dies unexpectedly. The
|
||||||
# shorter of the two timeouts actually matters.
|
# shorter of the two timeouts actually matters.
|
||||||
actionstart = if [ `id -u` -eq 0 ];then iptables -I INPUT -m recent --update --seconds 3600 --name f2b-<name> -j <blocktype>;fi
|
actionstart = if [ `id -u` -eq 0 ];then iptables -I <chain> -m recent --update --seconds 3600 --name f2b-<name> -j <blocktype>;fi
|
||||||
|
|
||||||
# Option: actionstop
|
# Option: actionstop
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstop = echo / > /proc/net/xt_recent/f2b-<name>
|
actionstop = echo / > /proc/net/xt_recent/f2b-<name>
|
||||||
if [ `id -u` -eq 0 ];then iptables -D INPUT -m recent --update --seconds 3600 --name f2b-<name> -j <blocktype>;fi
|
if [ `id -u` -eq 0 ];then iptables -D <chain> -m recent --update --seconds 3600 --name f2b-<name> -j <blocktype>;fi
|
||||||
|
|
||||||
# Option: actioncheck
|
# Option: actioncheck
|
||||||
# Notes.: command executed once before each actionban command
|
# Notes.: command executed once before each actionban command
|
||||||
|
@ -66,12 +65,3 @@ actionunban = echo -<ip> > /proc/net/xt_recent/f2b-<name>
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
# Default name of the chain
|
|
||||||
#
|
|
||||||
name = default
|
|
||||||
|
|
||||||
# Option: protocol
|
|
||||||
# Notes.: internally used by config reader for interpolations.
|
|
||||||
# Values: [ tcp | udp | icmp | all ] Default: tcp
|
|
||||||
#
|
|
||||||
protocol = tcp
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
before = iptables-blocktype.conf
|
before = iptables-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
|
@ -50,24 +50,3 @@ actionunban = iptables -D f2b-<name> -s <ip> -j <blocktype>
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
# Default name of the chain
|
|
||||||
#
|
|
||||||
name = default
|
|
||||||
|
|
||||||
# Option: port
|
|
||||||
# Notes.: specifies port to monitor
|
|
||||||
# Values: [ NUM | STRING ] Default:
|
|
||||||
#
|
|
||||||
port = ssh
|
|
||||||
|
|
||||||
# Option: protocol
|
|
||||||
# Notes.: internally used by config reader for interpolations.
|
|
||||||
# Values: [ tcp | udp | icmp | all ] Default: tcp
|
|
||||||
#
|
|
||||||
protocol = tcp
|
|
||||||
|
|
||||||
# Option: chain
|
|
||||||
# Notes specifies the iptables chain to which the fail2ban rules should be
|
|
||||||
# added
|
|
||||||
# Values: STRING Default: INPUT
|
|
||||||
chain = INPUT
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ messages['ban'] = {}
|
||||||
messages['ban']['head'] = \
|
messages['ban']['head'] = \
|
||||||
"""Hi,
|
"""Hi,
|
||||||
|
|
||||||
The IP %(ip)s has just been banned for %(bantime)s seconds
|
The IP %(ip)s has just been banned for %(bantime)i seconds
|
||||||
by Fail2Ban after %(failures)i attempts against %(jailname)s.
|
by Fail2Ban after %(failures)i attempts against %(jailname)s.
|
||||||
"""
|
"""
|
||||||
messages['ban']['tail'] = \
|
messages['ban']['tail'] = \
|
||||||
|
|
|
@ -21,7 +21,7 @@ before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
_daemon = fail2ban\.server\.actions
|
_daemon = fail2ban\.actions\s*
|
||||||
|
|
||||||
# The name of the jail that this filter is used for. In jail.conf, name the
|
# The name of the jail that this filter is used for. In jail.conf, name the
|
||||||
# jail using this filter 'recidive', or change this line!
|
# jail using this filter 'recidive', or change this line!
|
||||||
|
|
|
@ -24,12 +24,13 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging, os
|
import os
|
||||||
|
|
||||||
from .configreader import ConfigReader, DefinitionInitConfigReader
|
from .configreader import ConfigReader, DefinitionInitConfigReader
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class ActionReader(DefinitionInitConfigReader):
|
class ActionReader(DefinitionInitConfigReader):
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,11 @@ __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 logging
|
|
||||||
|
|
||||||
from ..exceptions import UnknownJailException, DuplicateJailException
|
from ..exceptions import UnknownJailException, DuplicateJailException
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
##
|
##
|
||||||
# Beautify the output of the client.
|
# Beautify the output of the client.
|
||||||
|
|
|
@ -24,7 +24,8 @@ __author__ = 'Yaroslav Halhenko'
|
||||||
__copyright__ = 'Copyright (c) 2007 Yaroslav Halchenko'
|
__copyright__ = 'Copyright (c) 2007 Yaroslav Halchenko'
|
||||||
__license__ = 'GPL'
|
__license__ = 'GPL'
|
||||||
|
|
||||||
import logging, os, sys
|
import os, sys
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
if sys.version_info >= (3,2): # pragma: no cover
|
if sys.version_info >= (3,2): # pragma: no cover
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ else: # pragma: no cover
|
||||||
from ConfigParser import SafeConfigParser
|
from ConfigParser import SafeConfigParser
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
__all__ = ['SafeConfigParserWithIncludes']
|
__all__ = ['SafeConfigParserWithIncludes']
|
||||||
|
|
||||||
|
|
|
@ -24,13 +24,14 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import glob, logging, os
|
import glob, os
|
||||||
from ConfigParser import NoOptionError, NoSectionError
|
from ConfigParser import NoOptionError, NoSectionError
|
||||||
|
|
||||||
from .configparserinc import SafeConfigParserWithIncludes
|
from .configparserinc import SafeConfigParserWithIncludes
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class ConfigReader(SafeConfigParserWithIncludes):
|
class ConfigReader(SafeConfigParserWithIncludes):
|
||||||
|
|
||||||
|
|
|
@ -24,13 +24,12 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from .fail2banreader import Fail2banReader
|
from .fail2banreader import Fail2banReader
|
||||||
from .jailsreader import JailsReader
|
from .jailsreader import JailsReader
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class Configurator:
|
class Configurator:
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,11 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from .configreader import ConfigReader
|
from .configreader import ConfigReader
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class Fail2banReader(ConfigReader):
|
class Fail2banReader(ConfigReader):
|
||||||
|
|
||||||
|
|
|
@ -24,13 +24,14 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging, os, shlex
|
import os, shlex
|
||||||
|
|
||||||
from .configreader import ConfigReader, DefinitionInitConfigReader
|
from .configreader import ConfigReader, DefinitionInitConfigReader
|
||||||
from ..server.action import CommandAction
|
from ..server.action import CommandAction
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class FilterReader(DefinitionInitConfigReader):
|
class FilterReader(DefinitionInitConfigReader):
|
||||||
|
|
||||||
|
|
|
@ -24,15 +24,16 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging, re, glob, os.path
|
import re, glob, os.path
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from .configreader import ConfigReader
|
from .configreader import ConfigReader
|
||||||
from .filterreader import FilterReader
|
from .filterreader import FilterReader
|
||||||
from .actionreader import ActionReader
|
from .actionreader import ActionReader
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class JailReader(ConfigReader):
|
class JailReader(ConfigReader):
|
||||||
|
|
||||||
|
|
|
@ -24,13 +24,12 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from .configreader import ConfigReader
|
from .configreader import ConfigReader
|
||||||
from .jailreader import JailReader
|
from .jailreader import JailReader
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class JailsReader(ConfigReader):
|
class JailsReader(ConfigReader):
|
||||||
|
|
||||||
|
|
|
@ -107,3 +107,17 @@ class FormatterWithTraceBack(logging.Formatter):
|
||||||
def format(self, record):
|
def format(self, record):
|
||||||
record.tbc = record.tb = self._tb()
|
record.tbc = record.tb = self._tb()
|
||||||
return logging.Formatter.format(self, record)
|
return logging.Formatter.format(self, record)
|
||||||
|
|
||||||
|
def getLogger(name):
|
||||||
|
"""Get logging.Logger instance with Fail2Ban logger name convention
|
||||||
|
"""
|
||||||
|
if "." in name:
|
||||||
|
name = "fail2ban.%s" % name.rpartition(".")[-1]
|
||||||
|
return logging.getLogger(name)
|
||||||
|
|
||||||
|
def excepthook(exctype, value, traceback):
|
||||||
|
"""Except hook used to log unhandled exceptions to Fail2Ban log
|
||||||
|
"""
|
||||||
|
getLogger("fail2ban").critical(
|
||||||
|
"Unhandled exception in Fail2Ban:", exc_info=True)
|
||||||
|
return sys.__excepthook__(exctype, value, traceback)
|
||||||
|
|
|
@ -25,10 +25,11 @@ import logging, os, subprocess, time, signal, tempfile
|
||||||
import threading, re
|
import threading, re
|
||||||
from abc import ABCMeta
|
from abc import ABCMeta
|
||||||
from collections import MutableMapping
|
from collections import MutableMapping
|
||||||
#from subprocess import call
|
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
# Create a lock for running system commands
|
# Create a lock for running system commands
|
||||||
_cmd_lock = threading.Lock()
|
_cmd_lock = threading.Lock()
|
||||||
|
@ -68,6 +69,9 @@ class CallingMap(MutableMapping):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.data = dict(*args, **kwargs)
|
self.data = dict(*args, **kwargs)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "%s(%r)" % (self.__class__.__name__, self.data)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
value = self.data[key]
|
value = self.data[key]
|
||||||
if callable(value):
|
if callable(value):
|
||||||
|
@ -87,6 +91,9 @@ class CallingMap(MutableMapping):
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self.data)
|
return len(self.data)
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
return self.__class__(self.data.copy())
|
||||||
|
|
||||||
class ActionBase(object):
|
class ActionBase(object):
|
||||||
"""An abstract base class for actions in Fail2Ban.
|
"""An abstract base class for actions in Fail2Ban.
|
||||||
|
|
||||||
|
@ -135,8 +142,7 @@ class ActionBase(object):
|
||||||
def __init__(self, jail, name):
|
def __init__(self, jail, name):
|
||||||
self._jail = jail
|
self._jail = jail
|
||||||
self._name = name
|
self._name = name
|
||||||
self._logSys = logging.getLogger(
|
self._logSys = getLogger("fail2ban.%s" % self.__class__.__name__)
|
||||||
'%s.%s' % (__name__, self.__class__.__name__))
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""Executed when the jail/action is started.
|
"""Executed when the jail/action is started.
|
||||||
|
|
|
@ -42,9 +42,10 @@ from .observer import Observers
|
||||||
from .jailthread import JailThread
|
from .jailthread import JailThread
|
||||||
from .action import ActionBase, CommandAction, CallingMap
|
from .action import ActionBase, CommandAction, CallingMap
|
||||||
from .mytime import MyTime
|
from .mytime import MyTime
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class Actions(JailThread, Mapping):
|
class Actions(JailThread, Mapping):
|
||||||
"""Handles jail actions.
|
"""Handles jail actions.
|
||||||
|
@ -299,11 +300,12 @@ class Actions(JailThread, Mapping):
|
||||||
# do actions :
|
# do actions :
|
||||||
for name, action in self._actions.iteritems():
|
for name, action in self._actions.iteritems():
|
||||||
try:
|
try:
|
||||||
action.ban(aInfo)
|
action.ban(aInfo.copy())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logSys.error(
|
logSys.error(
|
||||||
"Failed to execute ban jail '%s' action '%s': %s",
|
"Failed to execute ban jail '%s' action '%s' "
|
||||||
self._jail.name, name, e,
|
"info '%r': %s",
|
||||||
|
self._jail.name, name, aInfo, e,
|
||||||
exc_info=logSys.getEffectiveLevel()<=logging.DEBUG)
|
exc_info=logSys.getEffectiveLevel()<=logging.DEBUG)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
|
@ -347,11 +349,12 @@ class Actions(JailThread, Mapping):
|
||||||
logSys.notice("[%s] Unban %s" % (self._jail.name, aInfo["ip"]))
|
logSys.notice("[%s] Unban %s" % (self._jail.name, aInfo["ip"]))
|
||||||
for name, action in self._actions.iteritems():
|
for name, action in self._actions.iteritems():
|
||||||
try:
|
try:
|
||||||
action.unban(aInfo)
|
action.unban(aInfo.copy())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logSys.error(
|
logSys.error(
|
||||||
"Failed to execute unban jail '%s' action '%s': %s",
|
"Failed to execute unban jail '%s' action '%s' "
|
||||||
self._jail.name, name, e,
|
"info '%r': %s",
|
||||||
|
self._jail.name, name, aInfo, e,
|
||||||
exc_info=logSys.getEffectiveLevel()<=logging.DEBUG)
|
exc_info=logSys.getEffectiveLevel()<=logging.DEBUG)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -25,12 +25,12 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
from pickle import dumps, loads, HIGHEST_PROTOCOL
|
from pickle import dumps, loads, HIGHEST_PROTOCOL
|
||||||
import asyncore, asynchat, socket, os, logging, sys, traceback, fcntl
|
import asyncore, asynchat, socket, os, sys, traceback, fcntl
|
||||||
|
|
||||||
from .. import helpers
|
from ..helpers import getLogger,formatExceptionInfo
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
if sys.version_info >= (3,):
|
if sys.version_info >= (3,):
|
||||||
# b"" causes SyntaxError in python <= 2.5, so below implements equivalent
|
# b"" causes SyntaxError in python <= 2.5, so below implements equivalent
|
||||||
|
@ -81,7 +81,7 @@ class RequestHandler(asynchat.async_chat):
|
||||||
self.close_when_done()
|
self.close_when_done()
|
||||||
|
|
||||||
def handle_error(self):
|
def handle_error(self):
|
||||||
e1, e2 = helpers.formatExceptionInfo()
|
e1, e2 = formatExceptionInfo()
|
||||||
logSys.error("Unexpected communication error: %s" % str(e2))
|
logSys.error("Unexpected communication error: %s" % str(e2))
|
||||||
logSys.error(traceback.format_exc().splitlines())
|
logSys.error(traceback.format_exc().splitlines())
|
||||||
self.close()
|
self.close()
|
||||||
|
|
|
@ -24,14 +24,14 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging
|
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
|
||||||
from .ticket import BanTicket
|
from .ticket import BanTicket
|
||||||
from .mytime import MyTime
|
from .mytime import MyTime
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
##
|
##
|
||||||
# Banning Manager.
|
# Banning Manager.
|
||||||
|
|
|
@ -21,7 +21,6 @@ __author__ = "Steven Hiscocks"
|
||||||
__copyright__ = "Copyright (c) 2013 Steven Hiscocks"
|
__copyright__ = "Copyright (c) 2013 Steven Hiscocks"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging
|
|
||||||
import sys
|
import sys
|
||||||
import shutil, time
|
import shutil, time
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
@ -32,9 +31,10 @@ from threading import Lock
|
||||||
|
|
||||||
from .mytime import MyTime
|
from .mytime import MyTime
|
||||||
from .ticket import FailTicket
|
from .ticket import FailTicket
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
if sys.version_info >= (3,):
|
if sys.version_info >= (3,):
|
||||||
sqlite3.register_adapter(
|
sqlite3.register_adapter(
|
||||||
|
|
|
@ -21,13 +21,13 @@ __author__ = "Cyril Jaquier and Fail2Ban Contributors"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging
|
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
|
||||||
from .datetemplate import DatePatternRegex, DateTai64n, DateEpoch
|
from .datetemplate import DatePatternRegex, DateTai64n, DateEpoch
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class DateDetector(object):
|
class DateDetector(object):
|
||||||
"""Manages one or more date templates to find a date within a log line.
|
"""Manages one or more date templates to find a date within a log line.
|
||||||
|
|
|
@ -25,12 +25,12 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import logging
|
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
|
|
||||||
from .strptime import reGroupDictStrptime, timeRE
|
from .strptime import reGroupDictStrptime, timeRE
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DateTemplate(object):
|
class DateTemplate(object):
|
||||||
|
|
|
@ -24,10 +24,10 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class FailData:
|
class FailData:
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,10 @@ import logging
|
||||||
|
|
||||||
from .faildata import FailData
|
from .faildata import FailData
|
||||||
from .ticket import FailTicket
|
from .ticket import FailTicket
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class FailManager:
|
class FailManager:
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ __author__ = "Cyril Jaquier and Fail2Ban Contributors"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging, re, os, fcntl, sys, locale, codecs, datetime
|
import re, os, fcntl, sys, locale, codecs, datetime
|
||||||
|
|
||||||
from .failmanager import FailManagerEmpty, FailManager
|
from .failmanager import FailManagerEmpty, FailManager
|
||||||
from .observer import Observers
|
from .observer import Observers
|
||||||
|
@ -32,9 +32,10 @@ from .datetemplate import DatePatternRegex, DateEpoch, DateTai64n
|
||||||
from .mytime import MyTime
|
from .mytime import MyTime
|
||||||
from .failregex import FailRegex, Regex, RegexException
|
from .failregex import FailRegex, Regex, RegexException
|
||||||
from .action import CommandAction
|
from .action import CommandAction
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
##
|
##
|
||||||
# Log reader class.
|
# Log reader class.
|
||||||
|
|
|
@ -23,16 +23,17 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2012 Yaroslav Halchenko"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2012 Yaroslav Halchenko"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import time, logging, fcntl
|
import time, fcntl
|
||||||
|
|
||||||
import gamin
|
import gamin
|
||||||
|
|
||||||
from .failmanager import FailManagerEmpty
|
from .failmanager import FailManagerEmpty
|
||||||
from .filter import FileFilter
|
from .filter import FileFilter
|
||||||
from .mytime import MyTime
|
from .mytime import MyTime
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
##
|
##
|
||||||
# Log reader class.
|
# Log reader class.
|
||||||
|
|
|
@ -24,14 +24,15 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier; 2012 Yaroslav Halchenko"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier; 2012 Yaroslav Halchenko"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import time, logging, os
|
import time, os
|
||||||
|
|
||||||
from .failmanager import FailManagerEmpty
|
from .failmanager import FailManagerEmpty
|
||||||
from .filter import FileFilter
|
from .filter import FileFilter
|
||||||
from .mytime import MyTime
|
from .mytime import MyTime
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
##
|
##
|
||||||
# Log reader class.
|
# Log reader class.
|
||||||
|
|
|
@ -32,6 +32,7 @@ import pyinotify
|
||||||
from .failmanager import FailManagerEmpty
|
from .failmanager import FailManagerEmpty
|
||||||
from .filter import FileFilter
|
from .filter import FileFilter
|
||||||
from .mytime import MyTime
|
from .mytime import MyTime
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
|
|
||||||
if not hasattr(pyinotify, '__version__') \
|
if not hasattr(pyinotify, '__version__') \
|
||||||
|
@ -48,7 +49,7 @@ except Exception, e:
|
||||||
% str(e))
|
% str(e))
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
##
|
##
|
||||||
# Log reader class.
|
# Log reader class.
|
||||||
|
|
|
@ -22,7 +22,7 @@ __author__ = "Steven Hiscocks"
|
||||||
__copyright__ = "Copyright (c) 2013 Steven Hiscocks"
|
__copyright__ = "Copyright (c) 2013 Steven Hiscocks"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging, datetime, time
|
import datetime, time
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
|
|
||||||
from systemd import journal
|
from systemd import journal
|
||||||
|
@ -32,10 +32,10 @@ if LooseVersion(getattr(journal, '__version__', "0")) < '204':
|
||||||
from .failmanager import FailManagerEmpty
|
from .failmanager import FailManagerEmpty
|
||||||
from .filter import JournalFilter
|
from .filter import JournalFilter
|
||||||
from .mytime import MyTime
|
from .mytime import MyTime
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger("fail2ban.filter")
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
##
|
##
|
||||||
# Journal reader class.
|
# Journal reader class.
|
||||||
|
|
|
@ -26,10 +26,11 @@ __license__ = "GPL"
|
||||||
import Queue, logging, math, random
|
import Queue, logging, math, random
|
||||||
|
|
||||||
from .actions import Actions
|
from .actions import Actions
|
||||||
|
from ..helpers import getLogger
|
||||||
from .mytime import MyTime
|
from .mytime import MyTime
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class Jail:
|
class Jail:
|
||||||
"""Fail2Ban jail, which manages a filter and associated actions.
|
"""Fail2Ban jail, which manages a filter and associated actions.
|
||||||
|
|
|
@ -24,9 +24,12 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
|
import sys
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from abc import abstractproperty, abstractmethod
|
from abc import abstractproperty, abstractmethod
|
||||||
|
|
||||||
|
from ..helpers import excepthook
|
||||||
|
|
||||||
class JailThread(Thread):
|
class JailThread(Thread):
|
||||||
"""Abstract class for threading elements in Fail2Ban.
|
"""Abstract class for threading elements in Fail2Ban.
|
||||||
|
|
||||||
|
@ -53,6 +56,16 @@ class JailThread(Thread):
|
||||||
## The time the thread sleeps in the loop.
|
## The time the thread sleeps in the loop.
|
||||||
self.sleeptime = 1
|
self.sleeptime = 1
|
||||||
|
|
||||||
|
# excepthook workaround for threads, derived from:
|
||||||
|
# http://bugs.python.org/issue1230540#msg91244
|
||||||
|
run = self.run
|
||||||
|
def run_with_except_hook(*args, **kwargs):
|
||||||
|
try:
|
||||||
|
run(*args, **kwargs)
|
||||||
|
except:
|
||||||
|
excepthook(*sys.exc_info())
|
||||||
|
self.run = run_with_except_hook
|
||||||
|
|
||||||
@abstractproperty
|
@abstractproperty
|
||||||
def status(self): # pragma: no cover - abstract
|
def status(self): # pragma: no cover - abstract
|
||||||
"""Abstract - Should provide status information.
|
"""Abstract - Should provide status information.
|
||||||
|
|
|
@ -25,14 +25,14 @@ __author__ = "Serg G. Brester (sebres)"
|
||||||
__copyright__ = "Copyright (c) 2014 Serg G. Brester"
|
__copyright__ = "Copyright (c) 2014 Serg G. Brester"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import time, logging
|
|
||||||
import threading
|
import threading
|
||||||
import os, datetime, math, json, random
|
import os, time, datetime, math, json, random
|
||||||
import sys
|
import sys
|
||||||
|
from ..helpers import getLogger
|
||||||
from .mytime import MyTime
|
from .mytime import MyTime
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class ObserverThread(threading.Thread):
|
class ObserverThread(threading.Thread):
|
||||||
"""Handles observing a database, managing bad ips and ban increment.
|
"""Handles observing a database, managing bad ips and ban increment.
|
||||||
|
|
|
@ -33,9 +33,10 @@ from .filter import FileFilter, JournalFilter
|
||||||
from .transmitter import Transmitter
|
from .transmitter import Transmitter
|
||||||
from .asyncserver import AsyncServer, AsyncServerException
|
from .asyncserver import AsyncServer, AsyncServerException
|
||||||
from .. import version
|
from .. import version
|
||||||
|
from ..helpers import getLogger, excepthook
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from .database import Fail2BanDb
|
from .database import Fail2BanDb
|
||||||
|
@ -70,6 +71,9 @@ class Server:
|
||||||
signal.signal(signal.SIGTERM, self.__sigTERMhandler)
|
signal.signal(signal.SIGTERM, self.__sigTERMhandler)
|
||||||
signal.signal(signal.SIGINT, self.__sigTERMhandler)
|
signal.signal(signal.SIGINT, self.__sigTERMhandler)
|
||||||
|
|
||||||
|
# Ensure unhandled exceptions are logged
|
||||||
|
sys.excepthook = excepthook
|
||||||
|
|
||||||
# First set the mask to only allow access to owner
|
# First set the mask to only allow access to owner
|
||||||
os.umask(0077)
|
os.umask(0077)
|
||||||
if self.__daemon: # pragma: no cover
|
if self.__daemon: # pragma: no cover
|
||||||
|
@ -352,7 +356,7 @@ class Server:
|
||||||
def setLogLevel(self, value):
|
def setLogLevel(self, value):
|
||||||
try:
|
try:
|
||||||
self.__loggingLock.acquire()
|
self.__loggingLock.acquire()
|
||||||
logging.getLogger(__name__).parent.parent.setLevel(
|
getLogger("fail2ban").setLevel(
|
||||||
getattr(logging, value.upper()))
|
getattr(logging, value.upper()))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise ValueError("Invalid log level")
|
raise ValueError("Invalid log level")
|
||||||
|
@ -384,7 +388,7 @@ class Server:
|
||||||
try:
|
try:
|
||||||
self.__loggingLock.acquire()
|
self.__loggingLock.acquire()
|
||||||
# set a format which is simpler for console use
|
# set a format which is simpler for console use
|
||||||
formatter = logging.Formatter("%(asctime)s %(name)-16s[%(process)d]: %(levelname)-7s %(message)s")
|
formatter = logging.Formatter("%(asctime)s %(name)-24s[%(process)d]: %(levelname)-7s %(message)s")
|
||||||
if target == "SYSLOG":
|
if target == "SYSLOG":
|
||||||
# Syslog daemons already add date to the message.
|
# Syslog daemons already add date to the message.
|
||||||
formatter = logging.Formatter("%(name)s[%(process)d]: %(levelname)s %(message)s")
|
formatter = logging.Formatter("%(name)s[%(process)d]: %(levelname)s %(message)s")
|
||||||
|
@ -405,7 +409,7 @@ class Server:
|
||||||
return False
|
return False
|
||||||
# Removes previous handlers -- in reverse order since removeHandler
|
# Removes previous handlers -- in reverse order since removeHandler
|
||||||
# alter the list in-place and that can confuses the iterable
|
# alter the list in-place and that can confuses the iterable
|
||||||
logger = logging.getLogger(__name__).parent.parent
|
logger = getLogger("fail2ban")
|
||||||
for handler in logger.handlers[::-1]:
|
for handler in logger.handlers[::-1]:
|
||||||
# Remove the handler.
|
# Remove the handler.
|
||||||
logger.removeHandler(handler)
|
logger.removeHandler(handler)
|
||||||
|
@ -442,7 +446,7 @@ class Server:
|
||||||
|
|
||||||
def flushLogs(self):
|
def flushLogs(self):
|
||||||
if self.__logTarget not in ['STDERR', 'STDOUT', 'SYSLOG']:
|
if self.__logTarget not in ['STDERR', 'STDOUT', 'SYSLOG']:
|
||||||
for handler in logging.getLogger(__name__).parent.parent.handlers:
|
for handler in getLogger("fail2ban").handlers:
|
||||||
try:
|
try:
|
||||||
handler.doRollover()
|
handler.doRollover()
|
||||||
logSys.info("rollover performed on %s" % self.__logTarget)
|
logSys.info("rollover performed on %s" % self.__logTarget)
|
||||||
|
@ -451,7 +455,7 @@ class Server:
|
||||||
logSys.info("flush performed on %s" % self.__logTarget)
|
logSys.info("flush performed on %s" % self.__logTarget)
|
||||||
return "rolled over"
|
return "rolled over"
|
||||||
else:
|
else:
|
||||||
for handler in logging.getLogger(__name__).parent.parent.handlers:
|
for handler in getLogger("fail2ban").handlers:
|
||||||
handler.flush()
|
handler.flush()
|
||||||
logSys.info("flush performed on %s" % self.__logTarget)
|
logSys.info("flush performed on %s" % self.__logTarget)
|
||||||
return "flushed"
|
return "flushed"
|
||||||
|
|
|
@ -24,14 +24,15 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging
|
from ..helpers import getLogger
|
||||||
|
from .mytime import MyTime
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class Ticket:
|
class Ticket:
|
||||||
|
|
||||||
def __init__(self, ip, time, matches=None):
|
def __init__(self, ip, time=None, matches=None):
|
||||||
"""Ticket constructor
|
"""Ticket constructor
|
||||||
|
|
||||||
@param ip the IP address
|
@param ip the IP address
|
||||||
|
@ -43,7 +44,7 @@ class Ticket:
|
||||||
self.__restored = False;
|
self.__restored = False;
|
||||||
self.__banCount = 0;
|
self.__banCount = 0;
|
||||||
self.__banTime = None;
|
self.__banTime = None;
|
||||||
self.__time = time
|
self.__time = time if time is not None else MyTime.time()
|
||||||
self.__attempt = 0
|
self.__attempt = 0
|
||||||
self.__file = None
|
self.__file = None
|
||||||
self.__matches = matches or []
|
self.__matches = matches or []
|
||||||
|
|
|
@ -24,11 +24,13 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging, time
|
import time
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
class Transmitter:
|
class Transmitter:
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import os
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from ..server.actions import Actions
|
from ..server.actions import Actions
|
||||||
|
from ..server.ticket import FailTicket
|
||||||
from .dummyjail import DummyJail
|
from .dummyjail import DummyJail
|
||||||
from .utils import LogCaptureTestCase
|
from .utils import LogCaptureTestCase
|
||||||
|
|
||||||
|
@ -141,3 +142,27 @@ class ExecuteActions(LogCaptureTestCase):
|
||||||
self.__actions.join()
|
self.__actions.join()
|
||||||
self.assertTrue(self._is_logged("Failed to stop"))
|
self.assertTrue(self._is_logged("Failed to stop"))
|
||||||
|
|
||||||
|
def testBanActionsAInfo(self):
|
||||||
|
# Action which deletes IP address from aInfo
|
||||||
|
self.__actions.add(
|
||||||
|
"action1",
|
||||||
|
os.path.join(TEST_FILES_DIR, "action.d/action_modifyainfo.py"),
|
||||||
|
{})
|
||||||
|
self.__actions.add(
|
||||||
|
"action2",
|
||||||
|
os.path.join(TEST_FILES_DIR, "action.d/action_modifyainfo.py"),
|
||||||
|
{})
|
||||||
|
self.__jail.putFailTicket(FailTicket("1.2.3.4"))
|
||||||
|
self.__actions._Actions__checkBan()
|
||||||
|
# Will fail if modification of aInfo from first action propagates
|
||||||
|
# to second action, as both delete same key
|
||||||
|
self.assertFalse(self._is_logged("Failed to execute ban"))
|
||||||
|
self.assertTrue(self._is_logged("action1 ban deleted aInfo IP"))
|
||||||
|
self.assertTrue(self._is_logged("action2 ban deleted aInfo IP"))
|
||||||
|
|
||||||
|
self.__actions._Actions__flushBan()
|
||||||
|
# Will fail if modification of aInfo from first action propagates
|
||||||
|
# to second action, as both delete same key
|
||||||
|
self.assertFalse(self._is_logged("Failed to execute unban"))
|
||||||
|
self.assertTrue(self._is_logged("action1 unban deleted aInfo IP"))
|
||||||
|
self.assertTrue(self._is_logged("action2 unban deleted aInfo IP"))
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
from fail2ban.server.action import ActionBase
|
||||||
|
|
||||||
|
class TestAction(ActionBase):
|
||||||
|
|
||||||
|
def ban(self, aInfo):
|
||||||
|
del aInfo['ip']
|
||||||
|
self._logSys.info("%s ban deleted aInfo IP", self._name)
|
||||||
|
|
||||||
|
def unban(self, aInfo):
|
||||||
|
del aInfo['ip']
|
||||||
|
self._logSys.info("%s unban deleted aInfo IP", self._name)
|
||||||
|
|
||||||
|
Action = TestAction
|
|
@ -1,14 +1,14 @@
|
||||||
# failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4" }
|
# failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4" }
|
||||||
2006-02-13 15:52:30,388 fail2ban.server.actions: NOTICE [sendmail] Ban 1.2.3.4
|
2006-02-13 15:52:30,388 fail2ban.actions: NOTICE [sendmail] Ban 1.2.3.4
|
||||||
# failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4", "desc": "Extended with [PID]" }
|
# failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4", "desc": "Extended with [PID]" }
|
||||||
2006-02-13 15:52:30,388 fail2ban.server.actions[123]: NOTICE [sendmail] Ban 1.2.3.4
|
2006-02-13 15:52:30,388 fail2ban.actions[123]: NOTICE [sendmail] Ban 1.2.3.4
|
||||||
# failJSON: { "match": false }
|
# failJSON: { "match": false }
|
||||||
2006-02-13 16:07:31,183 fail2ban.server.actions: NOTICE [sendmail] Unban 1.2.3.4
|
2006-02-13 16:07:31,183 fail2ban.actions: NOTICE [sendmail] Unban 1.2.3.4
|
||||||
# failJSON: { "match": false }
|
# failJSON: { "match": false }
|
||||||
2006-02-13 15:52:30,388 fail2ban.server.actions: NOTICE [recidive] Ban 1.2.3.4
|
2006-02-13 15:52:30,388 fail2ban.actions: NOTICE [recidive] Ban 1.2.3.4
|
||||||
# syslog example
|
# syslog example
|
||||||
# failJSON: { "time": "2004-09-16T00:44:55", "match": true , "host": "10.0.0.7" }
|
# failJSON: { "time": "2004-09-16T00:44:55", "match": true , "host": "10.0.0.7" }
|
||||||
Sep 16 00:44:55 spaceman fail2ban.server.actions: NOTICE [jail] Ban 10.0.0.7
|
Sep 16 00:44:55 spaceman fail2ban.actions: NOTICE [jail] Ban 10.0.0.7
|
||||||
|
|
||||||
# failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4", "desc": "Extended with [PID] and padding" }
|
# failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4", "desc": "Extended with [PID] and padding" }
|
||||||
2006-02-13 15:52:30,388 fail2ban.server.actions[123]: NOTICE [sendmail] Ban 1.2.3.4
|
2006-02-13 15:52:30,388 fail2ban.actions [123]: NOTICE [sendmail] Ban 1.2.3.4
|
||||||
|
|
|
@ -32,7 +32,7 @@ import datetime
|
||||||
from glob import glob
|
from glob import glob
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
|
||||||
from ..helpers import formatExceptionInfo, mbasename, TraceBack, FormatterWithTraceBack
|
from ..helpers import formatExceptionInfo, mbasename, TraceBack, FormatterWithTraceBack, getLogger
|
||||||
from ..server.datetemplate import DatePatternRegex
|
from ..server.datetemplate import DatePatternRegex
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ class TestsUtilsTest(unittest.TestCase):
|
||||||
|
|
||||||
# and both types of traceback at once
|
# and both types of traceback at once
|
||||||
fmt = ' %(tb)s | %(tbc)s : %(message)s'
|
fmt = ' %(tb)s | %(tbc)s : %(message)s'
|
||||||
logSys = logging.getLogger("fail2ban_tests")
|
logSys = getLogger("fail2ban_tests")
|
||||||
out = logging.StreamHandler(strout)
|
out = logging.StreamHandler(strout)
|
||||||
out.setFormatter(Formatter(fmt))
|
out.setFormatter(Formatter(fmt))
|
||||||
logSys.addHandler(out)
|
logSys.addHandler(out)
|
||||||
|
|
|
@ -30,11 +30,13 @@ import tempfile
|
||||||
import os
|
import os
|
||||||
import locale
|
import locale
|
||||||
import sys
|
import sys
|
||||||
import logging
|
|
||||||
|
|
||||||
from ..server.failregex import Regex, FailRegex, RegexException
|
from ..server.failregex import Regex, FailRegex, RegexException
|
||||||
from ..server.server import Server
|
from ..server.server import Server
|
||||||
from ..server.jail import Jail
|
from ..server.jail import Jail
|
||||||
|
from ..server.jailthread import JailThread
|
||||||
|
from .utils import LogCaptureTestCase
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ..server import filtersystemd
|
from ..server import filtersystemd
|
||||||
|
@ -722,7 +724,7 @@ class TransmitterLogging(TransmitterBase):
|
||||||
os.close(f)
|
os.close(f)
|
||||||
self.server.setLogLevel("WARNING")
|
self.server.setLogLevel("WARNING")
|
||||||
self.assertEqual(self.transm.proceed(["set", "logtarget", fn]), (0, fn))
|
self.assertEqual(self.transm.proceed(["set", "logtarget", fn]), (0, fn))
|
||||||
l = logging.getLogger('fail2ban.server.server').parent.parent
|
l = getLogger('fail2ban')
|
||||||
l.warning("Before file moved")
|
l.warning("Before file moved")
|
||||||
try:
|
try:
|
||||||
f2, fn2 = tempfile.mkstemp("fail2ban.log")
|
f2, fn2 = tempfile.mkstemp("fail2ban.log")
|
||||||
|
@ -804,5 +806,33 @@ class RegexTests(unittest.TestCase):
|
||||||
self.assertTrue(fr.hasMatched())
|
self.assertTrue(fr.hasMatched())
|
||||||
self.assertRaises(RegexException, fr.getHost)
|
self.assertRaises(RegexException, fr.getHost)
|
||||||
|
|
||||||
|
class _BadThread(JailThread):
|
||||||
|
def run(self):
|
||||||
|
raise RuntimeError('run bad thread exception')
|
||||||
|
|
||||||
|
class LoggingTests(LogCaptureTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""Call before every test case."""
|
||||||
|
LogCaptureTestCase.setUp(self)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""Call after every test case."""
|
||||||
|
LogCaptureTestCase.tearDown(self)
|
||||||
|
|
||||||
|
def testGetF2BLogger(self):
|
||||||
|
testLogSys = getLogger("fail2ban.some.string.with.name")
|
||||||
|
self.assertEqual(testLogSys.parent.name, "fail2ban")
|
||||||
|
self.assertEqual(testLogSys.name, "fail2ban.name")
|
||||||
|
|
||||||
|
def testFail2BanExceptHook(self):
|
||||||
|
prev_exchook = sys.__excepthook__
|
||||||
|
x = []
|
||||||
|
sys.__excepthook__ = lambda *args: x.append(args)
|
||||||
|
badThread = _BadThread()
|
||||||
|
badThread.start()
|
||||||
|
badThread.join()
|
||||||
|
self.assertTrue(self._is_logged("Unhandled exception"))
|
||||||
|
sys.__excepthook__ = prev_exchook
|
||||||
|
self.assertEqual(len(x), 1)
|
||||||
|
self.assertEqual(x[0][0], RuntimeError)
|
||||||
|
|
|
@ -30,8 +30,9 @@ import unittest
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
|
||||||
from ..server.mytime import MyTime
|
from ..server.mytime import MyTime
|
||||||
|
from ..helpers import getLogger
|
||||||
|
|
||||||
logSys = logging.getLogger(__name__)
|
logSys = getLogger(__name__)
|
||||||
|
|
||||||
def mtimesleep():
|
def mtimesleep():
|
||||||
# no sleep now should be necessary since polling tracks now not only
|
# no sleep now should be necessary since polling tracks now not only
|
||||||
|
@ -90,6 +91,7 @@ def gatherTests(regexps=None, no_network=False):
|
||||||
tests.addTest(unittest.makeSuite(servertestcase.Transmitter))
|
tests.addTest(unittest.makeSuite(servertestcase.Transmitter))
|
||||||
tests.addTest(unittest.makeSuite(servertestcase.JailTests))
|
tests.addTest(unittest.makeSuite(servertestcase.JailTests))
|
||||||
tests.addTest(unittest.makeSuite(servertestcase.RegexTests))
|
tests.addTest(unittest.makeSuite(servertestcase.RegexTests))
|
||||||
|
tests.addTest(unittest.makeSuite(servertestcase.LoggingTests))
|
||||||
tests.addTest(unittest.makeSuite(actiontestcase.CommandActionTest))
|
tests.addTest(unittest.makeSuite(actiontestcase.CommandActionTest))
|
||||||
tests.addTest(unittest.makeSuite(actionstestcase.ExecuteActions))
|
tests.addTest(unittest.makeSuite(actionstestcase.ExecuteActions))
|
||||||
# FailManager
|
# FailManager
|
||||||
|
@ -190,7 +192,7 @@ class LogCaptureTestCase(unittest.TestCase):
|
||||||
|
|
||||||
# For extended testing of what gets output into logging
|
# For extended testing of what gets output into logging
|
||||||
# system, we will redirect it to a string
|
# system, we will redirect it to a string
|
||||||
logSys = logging.getLogger("fail2ban")
|
logSys = getLogger("fail2ban")
|
||||||
|
|
||||||
# Keep old settings
|
# Keep old settings
|
||||||
self._old_level = logSys.level
|
self._old_level = logSys.level
|
||||||
|
@ -203,7 +205,7 @@ class LogCaptureTestCase(unittest.TestCase):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
"""Call after every test case."""
|
"""Call after every test case."""
|
||||||
# print "O: >>%s<<" % self._log.getvalue()
|
# print "O: >>%s<<" % self._log.getvalue()
|
||||||
logSys = logging.getLogger("fail2ban")
|
logSys = getLogger("fail2ban")
|
||||||
logSys.handlers = self._old_handlers
|
logSys.handlers = self._old_handlers
|
||||||
logSys.level = self._old_level
|
logSys.level = self._old_level
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue