Releasing 0.8.9

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iEYEABECAAYFAlGRAHAACgkQjRFFY3XAJMjEJgCfUbU4Xwf04y1V0DwXrXBDNtN4
 Ye0AoJ3YZWbxvKoWVnLeY2PtR1QDHyCq
 =FbPM
 -----END PGP SIGNATURE-----

Merge tag '0.8.9' into debian

Releasing 0.8.9

* tag '0.8.9': (46 commits)
  All the (version) updates for the release of 0.8.9
  BF: (travis) relax the test for needed to be presented installed directories -- allow new
  BF: (travis) if tests ran under coverage -- there is a traceback parts to report (thus > would be present)
  ENH: also print the failing traceback line in case of failure
  ENH: include explicit list of new files which should not be there upon "install --root"
  ENH: now we know that logging handlers closing was still buggy in 2.6.2
  ENH: issue a warning if jail name is longer than 19 symbols (Close #222)
  DOC: inline commends with ';' are in effect only if ';' follows as space
  BF: Fix for filterpoll incorrectly checking for jailless state
  ENH: strengthen detection of working pyinotify
  ENH: use the same python executable for setup.py test
  ENH: actually tune up TraceBack to determine "unittest" portions of the stack across all python  releases
  TST: Some primarily smoke tests for tests utils
  TST: cover few more lines in fail2banreader.py
  ENH: basic test for setup.py itself (when applicable, should greatly improve coverage ;) )
  ENH: consistent operation of formatExceptionInfo + unittest for it
  ENH: point to the status of master branch on travis
  ENH: close open file in a test
  Previous coverage was 56% (without disregarding any pragma)
  ENH: close files in _test_move_into_file
  ...
pull/808/head
Yaroslav Halchenko 2013-05-13 11:02:40 -04:00
commit a0b20c642c
61 changed files with 770 additions and 134 deletions

View File

@ -4,26 +4,30 @@
|_| \__,_|_|_/___|_.__/\__,_|_||_|
================================================================================
Fail2Ban (version 0.8.9) 2013/04/XX
Fail2Ban (version 0.8.9) 2013/05/13
================================================================================
ver. 0.8.9 (2013/04/XX) - wanna-be-stable
ver. 0.8.9 (2013/05/13) - wanna-be-stable
----------
Although primarily a bugfix release, it incorporates many new
enhancements, few new features, but more importantly -- quite extended
tests battery with current 94% coverage. This release incorporates
more than a 100 of non-merge commits from 14 contributors (sorted by
number of commits): Yaroslav Halchenko, Daniel Black, Steven Hiscocks,
ArndRa, hamilton5, pigsyn, Erwan Ben Souiden, Michael Gebetsroither,
Orion Poplawski, Artur Penttinen, sebres, Nicolas Collignon, Pascal
Borreli, blotus:
Originally targeted as a bugfix release, it incorporated many new
enhancements, few new features, and more importantly -- quite extended
tests battery with current 94% coverage (from 56% of 0.8.8).
- Fixes:
Yaroslav Halchenko
* [6f4dad46] Documentation python-2.4 is the minimium version.
* [1eb23cf8] do not rely on scripts being under /usr -- might differ eg on
Fedora. Closes gh-112. Thanks to Camusensei for the bug report.
This release introduces over 200 of non-merge commits from 16
contributors (sorted by number of commits): Yaroslav Halchenko, Daniel
Black, Steven Hiscocks, James Stout, Orion Poplawski, Enrico Labedzki,
ArndRa, hamilton5, pigsyn, Erwan Ben Souiden, Michael Gebetsroither,
Artur Penttinen, blotus, sebres, Nicolas Collignon, Pascal Borreli.
Special Kudos also go to Fabian Wenk, Arturo 'Buanzo' Busleiman, Tom
Hendrikx, Yehuda Katz and other TBN heroes supporting users on
fail2ban-users mailing list and IRC.
- Fixes: Yaroslav Halchenko
* [6f4dad46] python-2.4 is the minimal version.
* [1eb23cf8] do not rely on scripts being under /usr -- might differ e.g.
on Fedora. Closes gh-112. Thanks to Camusensei for the bug report.
* [bf4d4af1] Changes for atomic writes. Thanks to Steven Hiscocks for
insight. Closes gh-103.
* [ab044b75] delay check for the existence of config directory until read.
@ -50,6 +54,8 @@ Borreli, blotus:
gh-70. Thanks to iGeorgeX for the idea.
blotus
* [96eb8986] ' and " should also be escaped in action tags Closes gh-109
Christoph Theis, Nick Hilliard, Daniel Black
* [b3bd877d,cde71080] Make syslog -v and syslog -vv formats work on FreeBSD
- New features:
Yaroslav Halchenko
* [9ba27353] Add support for jail.d/{confilefile} and fail2ban.d/{configfile}
@ -69,8 +75,15 @@ Borreli, blotus:
* [5f2d383] Add roundcube auth filter. Closes Debian bug #699442.
Daniel Black
* [be06b1b] Add action for iptables-ipsets. Closes gh-102.
Nick Munger, Ken Menzel, Daniel Black, Christoph Theis & Fabian Wenk
* [b6d0e8a] Add and enhance the bsd-ipfw action from
FreeBSD ports.
Soulard Morgan
* [f336d9f] Add filter for webmin. Closes gh-99.
Steven Hiscocks
* [..746c7d9] bash interactive shell completions for fail2ban-*'s
Nick Hilliard
* [0c5a9c5] Add pf action.
- Enhancements:
Enrico Labedzki
* [24a8d07] Added new date format for ASSP SMTP Proxy.
@ -90,6 +103,7 @@ Borreli, blotus:
* [40c5a2d] adding more of diagnostic messages into -client while starting
the daemon.
* [8e63d4c] Compare against None with 'is' instead of '=='.
* [6fef85f] Strip CR and LF while analyzing the log line
Daniel Black
* [3aeb1a9] Add jail.conf manual page. Closes gh-143.
* [MANY] man page edits.
@ -97,19 +111,22 @@ Borreli, blotus:
* [c8c7b0b,23bbc60] Better logging of log file read errors.
* [3665e6d] Added code coverage to development process.
* [41b9f7b,32d10e9,39750b8] More complete ssh filter rules to match openssh
source. Also include BSD changes.
source. Also include BSD changes.
* [1d9abd1] Action files can have tags in definition that refer to other
tags.
* [10886e7,cec5da2,adb991a] Change actions to response with ICMP port
unreachable rather than just a drop of the packet.
Pascal Borreli
* [a2b29b4] Fixed lots of typos in config files and documentation.
hamilton5
* [7ede1e8] Update dovecot filter config.
Romain Riviere
* [0ac8746] Enhance named-refused filter for views.
Special Kudos also go to Fabian Wenk, Arturo 'Buanzo' Busleiman, Tom
Hendrikx and other TBN heroes supporting users on fail2ban-users
mailing list and IRC.
James Stout
* [..2143cdf] Solaris support enhancements:
- README.Solaris
- failregex'es tune ups (sshd.conf)
- hostsdeny: do not rely on support of '-i' in sed
ver. 0.8.8 (2012/12/06) - stable
----------

View File

@ -1,4 +1,5 @@
README.md
README.Solaris
ChangeLog
TODO
THANKS
@ -43,6 +44,9 @@ server/datetemplate.py
server/mytime.py
server/failregex.py
testcases/files/testcase-usedns.log
testcases/files/logs/bsd/syslog-plain.txt
testcases/files/logs/bsd/syslog-v.txt
testcases/files/logs/bsd/syslog-vv.txt
testcases/banmanagertestcase.py
testcases/failmanagertestcase.py
testcases/clientreadertestcase.py
@ -97,7 +101,9 @@ config/filter.d/dropbear.conf
config/filter.d/lighttpd-auth.conf
config/filter.d/recidive.conf
config/filter.d/roundcube-auth.conf
config/action.d/bsd-ipfw.conf
config/action.d/dummy.conf
config/action.d/iptables-blocktype.conf
config/action.d/iptables-ipset-proto4.conf
config/action.d/iptables-ipset-proto6.conf
config/action.d/iptables-xt_recent-echo.conf
@ -117,6 +123,7 @@ config/action.d/mail-buffered.conf
config/action.d/mail-whois.conf
config/action.d/mail-whois-lines.conf
config/action.d/mynetwatchman.conf
config/action.d/pf.conf
config/action.d/sendmail.conf
config/action.d/sendmail-buffered.conf
config/action.d/sendmail-whois.conf
@ -145,3 +152,4 @@ files/cacti/cacti_host_template_fail2ban.xml
files/cacti/README
files/nagios/check_fail2ban
files/nagios/f2ban.txt
files/bash-completion

View File

@ -71,7 +71,7 @@ OPT: Create /etc/fail2ban/fail2ban.local containing:
# Fail2Ban main configuration file
#
# Comments: use '#' for comment lines and ';' for inline comments
# Comments: use '#' for comment lines and ';' (following a space) for inline comments
#
# Changes: in most of the cases you should not modify this
# file, but provide customizations in fail2ban.local file, e.g.:

View File

@ -2,7 +2,7 @@
/ _|__ _(_) |_ ) |__ __ _ _ _
| _/ _` | | |/ /| '_ \/ _` | ' \
|_| \__,_|_|_/___|_.__/\__,_|_||_|
v0.8.8 2012/07/31
v0.8.9 2013/05/13
## Fail2Ban: ban hosts that cause multiple authentication errors
@ -30,8 +30,8 @@ Optional:
To install, just do:
tar xvfj fail2ban-0.8.8.tar.bz2
cd fail2ban-0.8.8
tar xvfj fail2ban-0.8.9.tar.bz2
cd fail2ban-0.8.9
python setup.py install
This will install Fail2Ban into /usr/share/fail2ban. The executable scripts are
@ -56,7 +56,7 @@ the website: http://www.fail2ban.org
Code status:
------------
* [![tests status](https://secure.travis-ci.org/fail2ban/fail2ban.png)](https://travis-ci.org/fail2ban/fail2ban) travis-ci.org (master branch)
* [![tests status](https://secure.travis-ci.org/fail2ban/fail2ban.png?branch=master)](https://travis-ci.org/fail2ban/fail2ban) travis-ci.org (master branch)
* [![Coverage Status](https://coveralls.io/repos/fail2ban/fail2ban/badge.png?branch=master)](https://coveralls.io/r/fail2ban/fail2ban)

View File

@ -21,7 +21,5 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -21,8 +21,6 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -21,8 +21,6 @@
# Modified: Cyril Jaquier
__author__ = 'Yaroslav Halhenko'
__revision__ = '$Revision$'
__date__ = '$Date$'
__copyright__ = 'Copyright (c) 2007 Yaroslav Halchenko'
__license__ = 'GPL'

View File

@ -21,8 +21,6 @@
# Modified by: Yaroslav Halchenko (SafeConfigParserWithIncludes)
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -21,8 +21,6 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -21,8 +21,6 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -21,8 +21,6 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -21,8 +21,6 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -21,8 +21,6 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -21,8 +21,6 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -21,7 +21,5 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -17,13 +17,7 @@
# along with Fail2Ban; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# Author: Cyril Jaquier
# Author: Arturo 'Buanzo' Busleiman
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__author__ = "Cyril Jaquier, Arturo 'Buanzo' Busleiman"
__copyright__ = "Copyright (c) 2009 Cyril Jaquier"
__license__ = "GPL"
@ -35,6 +29,12 @@ def formatExceptionInfo():
excName = cla.__name__
try:
excArgs = exc.__dict__["args"]
# Assure that we always return a string, without unneeded
# 'decorations' with python <= 2.5 where args would be a tuple
if isinstance(excArgs, tuple) and len(excArgs) == 1:
excArgs = excArgs[0]
excArgs = str(excArgs)
except KeyError:
# And always provide a string output
excArgs = str(exc)
return (excName, excArgs)

View File

@ -21,8 +21,6 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -18,10 +18,10 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# Author: Cyril Jaquier
#
#
__author__ = "Cyril Jaquier, Yaroslav Halchenko"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2012 Yaroslav Halchenko"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
__license__ = "GPL"
version = "0.8.8"
version = "0.8.9"

View File

@ -0,0 +1,82 @@
# Fail2Ban configuration file
#
# Author: Nick Munger
# Modified by: Ken Menzel
# Daniel Black (start/stop)
# Fabian Wenk (many ideas as per fail2ban users list)
#
# Ensure firewall_enable="YES" in the top of /etc/rc.conf
#
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart = ipfw show | fgrep -q 'table(<table>)' || ( ipfw show | awk 'BEGIN { b = 1 } { if ($1 <= b) { b = $1 + 1 } else { e = b } } END { if (e) exit e <br> else exit b }'; num=$?; ipfw -q add $num deny <block> from table\(<table>\) to me <port>; echo $num > "<startstatefile>" )
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop = [ -f <startstatefile> ] && ( read num < "<startstatefile>" <br> ipfw -q delete $num <br> rm "<startstatefile>" )
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
# requires an ipfw rule like "deny ip from table(1) to me"
actionban = ipfw table <table> add <ip>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = ipfw table <table> delete <ip>
[Init]
# Option: table
# Notes: The ipfw table to use. If a ipfw rule using this table already exists,
# this action will not create a ipfw rule to block it and the following
# options will have no effect.
# Values: NUM
table = 1
# Option: port
# Notes.: Specifies port to monitor. Blank indicate block all ports.
# Values: [ NUM | STRING ]
#
port =
# Option: startstatefile
# Notes: A file to indicate that the table rule that was added. Ensure it is unique per table.
# Values: STRING
startstatefile = /var/run/fail2ban/ipfw-started-table_<table>
# Option: action
# Notes: This is the action to take for automaticly created rules. See the
# ACTION defination at the top of man ipfw for allowed values.
# "deny" and "unreach port" are probably the useful.
# Values: STRING
action = deny
# Option: block
# Notes: This is how much to block.
# Can be "ip", "tcp", "udp" or various other options.
# Values: STRING
block = ip

View File

@ -37,7 +37,7 @@ actioncheck =
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = echo block in quick from <ip>/32 | /sbin/ipf -f -
actionban = echo block <blocktype> in quick from <ip>/32 | /sbin/ipf -f -
# Option: actionunban
@ -47,7 +47,12 @@ actionban = echo block in quick from <ip>/32 | /sbin/ipf -f -
# Values: CMD
#
# note -r option used to remove matching rule
actionunban = echo block in quick from <ip>/32 | /sbin/ipf -r -f -
actionunban = echo block <blocktype> in quick from <ip>/32 | /sbin/ipf -r -f -
[Init]
# Option: Blocktype
# Notes : This is the return-icmp[return-code] mentioned in the ipf man page section 5. Keep this quoted to prevent
# Shell expansion. This should be blank (unquoted) to drop the packet.
# Values: STRING
blocktype = "return-icmp(port-unr)"

View File

@ -34,7 +34,7 @@ actioncheck =
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = ipfw add deny tcp from <ip> to <localhost> <port>
actionban = ipfw add <blocktype> tcp from <ip> to <localhost> <port>
# Option: actionunban
@ -58,3 +58,11 @@ port = ssh
# Values: IP
#
localhost = 127.0.0.1
# Option: blocktype
# Notes.: How to block the traffic. Use a action from man 5 ipfw
# Common values: deny, unreach port, reset
# Values: STRING
#
blocktype = unreach port

View File

@ -6,6 +6,11 @@
#
#
[INCLUDES]
before = iptables-blocktype.conf
[Definition]
# Option: actionstart
@ -36,7 +41,7 @@ actioncheck = iptables -n -L <chain> | grep -q 'fail2ban-<name>[ \t]'
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j <blocktype>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
@ -44,7 +49,7 @@ actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
actionunban = iptables -D fail2ban-<name> -s <ip> -j <blocktype>
[Init]

View File

@ -0,0 +1,22 @@
# 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

View File

@ -18,6 +18,10 @@
# apt-get install ipset xtables-addons-source
# module-assistant auto-install xtables-addons
[INCLUDES]
before = iptables-blocktype.conf
[Definition]
# Option: actionstart
@ -25,13 +29,13 @@
# Values: CMD
#
actionstart = ipset --create fail2ban-<name> iphash
iptables -I INPUT -p <protocol> -m multiport --dports <port> -m set --match-set fail2ban-<name> src -j DROP
iptables -I INPUT -p <protocol> -m multiport --dports <port> -m set --match-set fail2ban-<name> src -j <blocktype>
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop = iptables -D INPUT -p <protocol> -m multiport --dports <port> -m set --match-set fail2ban-<name> src -j DROP
actionstop = iptables -D INPUT -p <protocol> -m multiport --dports <port> -m set --match-set fail2ban-<name> src -j <blocktype>
ipset --flush fail2ban-<name>
ipset --destroy fail2ban-<name>
@ -68,4 +72,3 @@ port = ssh
# Values: [ tcp | udp | icmp | all ] Default: tcp
#
protocol = tcp

View File

@ -18,6 +18,11 @@
# apt-get install ipset xtables-addons-source
# module-assistant auto-install xtables-addons
[INCLUDES]
before = iptables-blocktype.conf
[Definition]
# Option: actionstart
@ -74,5 +79,3 @@ protocol = tcp
# Values: [ NUM ] Default: 600
bantime = 600

View File

@ -9,6 +9,10 @@
#
#
[INCLUDES]
before = iptables-blocktype.conf
[Definition]
# Option: actionstart
@ -20,7 +24,7 @@ actionstart = iptables -N fail2ban-<name>
iptables -I <chain> 1 -p <protocol> -m multiport --dports <port> -j fail2ban-<name>
iptables -N fail2ban-<name>-log
iptables -I fail2ban-<name>-log -j LOG --log-prefix "$(expr fail2ban-<name> : '\(.\{1,23\}\)'):DROP " --log-level warning -m limit --limit 6/m --limit-burst 2
iptables -A fail2ban-<name>-log -j DROP
iptables -A fail2ban-<name>-log -j <blocktype>
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban

View File

@ -4,6 +4,10 @@
# Modified by Yaroslav Halchenko for multiport banning
#
[INCLUDES]
before = iptables-blocktype.conf
[Definition]
# Option: actionstart
@ -34,7 +38,7 @@ actioncheck = iptables -n -L <chain> | grep -q 'fail2ban-<name>[ \t]'
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j <blocktype>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
@ -42,7 +46,7 @@ actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
actionunban = iptables -D fail2ban-<name> -s <ip> -j <blocktype>
[Init]

View File

@ -6,6 +6,11 @@
#
#
[INCLUDES]
before = iptables-blocktype.conf
[Definition]
# Option: actionstart
@ -36,7 +41,7 @@ actioncheck = iptables -n -L <chain> | grep -q 'fail2ban-<name>[ \t]'
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j <blocktype>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
@ -44,7 +49,7 @@ actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
actionunban = iptables -D fail2ban-<name> -s <ip> -j <blocktype>
[Init]

View File

@ -4,6 +4,11 @@
#
#
[INCLUDES]
before = iptables-blocktype.conf
[Definition]
# Option: actionstart
@ -28,7 +33,7 @@
# own rules. The 3600 second timeout is independent and acts as a
# safeguard in case the fail2ban process dies unexpectedly. The
# shorter of the two timeouts actually matters.
actionstart = iptables -I INPUT -m recent --update --seconds 3600 --name fail2ban-<name> -j DROP
actionstart = iptables -I INPUT -m recent --update --seconds 3600 --name fail2ban-<name> -j <blocktype>
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban

View File

@ -4,6 +4,10 @@
#
#
[INCLUDES]
before = iptables-blocktype.conf
[Definition]
# Option: actionstart
@ -34,7 +38,7 @@ actioncheck = iptables -n -L <chain> | grep -q 'fail2ban-<name>[ \t]'
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j <blocktype>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
@ -42,7 +46,7 @@ actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
actionunban = iptables -D fail2ban-<name> -s <ip> -j <blocktype>
[Init]

62
config/action.d/pf.conf Normal file
View File

@ -0,0 +1,62 @@
# Fail2Ban configuration file
#
# OpenBSD pf ban/unban
#
# Author: Nick Hilliard <nick@foobar.org>
#
#
[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
# we don't enable PF automatically, as it will be enabled elsewhere
actionstart =
# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
# we don't disable PF automatically either
actionstop =
# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =
# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = /sbin/pfctl -t <tablename> -T add <ip>/32
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
# note -r option used to remove matching rule
actionunban = /sbin/pfctl -t <tablename> -T delete <ip>/32
[Init]
# Option: tablename
# Notes.: The pf table name.
# Values: [ STRING ] Default: fail2ban
#
tablename = fail2ban

View File

@ -15,11 +15,10 @@
# - Blocking is per IP and NOT per service, but ideal as action against ssh password bruteforcing hosts
[Definition]
actionban = ip route add <type> <ip>
actionunban = ip route del <type> <ip>
actionban = ip route add <blocktype> <ip>
actionunban = ip route del <blocktype> <ip>
# Type of blocking
#
# Type can be blackhole, unreachable and prohibit. Unreachable and prohibit correspond to the ICMP reject messages.
type = blackhole
# Option: blocktype
# Note: Type can be blackhole, unreachable and prohibit. Unreachable and prohibit correspond to the ICMP reject messages.
# Values: STRING
blocktype = unreachable

View File

@ -38,7 +38,7 @@ actioncheck =
# Tags: See jail.conf(5) man page
# Values: CMD
#
actionban = shorewall drop <ip>
actionban = shorewall <blocktype> <ip>
# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
@ -47,3 +47,9 @@ actionban = shorewall drop <ip>
# Values: CMD
#
actionunban = shorewall allow <ip>
# Option: blocktype
# Note: This is what the action does with rules.
# See man page of shorewall for options that include drop, logdrop, reject, or logreject
# Values: STRING
blocktype = reject

View File

@ -1,6 +1,6 @@
# Fail2Ban main configuration file
#
# Comments: use '#' for comment lines and ';' for inline comments
# Comments: use '#' for comment lines and ';' (following a space) for inline comments
#
# Changes: in most of the cases you should not modify this
# file, but provide customizations in fail2ban.local file, e.g.:

View File

@ -41,10 +41,16 @@ __kernel_prefix = kernel: \[\d+\.\d+\]
__hostname = \S+
# bsdverbose is where syslogd is started with -v or -vv and results in <4.3> or
# <auth.info> appearing before the host as per testcases/files/logs/bsd/*.
__bsd_syslog_verbose = (<[^.]+\.[^.]+>)
#
# Common line prefixes (beginnings) which could be used in filters
#
# [hostname] [vserver tag] daemon_id spaces
# this can be optional (for instance if we match named native log files)
__prefix_line = \s*(?:%(__hostname)s )?(?:%(__kernel_prefix)s )?(?:@vserver_\S+ )?%(__daemon_combs_re)s?\s%(__daemon_extra_re)s?\s*
# [bsdverbose]? [hostname] [vserver tag] daemon_id spaces
#
# This can be optional (for instance if we match named native log files)
__prefix_line = \s*%(__bsd_syslog_verbose)s?\s*(?:%(__hostname)s )?(?:%(__kernel_prefix)s )?(?:@vserver_\S+ )?%(__daemon_combs_re)s?\s%(__daemon_extra_re)s?\s*

View File

@ -1,6 +1,6 @@
# Fail2Ban jail specifications file
#
# Comments: use '#' for comment lines and ';' for inline comments
# Comments: use '#' for comment lines and ';' (following a space) for inline comments
#
# Changes: in most of the cases you should not modify this
# file, but provide customizations in jail.local file, e.g.:
@ -139,6 +139,19 @@ action = iptables-ipset-proto6[name=SSH, port=ssh, protocol=tcp, bantime=600]
logpath = /var/log/sshd.log
maxretry = 5
# bsd-ipfw is ipfw used by BSD. It uses ipfw tables.
# table number must be unique.
#
# This will create a deny rule for that table ONLY if a rule
# for the table doesn't ready exist.
#
[ssh-bsd-ipfw]
enabled = false
filter = sshd
action = bsd-ipfw[port=ssh,table=1]
logpath = /var/log/auth.log
maxretry = 5
# This jail demonstrates the use of wildcards in "logpath".
# Moreover, it is possible to give other files on a new line.
@ -380,3 +393,14 @@ action = iptables-allports[name=recidive]
bantime = 604800 ; 1 week
findtime = 86400 ; 1 day
maxretry = 5
# PF is a BSD based firewall
[ssh-pf]
enabled=false
filter = sshd
action = pf
logpath = /var/log/sshd.log
maxretry=5

View File

@ -36,6 +36,7 @@ from testcases import servertestcase
from testcases import datedetectortestcase
from testcases import actiontestcase
from testcases import sockettestcase
from testcases import misctestcase
from testcases.utils import FormatterWithTraceBack
from server.mytime import MyTime
@ -139,6 +140,7 @@ else: # pragma: no cover
# Server
#tests.addTest(unittest.makeSuite(servertestcase.StartStop))
tests.addTest(unittest.makeSuite(servertestcase.Transmitter))
tests.addTest(unittest.makeSuite(servertestcase.JailTests))
tests.addTest(unittest.makeSuite(actiontestcase.ExecuteAction))
# FailManager
tests.addTest(unittest.makeSuite(failmanagertestcase.AddFailure))
@ -150,6 +152,10 @@ tests.addTest(unittest.makeSuite(clientreadertestcase.JailReaderTest))
tests.addTest(unittest.makeSuite(clientreadertestcase.JailsReaderTest))
# CSocket and AsyncServer
tests.addTest(unittest.makeSuite(sockettestcase.Socket))
# Misc helpers
tests.addTest(unittest.makeSuite(misctestcase.HelpersTest))
tests.addTest(unittest.makeSuite(misctestcase.SetupTest))
tests.addTest(unittest.makeSuite(misctestcase.TestsUtilsTest))
# Filter
if not opts.no_network:

149
files/bash-completion Normal file
View File

@ -0,0 +1,149 @@
# fail2ban bash-completion -*- shell-script -*-
#
# This file is part of Fail2Ban.
#
# Fail2Ban is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Fail2Ban is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Fail2Ban; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
__fail2ban_jails () {
"$1" status 2>/dev/null | awk -F"\t+" '/Jail list/{print $2}' | sed 's/, / /g'
}
_fail2ban () {
local cur prev words cword
_init_completion || return
case $prev in
-V|--version|-h|--help)
return 0 # No further completion valid
;;
-c)
_filedir -d # Directories
return 0
;;
-s|-p)
_filedir # Files
return 0
;;
*)
if [[ "$cur" == "-"* ]];then
COMPREPLY=( $( compgen -W \
"$( _parse_help "$1" --help 2>/dev/null) -V" \
-- "$cur") )
return 0
fi
;;
esac
if [[ "$1" == *"fail2ban-regex" ]];then
_filedir
return 0
elif [[ "$1" == *"fail2ban-client" ]];then
local cmd jail
case $prev in
"$1")
COMPREPLY=( $( compgen -W \
"$( "$1" --help 2>/dev/null | awk '/^ [a-z]+/{print $1}')" \
-- "$cur") )
return 0
;;
start|reload|stop|status)
COMPREPLY=( $(compgen -W "$(__fail2ban_jails "$1")" -- "$cur" ) )
return 0
;;
set|get)
COMPREPLY=( $( compgen -W \
"$( "$1" --help 2>/dev/null | awk '/^ '$prev' [^<]/{print $2}')" \
-- "$cur") )
COMPREPLY+=( $(compgen -W "$(__fail2ban_jails "$1")" -- "$cur" ) )
return 0
;;
*)
if [[ "${words[$cword-2]}" == "add" ]];then
COMPREPLY=( $( compgen -W "auto polling gamin pyinotify" -- "$cur" ) )
return 0
elif [[ "${words[$cword-2]}" == "set" || "${words[$cword-2]}" == "get" ]];then
cmd="${words[cword-2]}"
# Handle in section below
elif [[ "${words[$cword-3]}" == "set" || "${words[$cword-3]}" == "get" ]];then
cmd="${words[$cword-3]}"
jail="${words[$cword-2]}"
# Handle in section below
fi
;;
esac
if [[ -z "$jail" && -n "$cmd" ]];then
case $prev in
loglevel)
if [[ "$cmd" == "set" ]];then
COMPREPLY=( $( compgen -W "0 1 2 3 4" -- "$cur" ) )
fi
return 0
;;
logtarget)
if [[ "$cmd" == "set" ]];then
COMPREPLY=( $( compgen -W "STDOUT STDERR SYSLOG" -- "$cur" ) )
_filedir # And files
fi
return 0
;;
*) # Jail name
COMPREPLY=( $( compgen -W \
"$( "$1" --help 2>/dev/null | awk '/^ '${cmd}' <JAIL>/{print $3}')" \
-- "$cur") )
return 0
;;
esac
elif [[ -n "$jail" && "$cmd" == "set" ]];then
case $prev in
addlogpath)
_filedir
return 0
;;
dellogpath|delignoreip)
COMPREPLY=( $( compgen -W \
"$( "$1" get "$jail" "${prev/del/}" 2>/dev/null | awk -F- '{print $2}')" \
-- "$cur" ) )
if [[ -z "$COMPREPLY" && "$prev" == "dellogpath" ]];then
_filedir
fi
return 0
;;
delfailregex|delignoregex)
COMPREPLY=( $( compgen -W \
"$( "$1" get "$jail" "${prev/del/}" 2>/dev/null | awk -F"[][]" '{print $2}')" \
-- "$cur" ) )
return 0
;;
unbanip)
COMPREPLY=( $( compgen -W \
"$( "$1" status "$jail" 2>/dev/null | awk -F"\t+" '/IP list:/{print $2}')" \
-- "$cur" ) )
return 0
;;
idle)
COMPREPLY=( $( compgen -W "on off" -- "$cur" ) )
return 0
;;
usedns)
COMPREPLY=( $( compgen -W "yes no warn" -- "$cur" ) )
return 0
;;
esac
fi
fi # fail2ban-client
} &&
complete -F _fail2ban fail2ban-client fail2ban-server fail2ban-regex

View File

@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10.
.TH FAIL2BAN-CLIENT "1" "March 2013" "fail2ban-client v0.8.8" "User Commands"
.TH FAIL2BAN-CLIENT "1" "May 2013" "fail2ban-client v0.8.9" "User Commands"
.SH NAME
fail2ban-client \- configure and control the server
.SH SYNOPSIS
.B fail2ban-client
[\fIOPTIONS\fR] \fI<COMMAND>\fR
.SH DESCRIPTION
Fail2Ban v0.8.8 reads log file that contains password failure report
Fail2Ban v0.8.9 reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.SH OPTIONS
.TP
@ -62,6 +62,9 @@ server
.TP
\fBping\fR
tests if the server is alive
.TP
\fBhelp\fR
return this output
.IP
LOGGING
.TP

View File

@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10.
.TH FAIL2BAN-REGEX "1" "March 2013" "fail2ban-regex v0.8.8" "User Commands"
.TH FAIL2BAN-REGEX "1" "May 2013" "fail2ban-regex v0.8.9" "User Commands"
.SH NAME
fail2ban-regex \- test Fail2ban "failregex" option
.SH SYNOPSIS
.B fail2ban-regex
[\fIOPTIONS\fR] \fI<LOG> <REGEX> \fR[\fIIGNOREREGEX\fR]
.SH DESCRIPTION
Fail2Ban v0.8.8 reads log file that contains password failure report
Fail2Ban v0.8.9 reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.PP
This tools can test regular expressions for "fail2ban".

View File

@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10.
.TH FAIL2BAN-SERVER "1" "March 2013" "fail2ban-server v0.8.8" "User Commands"
.TH FAIL2BAN-SERVER "1" "May 2013" "fail2ban-server v0.8.9" "User Commands"
.SH NAME
fail2ban-server \- start the server
.SH SYNOPSIS
.B fail2ban-server
[\fIOPTIONS\fR]
.SH DESCRIPTION
Fail2Ban v0.8.8 reads log file that contains password failure report
Fail2Ban v0.8.9 reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.PP
Only use this command for debugging purpose. Start the server with

View File

@ -70,8 +70,8 @@ class RequestHandler(asynchat.async_chat):
self.close_when_done()
def handle_error(self):
e1,e2 = helpers.formatExceptionInfo()
logSys.error("Unexpected communication error: "+e2)
e1, e2 = helpers.formatExceptionInfo()
logSys.error("Unexpected communication error: %s" % str(e2))
logSys.error(traceback.format_exc().splitlines())
self.close()

View File

@ -290,6 +290,7 @@ class Filter(JailThread):
l = line.decode('utf-8')
except UnicodeDecodeError:
l = line
l = l.rstrip('\r\n')
timeMatch = self.dateDetector.matchTime(l)
if timeMatch:
# Lets split into time part and log part of the line

View File

@ -104,7 +104,8 @@ class FilterPoll(FileFilter):
time.sleep(self.getSleepTime())
else:
time.sleep(self.getSleepTime())
logSys.debug((self.jail and self.jail.getName() or "jailless") +
logSys.debug(
(self.jail is not None and self.jail.getName() or "jailless") +
" filter terminated")
return True
@ -130,7 +131,7 @@ class FilterPoll(FileFilter):
self.__file404Cnt[filename] += 1
if self.__file404Cnt[filename] > 2:
logSys.warn("Too many errors. Setting the jail idle")
if self.jail:
if self.jail is not None:
self.jail.setIdle(True)
else:
logSys.warn("No jail is assigned to %s" % self)

View File

@ -23,19 +23,28 @@ __author__ = "Cyril Jaquier, Lee Clemens, Yaroslav Halchenko"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2012 Lee Clemens, 2012 Yaroslav Halchenko"
__license__ = "GPL"
import time, logging, pyinotify
from distutils.version import LooseVersion
from os.path import dirname, sep as pathsep
from failmanager import FailManagerEmpty
from filter import FileFilter
from mytime import MyTime
import time, logging, pyinotify
if not hasattr(pyinotify, '__version__') \
or LooseVersion(pyinotify.__version__) < '0.8.3':
raise ImportError("Fail2Ban requires pyinotify >= 0.8.3")
from os.path import dirname, sep as pathsep
# Verify that pyinotify is functional on this system
# Even though imports -- might be dysfunctional, e.g. as on kfreebsd
try:
manager = pyinotify.WatchManager()
del manager
except Exception, e:
raise ImportError("Pyinotify is probably not functional on this system: %s"
% str(e))
# Gets the instance of the logger.
logSys = logging.getLogger("fail2ban.filter")

View File

@ -38,7 +38,7 @@ class Jail:
_BACKENDS = ['pyinotify', 'gamin', 'polling']
def __init__(self, name, backend = "auto"):
self.__name = name
self.setName(name)
self.__queue = Queue.Queue()
self.__filter = None
logSys.info("Creating new jail '%s'" % self.__name)
@ -102,6 +102,10 @@ class Jail:
self.__filter = FilterPyinotify(self)
def setName(self, name):
if len(name) >= 20:
logSys.warning("Jail name %r might be too long and some commands "
"might not function correctly. Please shorten"
% name)
self.__name = name
def getName(self):

View File

@ -377,10 +377,11 @@ class Server:
handler.flush()
handler.close()
except (ValueError, KeyError): # pragma: no cover
if sys.version_info >= (2,6):
raise
# is known to be thrown after logging was shutdown once
# Is known to be thrown after logging was shutdown once
# with older Pythons -- seems to be safe to ignore there
# At least it was still failing on 2.6.2-0ubuntu1 (jaunty)
if sys.version_info >= (2,6,3):
raise
# tell the handler to use this format
hdlr.setFormatter(formatter)
logging.getLogger("fail2ban").addHandler(hdlr)

View File

@ -21,7 +21,5 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -21,8 +21,6 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -21,8 +21,6 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -160,6 +160,15 @@ class JailsReaderTest(unittest.TestCase):
self.assertEqual(opts['socket'], '/var/run/fail2ban/fail2ban.sock')
self.assertEqual(opts['pidfile'], '/var/run/fail2ban/fail2ban.pid')
configurator.getOptions()
configurator.convertToProtocol()
commands = configurator.getConfigStream()
# and there is logging information left to be passed into the
# server
self.assertEqual(commands,
[['set', 'loglevel', 3],
['set', 'logtarget', '/var/log/fail2ban.log']])
# and if we force change configurator's fail2ban's baseDir
# there should be an error message (test visually ;) --
# otherwise just a code smoke test)

View File

@ -21,8 +21,6 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -21,8 +21,6 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

View File

@ -0,0 +1,3 @@
Apr 2 17:52:55 pancake sshd[55657]: Invalid user oracle from 192.0.2.100
Apr 2 17:53:01 pancake sshd[55657]: error: PAM: authentication error for illegal user oracle from example.com
Apr 2 17:53:01 pancake sshd[55657]: Failed keyboard-interactive/pam for invalid user oracle from 192.0.2.100 port 48856 ssh2

View File

@ -0,0 +1,10 @@
Apr 2 17:51:27 <4.3> pancake sshd[55624]: error: PAM: authentication error for nick from example.com
Apr 2 17:51:32 <4.6> pancake sshd[55628]: Invalid user r00t from 192.0.2.100
Apr 2 17:51:33 <4.3> pancake sshd[55628]: error: PAM: authentication error for illegal user r00t from example.com
Apr 2 17:51:33 <4.6> pancake sshd[55628]: Failed keyboard-interactive/pam for invalid user r00t from 192.0.2.100 port 46050 ssh2
Apr 2 17:51:34 <4.3> pancake sshd[55628]: error: PAM: authentication error for illegal user r00t from example.com
Apr 2 17:51:34 <4.6> pancake sshd[55628]: Failed keyboard-interactive/pam for invalid user r00t from 192.0.2.100 port 46050 ssh2
Apr 2 17:51:36 <4.3> pancake sshd[55628]: error: PAM: authentication error for illegal user r00t from example.com
Apr 2 17:51:36 <4.6> pancake sshd[55628]: Failed keyboard-interactive/pam for invalid user r00t from 192.0.2.100 port 46050 ssh2
Apr 2 17:52:06 <4.6> pancake sshd[55647]: Invalid user oracle from 192.0.2.100
Apr 2 17:52:07 <4.3> pancake sshd[55647]: error: PAM: authentication error for illegal user oracle from example.com

View File

@ -0,0 +1,5 @@
Mar 19 23:48:18 <auth.info> pancake sshd[55517]: Invalid user r00t from 183.60.159.20
Mar 19 23:48:20 <auth.info> pancake sshd[55519]: Invalid user r00t from 183.60.159.20
Mar 19 23:50:03 <auth.info> pancake sshd[55604]: Invalid user http from 183.60.159.20
Mar 19 23:50:05 <auth.info> pancake sshd[55606]: Invalid user kylix from 183.60.159.20
Mar 19 23:50:08 <auth.info> pancake sshd[55608]: Invalid user nagios from 183.60.159.20

View File

@ -477,8 +477,8 @@ def get_monitor_failures_testcase(Filter_):
def _test_move_into_file(self, interim_kill=False):
# if we move a new file into the location of an old (monitored) file
self.file1 = _copy_lines_between_files(GetFailures.FILENAME_01, self.name,
n=100)
_copy_lines_between_files(GetFailures.FILENAME_01, self.name,
n=100).close()
# make sure that it is monitored first
self.assert_correct_last_attempt(GetFailures.FAILURES_01)
self.assertEqual(self.filter.failManager.getFailTotal(), 3)
@ -488,14 +488,15 @@ def get_monitor_failures_testcase(Filter_):
time.sleep(0.2) # let them know
# now create a new one to override old one
self.file = _copy_lines_between_files(GetFailures.FILENAME_01,
self.name + '.new', n=100)
_copy_lines_between_files(GetFailures.FILENAME_01, self.name + '.new',
n=100).close()
os.rename(self.name + '.new', self.name)
self.assert_correct_last_attempt(GetFailures.FAILURES_01)
self.assertEqual(self.filter.failManager.getFailTotal(), 6)
# and to make sure that it now monitored for changes
_copy_lines_between_files(GetFailures.FILENAME_01, self.name, n=100)
_copy_lines_between_files(GetFailures.FILENAME_01, self.name,
n=100).close()
self.assert_correct_last_attempt(GetFailures.FAILURES_01)
self.assertEqual(self.filter.failManager.getFailTotal(), 9)
@ -579,11 +580,31 @@ class GetFailures(unittest.TestCase):
def testGetFailures01(self):
self.filter.addLogPath(GetFailures.FILENAME_01)
self.filter.addFailRegex("(?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) <HOST>")
self.filter.getFailures(GetFailures.FILENAME_01)
_assert_correct_last_attempt(self, self.filter, GetFailures.FAILURES_01)
def testGetFailures01(self, filename=None, failures=None):
filename = filename or GetFailures.FILENAME_01
failures = failures or GetFailures.FAILURES_01
self.filter.addLogPath(filename)
self.filter.addFailRegex("(?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) <HOST>$")
self.filter.getFailures(filename)
_assert_correct_last_attempt(self, self.filter, failures)
def testCRLFFailures01(self):
# We first adjust logfile/failures to end with CR+LF
fname = tempfile.mktemp(prefix='tmp_fail2ban', suffix='crlf')
# poor man unix2dos:
fin, fout = open(GetFailures.FILENAME_01), open(fname, 'w')
for l in fin.readlines():
fout.write('%s\r\n' % l.rstrip('\n'))
fin.close()
fout.close()
# now see if we should be getting the "same" failures
self.testGetFailures01(filename=fname,
failures=GetFailures.FAILURES_01[:3] +
([x.rstrip('\n') + '\r\n' for x in
GetFailures.FAILURES_01[-1]],))
_killfile(fout, fname)
def testGetFailures02(self):

169
testcases/misctestcase.py Normal file
View File

@ -0,0 +1,169 @@
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: t -*-
# vi: set ft=python sts=4 ts=4 sw=4 noet :
# This file is part of Fail2Ban.
#
# Fail2Ban is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Fail2Ban is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Fail2Ban; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
__author__ = "Yaroslav Halchenko"
__copyright__ = "Copyright (c) 2013 Yaroslav Halchenko"
__license__ = "GPL"
import logging
import os, sys, unittest
import tempfile
import shutil
from glob import glob
from utils import mbasename, TraceBack, FormatterWithTraceBack
from common.helpers import formatExceptionInfo
class HelpersTest(unittest.TestCase):
def testFormatExceptionInfoBasic(self):
try:
raise ValueError("Very bad exception")
except:
name, args = formatExceptionInfo()
self.assertEqual(name, "ValueError")
self.assertEqual(args, "Very bad exception")
def testFormatExceptionConvertArgs(self):
try:
raise ValueError("Very bad", None)
except:
name, args = formatExceptionInfo()
self.assertEqual(name, "ValueError")
# might be fragile due to ' vs "
self.assertEqual(args, "('Very bad', None)")
# based on
# http://stackoverflow.com/questions/2186525/use-a-glob-to-find-files-recursively-in-python
def recursive_glob(treeroot, pattern):
import fnmatch, os
results = []
for base, dirs, files in os.walk(treeroot):
goodfiles = fnmatch.filter(dirs + files, pattern)
results.extend(os.path.join(base, f) for f in goodfiles)
return results
class SetupTest(unittest.TestCase):
def setUp(self):
setup = os.path.join(os.path.dirname(__file__), '..', 'setup.py')
self.setup = os.path.exists(setup) and setup or None
if not self.setup and sys.version_info >= (2,7): # running not out of the source
raise unittest.SkipTest(
"Seems to be running not out of source distribution"
" -- cannot locate setup.py")
def testSetupInstallRoot(self):
if not self.setup: return # if verbose skip didn't work out
tmp = tempfile.mkdtemp()
os.system("%s %s install --root=%s >/dev/null"
% (sys.executable, self.setup, tmp))
def addpath(l):
return [os.path.join(tmp, x) for x in l]
def strippath(l):
return [x[len(tmp)+1:] for x in l]
got = strippath(sorted(glob('%s/*' % tmp)))
need = ['etc', 'usr', 'var']
# if anything is missing
if set(need).difference(got):
# below code was actually to print out not missing but
# rather files in 'excess'. Left in place in case we
# decide to revert to such more strict test
files = {}
for missing in set(got).difference(need):
missing_full = os.path.join(tmp, missing)
files[missing] = os.path.exists(missing_full) \
and strippath(recursive_glob(missing_full, '*')) or None
self.assertEqual(
got, need,
msg="Got: %s Needed: %s under %s. Files under new paths: %s"
% (got, need, tmp, files))
# Assure presence of some files we expect to see in the installation
for f in ('etc/fail2ban/fail2ban.conf',
'etc/fail2ban/jail.conf'):
self.assertTrue(os.path.exists(os.path.join(tmp, f)),
msg="Can't find %s" % f)
# clean up
shutil.rmtree(tmp)
class TestsUtilsTest(unittest.TestCase):
def testmbasename(self):
self.assertEqual(mbasename("sample.py"), 'sample')
self.assertEqual(mbasename("/long/path/sample.py"), 'sample')
# this one would include only the directory for the __init__ and base files
self.assertEqual(mbasename("/long/path/__init__.py"), 'path.__init__')
self.assertEqual(mbasename("/long/path/base.py"), 'path.base')
self.assertEqual(mbasename("/long/path/base"), 'path.base')
def testTraceBack(self):
# pretty much just a smoke test since tests runners swallow all the detail
for compress in True, False:
tb = TraceBack(compress=compress)
def func_raise():
raise ValueError()
def deep_function(i):
if i: deep_function(i-1)
else: func_raise()
try:
print deep_function(3)
except ValueError:
s = tb()
# if we run it through 'coverage' (e.g. on travis) then we
# would get a traceback
if 'coverage' in s:
self.assertTrue('>' in s, msg="no '>' in %r" % s)
else:
self.assertFalse('>' in s, msg="'>' present in %r" % s) # There is only "fail2ban-testcases" in this case, no true traceback
self.assertTrue(':' in s, msg="no ':' in %r" % s)
def testFormatterWithTraceBack(self):
from StringIO import StringIO
strout = StringIO()
Formatter = FormatterWithTraceBack
# and both types of traceback at once
fmt = ' %(tb)s | %(tbc)s : %(message)s'
logSys = logging.getLogger("fail2ban_tests")
out = logging.StreamHandler(strout)
out.setFormatter(Formatter(fmt))
logSys.addHandler(out)
logSys.error("XXX")
s = strout.getvalue()
self.assertTrue(s.rstrip().endswith(': XXX'))
pindex = s.index('|')
# in this case compressed and not should be the same (?)
self.assertTrue(pindex > 10) # we should have some traceback
self.assertEqual(s[:pindex], s[pindex+1:pindex*2 + 1])

View File

@ -21,13 +21,12 @@
#
__author__ = "Cyril Jaquier"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
import unittest, socket, time, tempfile, os
from server.server import Server
from server.jail import Jail
from common.exceptions import UnknownJailException
class StartStop(unittest.TestCase):
@ -509,3 +508,12 @@ class TransmitterLogging(TransmitterBase):
self.setGetTest("loglevel", "-1", -1)
self.setGetTest("loglevel", "0", 0)
self.setGetTestNOK("loglevel", "Bird")
class JailTests(unittest.TestCase):
def testLongName(self):
# Just a smoke test for now
longname = "veryveryverylongname"
jail = Jail(longname)
self.assertEqual(jail.getName(), longname)

View File

@ -21,8 +21,6 @@
#
__author__ = "Steven Hiscocks"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2013 Steven Hiscocks"
__license__ = "GPL"

View File

@ -61,11 +61,12 @@ class TraceBack(object):
def __call__(self):
ftb = traceback.extract_stack(limit=100)[:-2]
entries = [[mbasename(x[0]), str(x[1])] for x in ftb]
entries = [ e for e in entries
if not e[0] in ['unittest', 'logging.__init__' ]]
entries = [[mbasename(x[0]), dirname(x[0]), str(x[1])] for x in ftb]
entries = [ [e[0], e[2]] for e in entries
if not (e[0] in ['unittest', 'logging.__init__']
or e[1].endswith('/unittest'))]
# lets make it more consize
# lets make it more concise
entries_out = [entries[0]]
for entry in entries[1:]:
if entry[0] == entries_out[-1][0]: