Upgraded to fresh upstream 0.7.5

debian-releases/etch sdist/0.7.5
Yaroslav Halchenko 2007-10-16 17:01:20 -04:00
commit 325366066e
50 changed files with 1102 additions and 595 deletions

View File

@ -4,9 +4,33 @@
|_| \__,_|_|_/___|_.__/\__,_|_||_|
=============================================================
Fail2Ban (version 0.7.4) 2006/11/01
Fail2Ban (version 0.7.5) 2006/12/07
=============================================================
ver. 0.7.5 (2006/12/07) - beta
----------
- Do not ban a host that is currently banned. Thanks to
Yaroslav Halchenko
- The supported tags in "action(un)ban" are <ip>, <failures>
and <time>
- Fixed refactoring bug (getLastcommand -> getLastAction)
- Added option "ignoreregex" in filter scripts and jail.conf.
Feature Request #1283304
- Fixed a bug in user defined time regex/pattern
- Improved documentation
- Moved version.py and protocol.py to common/
- Merged "maxtime" option with "findtime"
- Added "<HOST>" tag support in failregex which matches
default IP address/hostname. "(?P<host>\S)" is still valid
and supported
- Fixed exception when calling fail2ban-server with unknown
option
- Fixed Debian bug 400162. The "socket" option is now handled
correctly by fail2ban-client
- Fixed RedHat init script. Thanks to Justin Shore
- Changed timeout to 30 secondes before assuming the server
cannot be started. Thanks to Joël Bertrand
ver. 0.7.4 (2006/11/01) - beta
----------
- Improved configuration files. Thanks to Yaroslav Halchenko

View File

@ -1,6 +1,6 @@
Metadata-Version: 1.0
Name: fail2ban
Version: 0.7.4
Version: 0.7.5
Summary: Ban IPs that make too many password failure
Home-page: http://fail2ban.sourceforge.net
Author: Cyril Jaquier

56
README
View File

@ -4,7 +4,7 @@
|_| \__,_|_|_/___|_.__/\__,_|_||_|
=============================================================
Fail2Ban (version 0.7.4) 2006/11/01
Fail2Ban (version 0.7.5) 2006/12/07
=============================================================
Fail2Ban scans log files like /var/log/pwdfail and bans IP
@ -13,7 +13,8 @@ rules to reject the IP address. These rules can be defined by
the user. Fail2Ban can read multiple log files such as sshd
or Apache web server ones.
Documentation, FAQ, HOWTOs are available on the project
This README is a quick introduction to Fail2ban. More
documentation, FAQ, HOWTOs are available on the project
website: http://fail2ban.sourceforge.net
Installation:
@ -27,8 +28,8 @@ Optional:
To install, just do:
> tar xvfj fail2ban-0.7.4.tar.bz2
> cd fail2ban-0.7.4
> tar xvfj fail2ban-0.7.5.tar.bz2
> cd fail2ban-0.7.5
> python setup.py install
This will install Fail2Ban into /usr/lib/fail2ban. The
@ -38,54 +39,27 @@ Gentoo: ebuilds are available on the website.
Debian: Fail2Ban is in Debian unstable.
RedHat: packages are available on the website.
Fail2Ban should now be correctly installed. Just type:
Fail2Ban should be correctly installed now. Just type:
> fail2ban-client -h
to see if everything is alright.
to see if everything is alright. You should always use
fail2ban-client and never call fail2ban-server directly.
Configuration:
--------------
You can configure fail2ban using the files in /etc/fail2ban
or using command line. Here are the available command line
options (not complete yet):
Options:
-c <DIR> configuration directory
-s <FILE> socket path
-d dump configuration. For debugging
-i interactive mode
-v increase verbosity
-q decrease verbosity
-x force execution of the server
-h, --help display this help message
-V, --version print the version
Command:
start start the server and the jails
reload reload the configuration
stop stop all jails and terminate the
server
status get the current status
set loglevel <LEVEL> set loglevel to <LEVEL>
get loglevel get loglevel
set logtarget <TARGET> set log target to <TARGET>
get logtarget get log target
add <JAIL> [BACKEND] create <JAIL> using [BACKEND]
set <JAIL> <CMD> set the <CMD> value for <JAIL>
get <JAIL> <CMD> get the <CMD> value for <JAIL>
start <JAIL> start <JAIL>
stop <JAIL> stop <JAIL>. The jail is removed
status <JAIL> get the current status of <JAIL>
You can configure Fail2ban using the files in /etc/fail2ban.
It is possible to configure the server using commands sent to
it by fail2ban-client. The available commands are described
in the man page of fail2ban-client. Please refer to it or to
the website: http://fail2ban.sourceforge.net
Contact:
--------
You need some new features, you found bugs or you just
appreciate this program, you can contact me at :
appreciate this program, you can contact me at:
Website: http://fail2ban.sourceforge.net
@ -98,7 +72,7 @@ Kévin Drapel, Marvin Rouge, Sireyessire, Robert Edeker,
Tom Pike, Iain Lea, Andrey G. Grozin, Yaroslav Halchenko,
Jonathan Kamens, Stephen Gildea, Markus Hoffmann, Mark
Edgington, Patrick Börjesson, kojiro, zugeschmiert, Tyler,
Nick Munger, Christoph Haas
Nick Munger, Christoph Haas, Justin Shore, Joël Bertrand
License:
--------

12
TODO
View File

@ -4,7 +4,7 @@
|_| \__,_|_|_/___|_.__/\__,_|_||_|
=============================================================
ToDo $Revision: 446 $
ToDo $Revision: 468 $
=============================================================
Legend:
@ -13,7 +13,9 @@ Legend:
# partially done
* done
- Add gettext support (I8N)
- Better handling of the protocol in transmitter.py
- Add gettext support (I18N)
- Fix the cPickle issue with Python 2.5
@ -26,14 +28,8 @@ Legend:
# see Feature Request Tracking System at SourceForge.net
- improve installation process (better prefix support)
# improve documentation and website for user
# better return values in function
? restart automatically the daemon if an exception occurs.
- do not close socket after a send
# refactoring in server.py, actions.py, filter.py

View File

@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
# $Revision: 433 $
# $Revision: 458 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 433 $"
__date__ = "$Date: 2006-10-24 21:40:51 +0200 (Tue, 24 Oct 2006) $"
__version__ = "$Revision: 458 $"
__date__ = "$Date: 2006-11-12 15:52:36 +0100 (Sun, 12 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@ -69,6 +69,7 @@ class ConfigReader(SafeConfigParser):
# 0 -> the type of the option
# 1 -> the name of the option
# 2 -> the default value for the option
def getOptions(self, sec, options, pOptions = None):
values = dict()
for option in options:
@ -88,7 +89,8 @@ class ConfigReader(SafeConfigParser):
values[option[1]] = option[2]
except NoOptionError:
if not option[2] == None:
logSys.warn("No '" + option[1] + "' defined in '" + sec + "'")
logSys.warn("'%s' not defined in '%s'. Using default value"
% (option[1], sec))
values[option[1]] = option[2]
except ValueError:
logSys.warn("Wrong value for '" + option[1] + "' in '" + sec +

View File

@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
# $Revision: 443 $
# $Revision: 459 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 443 $"
__date__ = "$Date: 2006-11-01 00:36:59 +0100 (Wed, 01 Nov 2006) $"
__version__ = "$Revision: 459 $"
__date__ = "$Date: 2006-11-12 22:55:57 +0100 (Sun, 12 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@ -41,7 +41,7 @@ class CSocket:
def send(self, msg):
# Convert every list member to string
obj = dumps(map(str, msg), HIGHEST_PROTOCOL)
obj = dumps([str(m) for m in msg], HIGHEST_PROTOCOL)
self.__csock.send(obj + CSocket.END_STRING)
ret = self.receive(self.__csock)
self.__csock.close()

View File

@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
# $Revision: 433 $
# $Revision: 458 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 433 $"
__date__ = "$Date: 2006-10-24 21:40:51 +0200 (Tue, 24 Oct 2006) $"
__version__ = "$Revision: 458 $"
__date__ = "$Date: 2006-11-12 15:52:36 +0100 (Sun, 12 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@ -55,6 +55,7 @@ class FilterReader(ConfigReader):
def getOptions(self, pOpts):
opts = [["string", "timeregex", None],
["string", "timepattern", None],
["string", "ignoreregex", ""],
["string", "failregex", ""]]
self.__opts = ConfigReader.getOptions(self, "Definition", opts, pOpts)
@ -66,6 +67,8 @@ class FilterReader(ConfigReader):
elif opt == "timepattern":
stream.append(["set", self.__name, "timepattern", self.__opts[opt]])
elif opt == "failregex":
stream.append(["set", self.__name, "failregex", self.__opts[opt]])
stream.append(["set", self.__name, "failregex", self.__opts[opt]])
elif opt == "ignoreregex":
stream.append(["set", self.__name, "ignoreregex", self.__opts[opt]])
return stream

View File

@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
# $Revision: 438 $
# $Revision: 470 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 438 $"
__date__ = "$Date: 2006-10-31 00:02:05 +0100 (Tue, 31 Oct 2006) $"
__version__ = "$Revision: 470 $"
__date__ = "$Date: 2006-11-18 16:15:58 +0100 (Sat, 18 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@ -60,8 +60,10 @@ class JailReader(ConfigReader):
["string", "logpath", "/var/log/messages"],
["string", "backend", "auto"],
["int", "maxretry", 3],
["int", "maxtime", 600],
["int", "findtime", 600],
["int", "bantime", 600],
["string", "failregex", None],
["string", "ignoreregex", None],
["string", "ignoreip", None],
["string", "filter", ""],
["string", "action", ""]]
@ -111,10 +113,14 @@ class JailReader(ConfigReader):
elif opt == "ignoreip":
for ip in self.__opts[opt].split():
stream.append(["set", self.__name, "addignoreip", ip])
elif opt == "maxtime":
stream.append(["set", self.__name, "maxtime", self.__opts[opt]])
elif opt == "findtime":
stream.append(["set", self.__name, "findtime", self.__opts[opt]])
elif opt == "bantime":
stream.append(["set", self.__name, "bantime", self.__opts[opt]])
elif opt == "failregex":
stream.append(["set", self.__name, "failregex", self.__opts[opt]])
elif opt == "ignoreregex":
stream.append(["set", self.__name, "ignoreregex", self.__opts[opt]])
stream.extend(self.__filter.convert())
for action in self.__actions:
stream.extend(action.convert())

25
common/__init__.py Normal file
View File

@ -0,0 +1,25 @@
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Author: Cyril Jaquier
#
# $Revision: 433 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 433 $"
__date__ = "$Date: 2006-10-24 21:40:51 +0200 (Tue, 24 Oct 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"

107
common/protocol.py Normal file
View File

@ -0,0 +1,107 @@
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Author: Cyril Jaquier
#
# $Revision: 456 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 456 $"
__date__ = "$Date: 2006-11-12 11:56:40 +0100 (Sun, 12 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
import textwrap
##
# Describes the protocol used to communicate with the server.
protocol = [
["start", "starts the server and the jails"],
["reload", "reloads the configuration"],
["stop", "stops all jails and terminate the server"],
["status", "gets the current status of the server"],
["ping", "tests if the server is alive"],
['', ''],
["set loglevel <LEVEL>", "sets logging level to <LEVEL>. 0 is minimal, 4 is debug"],
["get loglevel", "gets the logging level"],
["set logtarget <TARGET>", "sets logging target to <TARGET>. Can be STDOUT, STDERR, SYSLOG or a file"],
["get logtarget", "gets logging target"],
['', ''],
["add <JAIL> <BACKEND>", "creates <JAIL> using <BACKEND>"],
['', ''],
["set <JAIL> idle on|off", "sets the idle state of <JAIL>"],
["set <JAIL> addignoreip <IP>", "adds <IP> to the ignore list of <JAIL>"],
["set <JAIL> delignoreip <IP>", "removes <IP> from the ignore list of <JAIL>"],
["set <JAIL> addlogpath <FILE>", "adds <FILE> to the monitoring list of <JAIL>"],
["set <JAIL> dellogpath <FILE>", "removes <FILE> to the monitoring list of <JAIL>"],
["set <JAIL> timeregex <REGEX>", "sets the regular expression <REGEX> to match the date format for <JAIL>. This will disable the autodetection feature."],
["set <JAIL> timepattern <PATTERN>", "sets the pattern <PATTERN> to match the date format for <JAIL>. This will disable the autodetection feature."],
["set <JAIL> failregex <REGEX>", "sets the regular expression <REGEX> which must match failures for <JAIL>"],
["set <JAIL> ignoreregex <REGEX>", "sets the regular expression <REGEX> which should match pattern to exclude for <JAIL>"],
["set <JAIL> findtime <TIME>", "sets the number of seconds <TIME> for which the filter will look back for <JAIL>"],
["set <JAIL> bantime <TIME>", "sets the number of seconds <TIME> a host will be banned for <JAIL>"],
["set <JAIL> maxretry <RETRY>", "sets the number of failures <RETRY> before banning the host for <JAIL>"],
["set <JAIL> addaction <ACT>", "adds a new action named <NAME> for <JAIL>"],
["set <JAIL> delaction <ACT>", "removes the action <NAME> from <JAIL>"],
["set <JAIL> setcinfo <ACT> <KEY> <VALUE>", "sets <VALUE> for <KEY> of the action <NAME> for <JAIL>"],
["set <JAIL> delcinfo <ACT> <KEY>", "removes <KEY> for the action <NAME> for <JAIL>"],
["set <JAIL> actionstart <ACT> <CMD>", "sets the start command <CMD> of the action <ACT> for <JAIL>"],
["set <JAIL> actionstop <ACT> <CMD>", "sets the stop command <CMD> of the action <ACT> for <JAIL>"],
["set <JAIL> actioncheck <ACT> <CMD>", "sets the check command <CMD> of the action <ACT> for <JAIL>"],
["set <JAIL> actionban <ACT> <CMD>", "sets the ban command <CMD> of the action <ACT> for <JAIL>"],
["set <JAIL> actionunban <ACT> <CMD>", "sets the unban command <CMD> of the action <ACT> for <JAIL>"],
['', ''],
["get <JAIL> logpath", "gets the list of the monitored files for <JAIL>"],
["get <JAIL> ignoreip", "gets the list of ignored IP addresses for <JAIL>"],
["get <JAIL> timeregex", "gets the regular expression used for the time detection for <JAIL>"],
["get <JAIL> timepattern", "gets the pattern used for the time detection for <JAIL>"],
["get <JAIL> failregex", "gets the regular expression which matches the failures for <JAIL>"],
["get <JAIL> ignoreregex", "gets the regular expression which matches patterns to ignore for <JAIL>"],
["get <JAIL> findtime", "gets the time for which the filter will look back for failures for <JAIL>"],
["get <JAIL> bantime", "gets the time a host is banned for <JAIL>"],
["get <JAIL> maxretry", "gets the number of failures allowed for <JAIL>"],
["get <JAIL> addaction", "gets the last action which has been added for <JAIL>"],
["get <JAIL> actionstart <ACT>", "gets the start command for the action <ACT> for <JAIL>"],
["get <JAIL> actionstop <ACT>", "gets the stop command for the action <ACT> for <JAIL>"],
["get <JAIL> actioncheck <ACT>", "gets the check command for the action <ACT> for <JAIL>"],
["get <JAIL> actionban <ACT>", "gets the ban command for the action <ACT> for <JAIL>"],
["get <JAIL> actionunban <ACT>", "gets the unban command for the action <ACT> for <JAIL>"],
['', ''],
["start <JAIL>", "starts the jail <JAIL>"],
["stop <JAIL>", "stops the jail <JAIL>. The jail is removed"],
["status <JAIL>", "gets the current status of <JAIL>"]
]
##
# Prints the protocol in a "man" format. This is used for the
# "-h" output of fail2ban-client.
def printFormatted():
INDENT=4
MARGIN=41
WIDTH=34
for m in protocol:
if m[0] == '':
print
first = True
for n in textwrap.wrap(m[1], WIDTH):
if first:
n = ' ' * INDENT + m[0] + ' ' * (MARGIN - len(m[0])) + n
first = False
else:
n = ' ' * (INDENT + MARGIN) + n
print n

View File

@ -16,12 +16,12 @@
# Author: Cyril Jaquier
#
# $Revision: 446 $
# $Revision: 480 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 446 $"
__date__ = "$Date: 2006-11-01 23:13:44 +0100 (Wed, 01 Nov 2006) $"
__version__ = "$Revision: 480 $"
__date__ = "$Date: 2006-12-07 22:47:53 +0100 (Thu, 07 Dec 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
version = "0.7.4"
version = "0.7.5"

View File

@ -2,7 +2,7 @@
#
# Author: Cyril Jaquier
#
# $Revision: 394 $
# $Revision: 455 $
#
[Definition]
@ -30,8 +30,7 @@ actioncheck =
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <failtime> unix timestamp of the last failure
# <bantime> unix timestamp of the ban time
# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = IP=<ip> &&
@ -41,8 +40,8 @@ actionban = IP=<ip> &&
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <bantime> unix timestamp of the ban time
# <unbantime> unix timestamp of the unban time
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = IP=<ip> &&

View File

@ -34,8 +34,7 @@ actioncheck =
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <failtime> unix timestamp of the last failure
# <bantime> unix timestamp of the ban time
# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = ipfw add deny tcp from <ip> to <localhost> <port>
@ -45,8 +44,8 @@ actionban = ipfw add deny tcp from <ip> to <localhost> <port>
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <bantime> unix timestamp of the ban time
# <unbantime> unix timestamp of the unban time
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = ipfw delete `ipfw list | grep -i <ip> | awk '{print $1;}'`

View File

@ -2,7 +2,7 @@
#
# Author: Cyril Jaquier
#
# $Revision: 394 $
# $Revision: 455 $
#
[Definition]
@ -34,8 +34,7 @@ actioncheck = iptables -L INPUT | grep -q fail2ban-<name>
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <failtime> unix timestamp of the last failure
# <bantime> unix timestamp of the ban time
# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
@ -44,8 +43,8 @@ actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <bantime> unix timestamp of the ban time
# <unbantime> unix timestamp of the unban time
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP

View File

@ -36,8 +36,7 @@ actioncheck =
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <failtime> unix timestamp of the last failure
# <bantime> unix timestamp of the ban time
# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = echo -en "Hi,\n
@ -52,8 +51,8 @@ actionban = echo -en "Hi,\n
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <bantime> unix timestamp of the ban time
# <unbantime> unix timestamp of the unban time
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban =
@ -64,7 +63,7 @@ actionunban =
#
name = default
# Destinataire of the mail
# Destination/Addressee of the mail
#
dest = root

View File

@ -36,8 +36,7 @@ actioncheck =
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <failtime> unix timestamp of the last failure
# <bantime> unix timestamp of the ban time
# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = echo -en "Hi,\n
@ -50,8 +49,8 @@ actionban = echo -en "Hi,\n
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <bantime> unix timestamp of the ban time
# <unbantime> unix timestamp of the unban time
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban =
@ -62,7 +61,7 @@ actionunban =
#
name = default
# Destinataire of the mail
# Destination/Addressee of the mail
#
dest = root

View File

@ -30,8 +30,7 @@ actioncheck =
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <failtime> unix timestamp of the last failure
# <bantime> unix timestamp of the ban time
# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = shorewall reject <ip>
@ -40,8 +39,8 @@ actionban = shorewall reject <ip>
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <bantime> unix timestamp of the ban time
# <unbantime> unix timestamp of the unban time
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = shorewall allow <ip>

View File

@ -2,13 +2,21 @@
#
# Author: Cyril Jaquier
#
# $Revision: 394 $
# $Revision: 471 $
#
[Definition]
# Option: failregex
# Notes.: regex to match the password failure messages in the logfile.
# Notes.: regex to match the password failure messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching.
# Values: TEXT
#
failregex = [[]client (?P<host>\S*)[]] user .*(?:: authentication failure|not found)
failregex = [[]client <HOST>[]] user .*(?:: authentication failure|not found)
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =

View File

@ -8,7 +8,15 @@
[Definition]
# Option: failregex
# Notes.: regex to match the password failure messages in the logfile.
# Notes.: regex to match the password failure messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching.
# Values: TEXT
#
failregex = [[]client (?P<host>\S*)[]] File does not exist: .*(\.php|\.asp)
failregex = [[]client <HOST>[]] File does not exist: .*(\.php|\.asp)
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =

View File

@ -9,7 +9,15 @@
[Definition]
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile.
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching.
# Values: TEXT
#
failregex = LOGIN FAILED, ip=\[::ffff:(?P<host>\S*)\]$
failregex = LOGIN FAILED, ip=\[<HOST>\]$
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =

View File

@ -8,7 +8,15 @@
[Definition]
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile.
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching.
# Values: TEXT
#
failregex = error,relay=(?:::f{4,6}:)?(?P<host>\S*),.*550 User unknown
failregex = error,relay=<HOST>,.*550 User unknown
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =

View File

@ -8,7 +8,15 @@
[Definition]
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile.
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching.
# Values: TEXT
#
failregex = reject: RCPT from (.*)\[(?P<host>\S*)\]: 554
failregex = reject: RCPT from (.*)\[<HOST>\]: 554
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =

View File

@ -8,7 +8,15 @@
[Definition]
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile.
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching.
# Values: TEXT
#
failregex = USER \S+: no such user found from \S* ?\[(?P<host>\S+)\] to \S+\s*$
failregex = USER \S+: no such user found from \S* ?\[<HOST>\] to \S+\s*$
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =

View File

@ -8,7 +8,15 @@
[Definition]
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile.
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching.
# Values: TEXT
#
failregex = (?:[\d,.]+[\d,.] rblsmtpd: |421 badiprbl: ip )(?P<host>\S*)
failregex = (?:[\d,.]+[\d,.] rblsmtpd: |421 badiprbl: ip )<HOST>
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =

View File

@ -8,7 +8,15 @@
[Definition]
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile.
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching.
# Values: TEXT
#
failregex = : warning: [-._\w]+\[(?P<host>[.\d]+)\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed$
failregex = : warning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed$
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =

View File

@ -2,14 +2,21 @@
#
# Author: Cyril Jaquier
#
# $Revision: 394 $
# $Revision: 471 $
#
[Definition]
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile.
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching.
# Values: TEXT
#
failregex = (?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) (?:::f{4,6}:)?(?P<host>\S*)
failregex = (?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) <HOST>
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =

View File

@ -2,13 +2,21 @@
#
# Author: Cyril Jaquier
#
# $Revision: 394 $
# $Revision: 471 $
#
[Definition]
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile.
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "<HOST>" can
# be used for standard IP/hostname matching.
# Values: TEXT
#
failregex = vsftpd: \(pam_unix\) authentication failure; .* rhost=(?P<host>\S*)
failregex = vsftpd: \(pam_unix\) authentication failure; .* rhost=<HOST>
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =

View File

@ -2,7 +2,7 @@
#
# Author: Cyril Jaquier
#
# $Revision: 421 $
# $Revision: 470 $
#
# The DEFAULT allows a global definition of the options. They can be override
@ -10,9 +10,14 @@
[DEFAULT]
# "ignoreip" can be an IP address, a CIDR mask or a DNS host
# "ignoreip" can be an IP address, a CIDR mask or a DNS host.
ignoreip = 127.0.0.1
# "bantime" is the number of seconds that a host is banned.
bantime = 600
# A host is banned if it has generated "maxretry" during the
# last "findtime" seconds.
findtime = 600
# "maxretry" is the number of failures before a host get banned.
maxretry = 3
# "backend" specifies the backend used to get files modification. Available
@ -66,15 +71,17 @@ action = iptables[name=SSH, port=ssh, protocol=tcp]
logpath = /var/log/sshd.log
maxretry = 5
# Here we use TCP-Wrappers instead of Netfilter/Iptables.
# Here we use TCP-Wrappers instead of Netfilter/Iptables. "ignoreregex" is
# used to avoid banning the user "myuser".
[ssh-tcpwrapper]
enabled = false
filter = sshd
action = hostsdeny
mail-whois[name=SSH, dest=yourmail@mail.com]
logpath = /var/log/sshd.log
enabled = false
filter = sshd
action = hostsdeny
mail-whois[name=SSH, dest=yourmail@mail.com]
ignoreregex = for myuser from
logpath = /var/log/sshd.log
# This jail demonstrates the use of wildcards in "logpath".
# Moreover, it is possible to give other files on a new line.

View File

@ -17,11 +17,11 @@
# Author: Cyril Jaquier
#
# $Revision: 444 $
# $Revision: 477 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 444 $"
__date__ = "$Date: 2006-11-01 23:03:48 +0100 (Wed, 01 Nov 2006) $"
__version__ = "$Revision: 477 $"
__date__ = "$Date: 2006-12-03 23:01:18 +0100 (Sun, 03 Dec 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@ -33,7 +33,8 @@ import getopt, time, readline, shlex, socket
sys.path.insert(1, "/usr/lib/fail2ban")
# Now we can import our modules
from version import version
from common.version import version
from common.protocol import printFormatted
from client.csocket import CSocket
from client.configurator import Configurator
from client.beautifier import Beautifier
@ -91,22 +92,10 @@ class Fail2banClient:
print " -V, --version print the version"
print
print "Command:"
print " start start the server and the jails"
print " reload reload the configuration"
print " stop stop all jails and terminate the server"
print " status get the current status"
print
print " set loglevel <LEVEL> set loglevel to <LEVEL>"
print " get loglevel get loglevel"
print " set logtarget <TARGET> set log target to <TARGET>"
print " get logtarget get log target"
print
print " add <JAIL> [BACKEND] create <JAIL> using [BACKEND]"
print " set <JAIL> <CMD> set the <CMD> value for <JAIL>"
print " get <JAIL> <CMD> get the <CMD> value for <JAIL>"
print " start <JAIL> start <JAIL>"
print " stop <JAIL> stop <JAIL>. The jail is removed"
print " status <JAIL> get the current status of <JAIL>"
# Prints the protocol
printFormatted()
print
print "Report bugs to <lostcontrol@users.sourceforge.net>"
@ -180,7 +169,8 @@ class Fail2banClient:
logSys.error("Server already running")
return False
else:
self.__startServerAsync(self.__conf["force"])
self.__startServerAsync(self.__conf["socket"],
self.__conf["force"])
# Read the config while the server is starting
self.__readConfig()
try:
@ -210,16 +200,20 @@ class Fail2banClient:
#
# Start the Fail2ban server in daemon mode.
def __startServerAsync(self, force = False):
args = list()
args.append("fail2ban-server")
args.append("-b")
if force:
args.append("-x")
def __startServerAsync(self, socket, force = False):
# Forks the current process.
pid = os.fork()
if pid == 0:
args = list()
args.append("fail2ban-server")
# Start in background mode.
args.append("-b")
# Set the socket path.
args.append("-s")
args.append(socket)
# Force the execution if needed.
if force:
args.append("-x")
try:
# Use the PATH env
os.execvp("fail2ban-server", args)
@ -236,10 +230,11 @@ class Fail2banClient:
# Wait for the server to start
cnt = 0
while not self.__ping():
if cnt > 10:
# The server has 30 secondes to start.
if cnt >= 300:
raise ServerExecutionException("Failed to start server")
time.sleep(0.1)
cnt = cnt + 1
cnt += 1
def start(self, argv):

View File

@ -31,7 +31,7 @@ import locale, getopt, sys, time, logging, gc
# fix for bug #343821
sys.path.insert(1, "/usr/lib/fail2ban")
from version import version
from common.version import version
from server.filter import Filter
# Gets the instance of the logger.

View File

@ -17,11 +17,11 @@
# Author: Cyril Jaquier
#
# $Revision: 406 $
# $Revision: 472 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 406 $"
__date__ = "$Date: 2006-10-05 00:17:53 +0200 (Thu, 05 Oct 2006) $"
__version__ = "$Revision: 472 $"
__date__ = "$Date: 2006-11-19 22:26:47 +0100 (Sun, 19 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@ -31,7 +31,7 @@ import getopt, sys
# fix for bug #343821
sys.path.insert(1, "/usr/lib/fail2ban")
from version import version
from common.version import version
from server.server import Server
##
@ -71,15 +71,16 @@ class Fail2banServer:
print "and bans the corresponding IP addresses using firewall rules."
print
print "Only use this command for debugging purpose. Start the server with"
print "fail2ban-client instead."
print "fail2ban-client instead. The default behaviour is to start the server"
print "in background."
print
print "Options:"
print " -b start in background"
print " -f start in foreground"
print " -s <FILE> socket path"
print " -x force execution of the server"
print " -h, --help display this help message"
print " -V, --version print the version"
print " -b start in background"
print " -f start in foreground"
print " -s <FILE> socket path"
print " -x force execution of the server"
print " -h, --help display this help message"
print " -V, --version print the version"
print
print "Report bugs to <lostcontrol@users.sourceforge.net>"
@ -113,6 +114,7 @@ class Fail2banServer:
optList, args = getopt.getopt(self.__argv[1:], cmdOpts, cmdLongOpts)
except getopt.GetoptError:
self.dispUsage()
sys.exit(-1)
self.__getCmdLineOptions(optList)

View File

@ -17,11 +17,11 @@
# Author: Cyril Jaquier
#
# $Revision: 429 $
# $Revision: 467 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 429 $"
__date__ = "$Date: 2006-10-23 22:13:21 +0200 (Mon, 23 Oct 2006) $"
__version__ = "$Revision: 467 $"
__date__ = "$Date: 2006-11-16 22:07:42 +0100 (Thu, 16 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@ -32,7 +32,7 @@ import unittest, logging, sys
# fix for bug #343821
sys.path.insert(1, "/usr/lib/fail2ban")
from version import version
from common.version import version
from testcases import banmanagertestcase
from testcases import clientreadertestcase
from testcases import failmanagertestcase

View File

@ -27,7 +27,7 @@ getpid() {
start() {
echo -n $"Starting fail2ban: "
getpid
if [ -z "$pid"]; then
if [ -z "$pid" ]; then
$FAIL2BAN start > /dev/null
RETVAL=$?
fi
@ -77,8 +77,8 @@ case "$1" in
fi
;;
restart)
stop
start
stop
;;
*)
echo $"Usage: $0 {start|stop|status|restart}"

View File

@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
.TH FAIL2BAN-CLIENT "1" "November 2006" "fail2ban-client v0.7.4" "User Commands"
.TH FAIL2BAN-CLIENT "1" "December 2006" "fail2ban-client v0.7.4-SVN" "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.7.4 reads log file that contains password failure report
Fail2Ban v0.7.4\-SVN reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.SH OPTIONS
.TP
@ -38,47 +38,203 @@ display this help message
print the version
.SH COMMAND
.TP
start
start the server and the jails
\fBstart\fR
starts the server and the jails
.TP
reload
reload the configuration
\fBreload\fR
reloads the configuration
.TP
stop
stop all jails and terminate the server
\fBstop\fR
stops all jails and terminate the
server
.TP
status
get the current status
\fBstatus\fR
gets the current status of the
server
.TP
set loglevel <LEVEL>
set loglevel to <LEVEL>
\fBping\fR
tests if the server is alive
.TP
get loglevel
get loglevel
\fBset loglevel <LEVEL>\fR
sets logging level to <LEVEL>. 0
is minimal, 4 is debug
.TP
set logtarget <TARGET>
set log target to <TARGET>
\fBget loglevel\fR
gets the logging level
.TP
get logtarget
get log target
\fBset logtarget <TARGET>\fR
sets logging target to <TARGET>.
Can be STDOUT, STDERR, SYSLOG or a
file
.TP
add <JAIL> [BACKEND]
create <JAIL> using [BACKEND]
\fBget logtarget\fR
gets logging target
.TP
set <JAIL> <CMD>
set the <CMD> value for <JAIL>
\fBadd <JAIL> <BACKEND>\fR
creates <JAIL> using <BACKEND>
.TP
get <JAIL> <CMD>
get the <CMD> value for <JAIL>
\fBset <JAIL> idle on|off\fR
sets the idle state of <JAIL>
.TP
start <JAIL>
start <JAIL>
\fBset <JAIL> addignoreip <IP>\fR
adds <IP> to the ignore list of
<JAIL>
.TP
stop <JAIL>
stop <JAIL>. The jail is removed
\fBset <JAIL> delignoreip <IP>\fR
removes <IP> from the ignore list
of <JAIL>
.TP
status <JAIL>
get the current status of <JAIL>
\fBset <JAIL> addlogpath <FILE>\fR
adds <FILE> to the monitoring list
of <JAIL>
.TP
\fBset <JAIL> dellogpath <FILE>\fR
removes <FILE> to the monitoring
list of <JAIL>
.TP
\fBset <JAIL> timeregex <REGEX>\fR
sets the regular expression
<REGEX> to match the date format
for <JAIL>. This will disable the
autodetection feature.
.TP
\fBset <JAIL> timepattern <PATTERN>\fR
sets the pattern <PATTERN> to
match the date format for <JAIL>.
This will disable the
autodetection feature.
.TP
\fBset <JAIL> failregex <REGEX>\fR
sets the regular expression
<REGEX> which must match failures
for <JAIL>
.TP
\fBset <JAIL> ignoreregex <REGEX>\fR
sets the regular expression
<REGEX> which should match pattern
to exclude for <JAIL>
.TP
\fBset <JAIL> findtime <TIME>\fR
sets the number of seconds <TIME>
for which the filter will look
back for <JAIL>
.TP
\fBset <JAIL> bantime <TIME>\fR
sets the number of seconds <TIME>
a host will be banned for <JAIL>
.TP
\fBset <JAIL> maxretry <RETRY>\fR
sets the number of failures
<RETRY> before banning the host
for <JAIL>
.TP
\fBset <JAIL> addaction <ACT>\fR
adds a new action named <NAME> for
<JAIL>
.TP
\fBset <JAIL> delaction <ACT>\fR
removes the action <NAME> from
<JAIL>
.TP
\fBset <JAIL> setcinfo <ACT> <KEY> <VALUE>\fR
sets <VALUE> for <KEY> of the
action <NAME> for <JAIL>
.TP
\fBset <JAIL> delcinfo <ACT> <KEY>\fR
removes <KEY> for the action
<NAME> for <JAIL>
.TP
\fBset <JAIL> actionstart <ACT> <CMD>\fR
sets the start command <CMD> of
the action <ACT> for <JAIL>
.TP
\fBset <JAIL> actionstop <ACT> <CMD>\fR
sets the stop command <CMD> of the
action <ACT> for <JAIL>
.TP
\fBset <JAIL> actioncheck <ACT> <CMD>\fR
sets the check command <CMD> of
the action <ACT> for <JAIL>
.TP
\fBset <JAIL> actionban <ACT> <CMD>\fR
sets the ban command <CMD> of the
action <ACT> for <JAIL>
.TP
\fBset <JAIL> actionunban <ACT> <CMD>\fR
sets the unban command <CMD> of
the action <ACT> for <JAIL>
.TP
\fBget <JAIL> logpath\fR
gets the list of the monitored
files for <JAIL>
.TP
\fBget <JAIL> ignoreip\fR
gets the list of ignored IP
addresses for <JAIL>
.TP
\fBget <JAIL> timeregex\fR
gets the regular expression used
for the time detection for <JAIL>
.TP
\fBget <JAIL> timepattern\fR
gets the pattern used for the time
detection for <JAIL>
.TP
\fBget <JAIL> failregex\fR
gets the regular expression which
matches the failures for <JAIL>
.TP
\fBget <JAIL> ignoreregex\fR
gets the regular expression which
matches patterns to ignore for
<JAIL>
.TP
\fBget <JAIL> findtime\fR
gets the time for which the filter
will look back for failures for
<JAIL>
.TP
\fBget <JAIL> bantime\fR
gets the time a host is banned for
<JAIL>
.TP
\fBget <JAIL> maxretry\fR
gets the number of failures
allowed for <JAIL>
.TP
\fBget <JAIL> addaction\fR
gets the last action which has
been added for <JAIL>
.TP
\fBget <JAIL> actionstart <ACT>\fR
gets the start command for the
action <ACT> for <JAIL>
.TP
\fBget <JAIL> actionstop <ACT>\fR
gets the stop command for the
action <ACT> for <JAIL>
.TP
\fBget <JAIL> actioncheck <ACT>\fR
gets the check command for the
action <ACT> for <JAIL>
.TP
\fBget <JAIL> actionban <ACT>\fR
gets the ban command for the
action <ACT> for <JAIL>
.TP
\fBget <JAIL> actionunban <ACT>\fR
gets the unban command for the
action <ACT> for <JAIL>
.TP
\fBstart <JAIL>\fR
starts the jail <JAIL>
.TP
\fBstop <JAIL>\fR
stops the jail <JAIL>. The jail is
removed
.TP
\fBstatus <JAIL>\fR
gets the current status of <JAIL>
.SH FILES
\fI/etc/fail2ban/*\fR
.SH AUTHOR

View File

@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
.TH FAIL2BAN-REGEX "1" "November 2006" "fail2ban-regex v0.7.4" "User Commands"
.TH FAIL2BAN-REGEX "1" "December 2006" "fail2ban-regex v0.7.4-SVN" "User Commands"
.SH NAME
fail2ban-regex \- test Fail2ban "failregex" option
.SH SYNOPSIS
.B fail2ban-regex
\fI<logline> <failregex>\fR
.SH DESCRIPTION
Fail2Ban v0.7.4 reads log file that contains password failure report
Fail2Ban v0.7.4\-SVN reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.PP
This tools can test and benchmark your regular expressions for the "failregex"

View File

@ -1,16 +1,17 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
.TH FAIL2BAN-SERVER "1" "November 2006" "fail2ban-server v0.7.4" "User Commands"
.TH FAIL2BAN-SERVER "1" "December 2006" "fail2ban-server v0.7.4-SVN" "User Commands"
.SH NAME
fail2ban-server \- start the server
.SH SYNOPSIS
.B fail2ban-server
[\fIOPTIONS\fR]
.SH DESCRIPTION
Fail2Ban v0.7.4 reads log file that contains password failure report
Fail2Ban v0.7.4\-SVN 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
fail2ban\-client instead.
fail2ban\-client instead. The default behaviour is to start the server
in background.
.SH OPTIONS
.TP
\fB\-b\fR

View File

@ -5,7 +5,30 @@ echo -n "Generating fail2ban-client "
help2man --section=1 --no-info --include=fail2ban-client.h2m --output fail2ban-client.1 ../fail2ban-client
echo "[done]"
echo -n "Patching fail2ban-client "
# Changes the title.
sed -i -e 's/.SS "Command:"/.SH COMMAND/' fail2ban-client.1
# Sets bold font for commands.
IFS="
"
NEXT=0
FOUND=0
LINES=$( cat fail2ban-client.1 )
echo -n "" > fail2ban-client.1
for LINE in $LINES; do
if [ "$LINE" = ".SH COMMAND" ]; then
FOUND=1
fi
if [ $NEXT -eq 1 ] && [ $FOUND -eq 1 ]; then
echo "\fB$LINE\fR" >> fail2ban-client.1
else
echo "$LINE" >> fail2ban-client.1
fi
if [ "$LINE" = ".TP" ]; then
NEXT=1
else
NEXT=0
fi
done
echo "[done]"
# fail2ban-server

View File

@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
# $Revision: 433 $
# $Revision: 455 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 433 $"
__date__ = "$Date: 2006-10-24 21:40:51 +0200 (Tue, 24 Oct 2006) $"
__version__ = "$Revision: 455 $"
__date__ = "$Date: 2006-11-12 11:56:21 +0100 (Sun, 12 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@ -134,11 +134,15 @@ class Actions(JailThread):
bTicket = BanManager.createBanTicket(ticket)
aInfo["ip"] = bTicket.getIP()
aInfo["failures"] = bTicket.getAttempt()
logSys.warn("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"]))
for action in self.__actions:
action.execActionBan(aInfo)
self.__banManager.addBanTicket(bTicket)
return True
aInfo["time"] = bTicket.getTime()
if self.__banManager.addBanTicket(bTicket):
logSys.warn("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"]))
for action in self.__actions:
action.execActionBan(aInfo)
return True
else:
logSys.warn("[%s] %s already banned" % (self.jail.getName(),
aInfo["ip"]))
return False
##
@ -148,11 +152,7 @@ class Actions(JailThread):
def __checkUnBan(self):
for ticket in self.__banManager.unBanList(MyTime.time()):
aInfo = dict()
aInfo["ip"] = ticket.getIP()
logSys.warn("[%s] Unban %s" % (self.jail.getName(), aInfo["ip"]))
for action in self.__actions:
action.execActionUnban(aInfo)
self.__unBan(ticket)
##
# Flush the ban list.
@ -162,11 +162,23 @@ class Actions(JailThread):
def __flushBan(self):
logSys.debug("Flush ban list")
for ticket in self.__banManager.flushBanList():
aInfo = dict()
aInfo["ip"] = ticket.getIP()
logSys.warn("[%s] Unban %s" % (self.jail.getName(), aInfo["ip"]))
for action in self.__actions:
action.execActionUnban(aInfo)
self.__unBan(ticket)
##
# Unbans host corresponding to the ticket.
#
# Executes the actions in order to unban the host given in the
# ticket.
def __unBan(self, ticket):
aInfo = dict()
aInfo["ip"] = ticket.getIP()
aInfo["failures"] = ticket.getAttempt()
aInfo["time"] = ticket.getTime()
logSys.warn("[%s] Unban %s" % (self.jail.getName(), aInfo["ip"]))
for action in self.__actions:
action.execActionUnban(aInfo)
##
# Get the status of the filter.
@ -176,7 +188,7 @@ class Actions(JailThread):
# @return a list with tuple
def status(self):
ret = [("Currently banned", self.__banManager.size()),
ret = [("Currently banned", self.__banManager.size()),
("Total banned", self.__banManager.getBanTotal())]
return ret

View File

@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
# $Revision: 433 $
# $Revision: 454 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 433 $"
__date__ = "$Date: 2006-10-24 21:40:51 +0200 (Tue, 24 Oct 2006) $"
__version__ = "$Revision: 454 $"
__date__ = "$Date: 2006-11-12 11:54:19 +0100 (Sun, 12 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@ -136,14 +136,6 @@ class BanManager:
finally:
self.__lock.release()
##
# Delete a ban ticket.
#
# Remove a BanTicket from the ban list.
# @param ticket the ticket
def __delBanTicket(self, ticket):
self.__banList.remove(ticket)
##
# Get the size of the ban list.
@ -177,20 +169,23 @@ class BanManager:
# Return a list of BanTicket which need to be unbanned.
# @param time the time
# @return the list of ticket to unban
# @todo Check the delete operation
def unBanList(self, time):
try:
self.__lock.acquire()
uBList = list()
# Permanent banning
if self.__banTime < 0:
return uBList
for ticket in self.__banList:
if ticket.getTime() < time - self.__banTime:
uBList.append(ticket)
self.__delBanTicket(ticket)
return uBList
return list()
# Gets the list of ticket to remove.
unBanList = [ticket for ticket in self.__banList
if ticket.getTime() < time - self.__banTime]
# Removes tickets.
self.__banList = [ticket for ticket in self.__banList
if ticket not in unBanList]
return unBanList
finally:
self.__lock.release()

View File

@ -26,7 +26,6 @@ __license__ = "GPL"
import time, logging
from datetemplate import DateTemplate
from datestrptime import DateStrptime
from datetai64n import DateTai64n
from dateepoch import DateEpoch
@ -40,7 +39,7 @@ class DateDetector:
def __init__(self):
self.__lock = Lock()
self.__templates = list()
self.__defTemplate = DateTemplate()
self.__defTemplate = DateStrptime()
def addDefaultTemplate(self):
# standard

View File

@ -42,14 +42,14 @@ class DateTemplate:
return self.__name
def setRegex(self, regex):
self.__regex = regex
self.__regex = regex.strip()
self.__cRegex = re.compile(regex)
def getRegex(self):
return self.__regex
def setPattern(self, pattern):
self.__pattern = pattern
self.__pattern = pattern.strip()
def getPattern(self):
return self.__pattern

View File

@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
# $Revision: 440 $
# $Revision: 471 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 440 $"
__date__ = "$Date: 2006-10-31 23:24:34 +0100 (Tue, 31 Oct 2006) $"
__version__ = "$Revision: 471 $"
__date__ = "$Date: 2006-11-19 22:25:51 +0100 (Sun, 19 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@ -56,7 +56,6 @@ class Filter(JailThread):
self.jail = jail
## The failures manager.
self.failManager = FailManager()
self.modified = False
## The log file handler.
self.__crtHandler = None
self.__crtFilename = None
@ -65,6 +64,9 @@ class Filter(JailThread):
## The regular expression matching the failure.
self.__failRegex = ''
self.__failRegexObj = None
## The regular expression with expression to ignore.
self.__ignoreRegex = ''
self.__ignoreRegexObj = None
## The amount of time to look back.
self.__findTime = 6000
## The ignore IP list.
@ -164,11 +166,18 @@ class Filter(JailThread):
def setFailRegex(self, value):
try:
self.__failRegexObj = re.compile(value)
self.__failRegex = value
logSys.info("Set failregex = %s" % value)
if value.lstrip() == '':
self.__failRegex = value
self.__failRegexObj = None
else:
# Replace "<HOST>" with default regular expression for host.
regex = value.replace("<HOST>", "(?:::f{4,6}:)?(?P<host>\S+)")
self.__failRegex = regex
self.__failRegexObj = re.compile(regex)
logSys.info("Set failregex = %s" % self.__failRegex)
except sre_constants.error:
logSys.error("Unable to compile regular expression " + value)
logSys.error("Unable to compile regular expression " +
self.__failRegex)
##
# Get the regular expression which matches the failure.
@ -178,6 +187,32 @@ class Filter(JailThread):
def getFailRegex(self):
return self.__failRegex
##
# Set the regular expression which matches the failure.
#
# The regular expression can also match any other pattern than failures
# and thus can be used for many purporse.
# @param value the regular expression
def setIgnoreRegex(self, value):
try:
if value.lstrip() == '':
self.__ignoreRegexObj = None
else:
self.__ignoreRegexObj = re.compile(value)
self.__ignoreRegex = value
logSys.info("Set ignoreregex = %s" % value)
except sre_constants.error:
logSys.error("Unable to compile regular expression " + value)
##
# Get the regular expression which matches the failure.
#
# @return the regular expression
def getIgnoreRegex(self):
return self.__ignoreRegex
##
# Set the time needed to find a failure.
#
@ -187,6 +222,7 @@ class Filter(JailThread):
def setFindTime(self, value):
self.__findTime = value
self.failManager.setMaxTime(value)
logSys.info("Set findtime = %s" % value)
##
@ -214,23 +250,6 @@ class Filter(JailThread):
def getMaxRetry(self):
return self.failManager.getMaxRetry()
##
# Set the maximum time a failure stays in the list.
#
# @param value the maximum time
def setMaxTime(self, value):
self.failManager.setMaxTime(value)
logSys.info("Set maxTime = %s" % value)
##
# Get the maximum time a failure stays in the list.
#
# @return the time value
def getMaxTime(self):
return self.failManager.getMaxTime()
##
# Main loop.
#
@ -394,26 +413,35 @@ class Filter(JailThread):
def findFailure(self, line):
failList = list()
# Checks if failregex is defined.
if self.__failRegexObj == None:
logSys.error("No failregex is set")
else:
match = self.__failRegexObj.search(line)
return failList
# Checks if ignoreregex is defined.
if not self.__ignoreRegexObj == None:
match = self.__ignoreRegexObj.search(line)
if match:
date = self.dateDetector.getUnixTime(match.string)
if date == None:
logSys.debug("Found a match but no valid date/time found "
+ "for " + match.string + ". Please contact "
+ "the author in order to get support for "
+ "this format")
else:
try:
ipMatch = DNSUtils.textToIp(match.group("host"))
if ipMatch:
for ip in ipMatch:
failList.append([ip, date])
except IndexError:
logSys.error("There is no 'host' group in the rule. " +
"Please correct your configuration.")
# The ignoreregex matched. Return.
logSys.debug("Ignoring this line")
return failList
match = self.__failRegexObj.search(line)
if match:
# The failregex matched.
date = self.dateDetector.getUnixTime(match.string)
if date == None:
logSys.debug("Found a match but no valid date/time found "
+ "for " + match.string + ". Please contact "
+ "the author in order to get support for "
+ "this format")
else:
try:
ipMatch = DNSUtils.textToIp(match.group("host"))
if ipMatch:
for ip in ipMatch:
failList.append([ip, date])
except IndexError:
logSys.error("There is no 'host' group in the rule. " +
"Please correct your configuration.")
return failList
@ -425,7 +453,7 @@ class Filter(JailThread):
# @return a list with tuple
def status(self):
ret = [("Currently failed", self.failManager.size()),
ret = [("Currently failed", self.failManager.size()),
("Total failed", self.failManager.getFailTotal())]
return ret
@ -451,6 +479,8 @@ class DNSUtils:
try:
return socket.gethostbyname_ex(dns)[2]
except socket.gaierror:
logSys.warn("Unable to find a corresponding IP address for %s"
% dns)
return list()
@staticmethod

View File

@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
# $Revision: 418 $
# $Revision: 451 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 418 $"
__date__ = "$Date: 2006-10-19 00:30:57 +0200 (Thu, 19 Oct 2006) $"
__version__ = "$Revision: 451 $"
__date__ = "$Date: 2006-11-06 23:47:24 +0100 (Mon, 06 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@ -50,6 +50,7 @@ class FilterGamin(Filter):
def __init__(self, jail):
Filter.__init__(self, jail)
self.__modified = False
# Gamin monitor
self.monitor = gamin.WatchMonitor()
logSys.info("Created FilterGamin")
@ -60,7 +61,7 @@ class FilterGamin(Filter):
if event in (gamin.GAMCreated, gamin.GAMChanged, gamin.GAMExists):
logSys.debug("File changed: " + path)
self.getFailures(path)
self.modified = True
self.__modified = True
##
@ -105,14 +106,14 @@ class FilterGamin(Filter):
if self.monitor.event_pending():
self.monitor.handle_events()
if self.modified:
if self.__modified:
try:
ticket = self.failManager.toBan()
self.jail.putFailTicket(ticket)
except FailManagerEmpty:
self.failManager.cleanup(MyTime.time())
self.dateDetector.sortTemplate()
self.modified = False
self.__modified = False
time.sleep(self.getSleepTime())
else:
time.sleep(self.getSleepTime())

View File

@ -50,6 +50,7 @@ class FilterPoll(Filter):
def __init__(self, jail):
Filter.__init__(self, jail)
self.__modified = False
## The time of the last modification of the file.
self.__lastModTime = dict()
self.__file404Cnt = dict()
@ -98,16 +99,16 @@ class FilterPoll(Filter):
for f in self.getLogPath():
if self.isModified(f):
self.getFailures(f)
self.modified = True
self.__modified = True
if self.modified:
if self.__modified:
try:
ticket = self.failManager.toBan()
self.jail.putFailTicket(ticket)
except FailManagerEmpty:
self.failManager.cleanup(MyTime.time())
self.dateDetector.sortTemplate()
self.modified = False
self.__modified = False
time.sleep(self.getSleepTime())
else:
time.sleep(self.getSleepTime())

View File

@ -16,18 +16,17 @@
# Author: Cyril Jaquier
#
# $Revision: 433 $
# $Revision: 452 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 433 $"
__date__ = "$Date: 2006-10-24 21:40:51 +0200 (Tue, 24 Oct 2006) $"
__version__ = "$Revision: 452 $"
__date__ = "$Date: 2006-11-06 23:48:46 +0100 (Mon, 06 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
import Queue, logging
from actions import Actions
from threading import Lock
# Gets the instance of the logger.
logSys = logging.getLogger("fail2ban.jail")
@ -35,7 +34,6 @@ logSys = logging.getLogger("fail2ban.jail")
class Jail:
def __init__(self, name, backend = "auto"):
self.__lock = Lock()
self.__name = name
self.__queue = Queue.Queue()
self.__filter = None
@ -61,89 +59,51 @@ class Jail:
self.__filter = FilterGamin(self)
def setName(self, name):
self.__lock.acquire()
self.__name = name
self.__lock.release()
def getName(self):
try:
self.__lock.acquire()
return self.__name
finally:
self.__lock.release()
return self.__name
def getFilter(self):
try:
self.__lock.acquire()
return self.__filter
finally:
self.__lock.release()
return self.__filter
def getAction(self):
try:
self.__lock.acquire()
return self.__action
finally:
self.__lock.release()
return self.__action
def putFailTicket(self, ticket):
self.__lock.acquire()
self.__queue.put(ticket)
self.__lock.release()
def getFailTicket(self):
try:
self.__lock.acquire()
try:
return self.__queue.get(False)
except Queue.Empty:
return False
finally:
self.__lock.release()
return self.__queue.get(False)
except Queue.Empty:
return False
def start(self):
self.__lock.acquire()
self.__filter.start()
self.__action.start()
self.__lock.release()
def stop(self):
self.__lock.acquire()
self.__filter.stop()
self.__action.stop()
self.__lock.release()
self.__filter.join()
self.__action.join()
def isActive(self):
try:
self.__lock.acquire()
isActive0 = self.__filter.isActive()
isActive1 = self.__action.isActive()
return isActive0 or isActive1
finally:
self.__lock.release()
isActive0 = self.__filter.isActive()
isActive1 = self.__action.isActive()
return isActive0 or isActive1
def setIdle(self, value):
self.__lock.acquire()
self.__filter.setIdle(value)
self.__action.setIdle(value)
self.__lock.release()
def getIdle(self):
try:
self.__lock.acquire()
return self.__filter.getIdle() or self.__action.getIdle()
finally:
self.__lock.release()
return self.__filter.getIdle() or self.__action.getIdle()
def getStatus(self):
try:
self.__lock.acquire()
fStatus = self.__filter.status()
aStatus = self.__action.status()
ret = [("filter", fStatus),
("action", aStatus)]
return ret
finally:
self.__lock.release()
fStatus = self.__filter.status()
aStatus = self.__action.status()
ret = [("filter", fStatus),
("action", aStatus)]
return ret

View File

@ -28,29 +28,63 @@ __license__ = "GPL"
from jail import Jail
from threading import Lock
##
# Handles the jails.
#
# This class handles the jails. Creation, deletion or access to a jail must be
# done through this class. This class is thread-safe which is not the case of
# the jail itself, including filter and actions.
class Jails:
##
# Constructor.
def __init__(self):
self.__lock = Lock()
self.__jails = dict()
##
# Adds a jail.
#
# Adds a new jail which should use the given backend. Raises a
# <code>DuplicateJailException</code> if the jail is already defined.
# @param name The name of the jail
# @param backend The backend to use
def add(self, name, backend):
self.__lock.acquire()
if self.__jails.has_key(name):
self.__lock.release()
raise DuplicateJailException(name)
else:
self.__jails[name] = Jail(name, backend)
try:
self.__lock.acquire()
if self.__jails.has_key(name):
raise DuplicateJailException(name)
else:
self.__jails[name] = Jail(name, backend)
finally:
self.__lock.release()
##
# Removes a jail.
#
# Removes the jail <code>name</code>. Raise an <code>UnknownJailException</code>
# if the jail does not exist.
# @param name The name of the jail
def remove(self, name):
self.__lock.acquire()
if self.__jails.has_key(name):
del self.__jails[name]
try:
self.__lock.acquire()
if self.__jails.has_key(name):
del self.__jails[name]
else:
raise UnknownJailException(name)
finally:
self.__lock.release()
else:
self.__lock.release()
raise UnknownJailException(name)
##
# Returns a jail.
#
# Returns the jail <code>name</code>. Raise an <code>UnknownJailException</code>
# if the jail does not exist.
# @param name The name of the jail
def get(self, name):
try:
@ -63,6 +97,13 @@ class Jails:
finally:
self.__lock.release()
##
# Returns an action class instance.
#
# Returns the action object of the jail <code>name</code>. Raise an
# <code>UnknownJailException</code> if the jail does not exist.
# @param name The name of the jail
def getAction(self, name):
try:
self.__lock.acquire()
@ -74,6 +115,13 @@ class Jails:
finally:
self.__lock.release()
##
# Returns a filter class instance.
#
# Returns the filter object of the jail <code>name</code>. Raise an
# <code>UnknownJailException</code> if the jail does not exist.
# @param name The name of the jail
def getFilter(self, name):
try:
self.__lock.acquire()
@ -85,6 +133,11 @@ class Jails:
finally:
self.__lock.release()
##
# Returns the jails.
#
# Returns a copy of the jails list.
def getAll(self):
try:
self.__lock.acquire()
@ -92,6 +145,11 @@ class Jails:
finally:
self.__lock.release()
##
# Returns the size of the jails.
#
# Returns the number of jails.
def size(self):
try:
self.__lock.acquire()

View File

@ -16,14 +16,15 @@
# Author: Cyril Jaquier
#
# $Revision: 436 $
# $Revision: 470 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 436 $"
__date__ = "$Date: 2006-10-30 23:47:30 +0100 (Mon, 30 Oct 2006) $"
__version__ = "$Revision: 470 $"
__date__ = "$Date: 2006-11-18 16:15:58 +0100 (Sat, 18 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
from threading import Lock, RLock
from jails import Jails
from transmitter import Transmitter
from ssocket import SSocket
@ -36,6 +37,8 @@ logSys = logging.getLogger("fail2ban.server")
class Server:
def __init__(self, daemon = False):
self.__loggingLock = Lock()
self.__lock = RLock()
self.__jails = Jails()
self.__daemon = daemon
self.__transm = Transmitter(self)
@ -91,17 +94,29 @@ class Server:
self.__jails.remove(name)
def startJail(self, name):
if not self.isActive(name):
self.__jails.get(name).start()
try:
self.__lock.acquire()
if not self.isActive(name):
self.__jails.get(name).start()
finally:
self.__lock.release()
def stopJail(self, name):
if self.isActive(name):
self.__jails.get(name).stop()
self.delJail(name)
try:
self.__lock.acquire()
if self.isActive(name):
self.__jails.get(name).stop()
self.delJail(name)
finally:
self.__lock.release()
def stopAllJail(self):
for jail in self.__jails.getAll():
self.stopJail(jail)
try:
self.__lock.acquire()
for jail in self.__jails.getAll():
self.stopJail(jail)
finally:
self.__lock.release()
def isActive(self, name):
return self.__jails.get(name).isActive()
@ -156,18 +171,18 @@ class Server:
def getFailRegex(self, name):
return self.__jails.getFilter(name).getFailRegex()
def setIgnoreRegex(self, name, value):
self.__jails.getFilter(name).setIgnoreRegex(value)
def getIgnoreRegex(self, name):
return self.__jails.getFilter(name).getIgnoreRegex()
def setMaxRetry(self, name, value):
self.__jails.getFilter(name).setMaxRetry(value)
def getMaxRetry(self, name):
return self.__jails.getFilter(name).getMaxRetry()
def setMaxTime(self, name, value):
self.__jails.getFilter(name).setMaxTime(value)
def getMaxTime(self, name):
return self.__jails.getFilter(name).getMaxTime()
# Action
def addAction(self, name, value):
self.__jails.getAction(name).addAction(value)
@ -225,15 +240,19 @@ class Server:
# Status
def status(self):
jailList = ''
for jail in self.__jails.getAll():
jailList += jail + ', '
length = len(jailList)
if not length == 0:
jailList = jailList[:length-2]
ret = [("Number of jail", self.__jails.size()),
("Jail list", jailList)]
return ret
try:
self.__lock.acquire()
jailList = ''
for jail in self.__jails.getAll():
jailList += jail + ', '
length = len(jailList)
if not length == 0:
jailList = jailList[:length-2]
ret = [("Number of jail", self.__jails.size()),
("Jail list", jailList)]
return ret
finally:
self.__lock.release()
def statusJail(self, name):
return self.__jails.get(name).getStatus()
@ -252,17 +271,21 @@ class Server:
# @param value the level
def setLogLevel(self, value):
self.__logLevel = value
logLevel = logging.DEBUG
if value == 0:
logLevel = logging.FATAL
elif value == 1:
logLevel = logging.ERROR
elif value == 2:
logLevel = logging.WARNING
elif value == 3:
logLevel = logging.INFO
logging.getLogger("fail2ban").setLevel(logLevel)
try:
self.__loggingLock.acquire()
self.__logLevel = value
logLevel = logging.DEBUG
if value == 0:
logLevel = logging.FATAL
elif value == 1:
logLevel = logging.ERROR
elif value == 2:
logLevel = logging.WARNING
elif value == 3:
logLevel = logging.INFO
logging.getLogger("fail2ban").setLevel(logLevel)
finally:
self.__loggingLock.release()
##
# Get the logging level.
@ -271,35 +294,47 @@ class Server:
# @return the log level
def getLogLevel(self):
return self.__logLevel
try:
self.__loggingLock.acquire()
return self.__logLevel
finally:
self.__loggingLock.release()
def setLogTarget(self, target):
# Remove previous handler
logging.getLogger("fail2ban").handlers = []
self.__logTarget = target
if target == "SYSLOG":
hdlr = logging.handlers.SysLogHandler()
elif target == "STDOUT":
hdlr = logging.StreamHandler(sys.stdout)
elif target == "STDERR":
hdlr = logging.StreamHandler(sys.stderr)
else:
# Target should be a file
try:
open(target, "a")
hdlr = logging.FileHandler(target)
except IOError:
logSys.error("Unable to log to " + target)
return False
# set a format which is simpler for console use
formatter = logging.Formatter("%(asctime)s %(name)-16s: %(levelname)-6s %(message)s")
# tell the handler to use this format
hdlr.setFormatter(formatter)
logging.getLogger("fail2ban").addHandler(hdlr)
return True
try:
self.__loggingLock.acquire()
# Remove previous handler
logging.getLogger("fail2ban").handlers = []
if target == "SYSLOG":
hdlr = logging.handlers.SysLogHandler()
elif target == "STDOUT":
hdlr = logging.StreamHandler(sys.stdout)
elif target == "STDERR":
hdlr = logging.StreamHandler(sys.stderr)
else:
# Target should be a file
try:
open(target, "a")
hdlr = logging.FileHandler(target)
except IOError:
logSys.error("Unable to log to " + target)
return False
self.__logTarget = target
# set a format which is simpler for console use
formatter = logging.Formatter("%(asctime)s %(name)-16s: %(levelname)-6s %(message)s")
# tell the handler to use this format
hdlr.setFormatter(formatter)
logging.getLogger("fail2ban").addHandler(hdlr)
return True
finally:
self.__loggingLock.release()
def getLogTarget(self):
return self.__logTarget
try:
self.__loggingLock.acquire()
return self.__logTarget
finally:
self.__loggingLock.release()
def __createDaemon(self):
""" Detach a process from the controlling terminal and run it in the

View File

@ -16,15 +16,14 @@
# Author: Cyril Jaquier
#
# $Revision: 409 $
# $Revision: 470 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 409 $"
__date__ = "$Date: 2006-10-16 21:42:50 +0200 (Mon, 16 Oct 2006) $"
__version__ = "$Revision: 470 $"
__date__ = "$Date: 2006-11-18 16:15:58 +0100 (Sat, 18 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
from threading import Lock
import logging, time
# Gets the instance of the logger.
@ -32,229 +31,235 @@ logSys = logging.getLogger("fail2ban.comm")
class Transmitter:
##
# Constructor.
#
# @param The server reference
def __init__(self, server):
self.__lock = Lock()
self.__server = server
def proceed(self, action):
##
# Proceeds a command.
#
# Proceeds an incoming command.
# @param command The incoming command
def proceed(self, command):
# Deserialize object
logSys.debug("Command: " + `command`)
try:
self.__lock.acquire()
logSys.debug("Action: " + `action`)
try:
ret = self.__actionHandler(action)
ack = 0, ret
except Exception, e:
logSys.warn("Invalid command: " + `action`)
ack = 1, e
return ack
finally:
self.__lock.release()
ret = self.__commandHandler(command)
ack = 0, ret
except Exception, e:
logSys.warn("Invalid command: " + `command`)
ack = 1, e
return ack
##
# Handle an action.
# Handle an command.
#
#
def __actionHandler(self, action):
if action[0] == "ping":
def __commandHandler(self, command):
if command[0] == "ping":
return "pong"
elif action[0] == "add":
name = action[1]
elif command[0] == "add":
name = command[1]
if name == "all":
raise Exception("Reserved name")
try:
backend = action[2]
backend = command[2]
except IndexError:
backend = "auto"
self.__server.addJail(name, backend)
return name
elif action[0] == "start":
name = action[1]
elif command[0] == "start":
name = command[1]
self.__server.startJail(name)
return None
elif action[0] == "stop":
if len(action) == 1:
elif command[0] == "stop":
if len(command) == 1:
self.__server.quit()
elif action[1] == "all":
elif command[1] == "all":
self.__server.stopAllJail()
else:
name = action[1]
name = command[1]
self.__server.stopJail(name)
return None
elif action[0] == "sleep":
value = action[1]
elif command[0] == "sleep":
value = command[1]
time.sleep(int(value))
return None
elif action[0] == "set":
return self.__actionSet(action[1:])
elif action[0] == "get":
return self.__actionGet(action[1:])
elif action[0] == "status":
return self.status(action[1:])
elif command[0] == "set":
return self.__commandSet(command[1:])
elif command[0] == "get":
return self.__commandGet(command[1:])
elif command[0] == "status":
return self.status(command[1:])
raise Exception("Invalid command")
def __actionSet(self, action):
name = action[0]
def __commandSet(self, command):
name = command[0]
# Logging
if name == "loglevel":
value = int(action[1])
value = int(command[1])
self.__server.setLogLevel(value)
return self.__server.getLogLevel()
elif name == "logtarget":
value = action[1]
value = command[1]
self.__server.setLogTarget(value)
return self.__server.getLogTarget()
# Jail
elif action[1] == "idle":
if action[2] == "on":
elif command[1] == "idle":
if command[2] == "on":
self.__server.setIdleJail(name, True)
elif action[2] == "off":
elif command[2] == "off":
self.__server.setIdleJail(name, False)
return self.__server.getIdleJail(name)
# Filter
elif action[1] == "addignoreip":
value = action[2]
elif command[1] == "addignoreip":
value = command[2]
self.__server.addIgnoreIP(name, value)
return self.__server.getIgnoreIP(name)
elif action[1] == "delignoreip":
value = action[2]
elif command[1] == "delignoreip":
value = command[2]
self.__server.delIgnoreIP(name, value)
return self.__server.getIgnoreIP(name)
elif action[1] == "addlogpath":
value = action[2:]
elif command[1] == "addlogpath":
value = command[2:]
for path in value:
self.__server.addLogPath(name, path)
return self.__server.getLogPath(name)
elif action[1] == "dellogpath":
value = action[2]
elif command[1] == "dellogpath":
value = command[2]
self.__server.delLogPath(name, value)
return self.__server.getLogPath(name)
elif action[1] == "timeregex":
value = action[2]
elif command[1] == "timeregex":
value = command[2]
self.__server.setTimeRegex(name, value)
return self.__server.getTimeRegex(name)
elif action[1] == "timepattern":
value = action[2]
elif command[1] == "timepattern":
value = command[2]
self.__server.setTimePattern(name, value)
return self.__server.getTimePattern(name)
elif action[1] == "failregex":
value = action[2]
elif command[1] == "failregex":
value = command[2]
self.__server.setFailRegex(name, value)
return self.__server.getFailRegex(name)
elif action[1] == "maxtime":
value = action[2]
self.__server.setMaxTime(name, int(value))
return self.__server.getMaxTime(name)
elif action[1] == "findtime":
value = action[2]
elif command[1] == "ignoreregex":
value = command[2]
self.__server.setIgnoreRegex(name, value)
return self.__server.getIgnoreRegex(name)
elif command[1] == "findtime":
value = command[2]
self.__server.setFindTime(name, int(value))
return self.__server.getFindTime(name)
elif action[1] == "maxretry":
value = action[2]
elif command[1] == "maxretry":
value = command[2]
self.__server.setMaxRetry(name, int(value))
return self.__server.getMaxRetry(name)
# Action
elif action[1] == "bantime":
value = action[2]
# command
elif command[1] == "bantime":
value = command[2]
self.__server.setBanTime(name, int(value))
return self.__server.getBanTime(name)
elif action[1] == "addaction":
value = action[2]
elif command[1] == "addaction":
value = command[2]
self.__server.addAction(name, value)
return self.__server.getLastAction(name).getName()
elif action[1] == "delaction":
elif command[1] == "delaction":
self.__server.delAction(name, value)
return None
elif action[1] == "setcinfo":
act = action[2]
key = action[3]
value = action[4]
elif command[1] == "setcinfo":
act = command[2]
key = command[3]
value = command[4]
self.__server.setCInfo(name, act, key, value)
return self.__server.getCInfo(name, act, key)
elif action[1] == "delcinfo":
act = action[2]
key = action[3]
elif command[1] == "delcinfo":
act = command[2]
key = command[3]
self.__server.delCInfo(name, act, key)
return None
elif action[1] == "actionstart":
act = action[2]
value = action[3]
elif command[1] == "actionstart":
act = command[2]
value = command[3]
self.__server.setActionStart(name, act, value)
return self.__server.getActionStart(name, act)
elif action[1] == "actionstop":
act = action[2]
value = action[3]
elif command[1] == "actionstop":
act = command[2]
value = command[3]
self.__server.setActionStop(name, act, value)
return self.__server.getActionStop(name, act)
elif action[1] == "actioncheck":
act = action[2]
value = action[3]
elif command[1] == "actioncheck":
act = command[2]
value = command[3]
self.__server.setActionCheck(name, act, value)
return self.__server.getActionCheck(name, act)
elif action[1] == "actionban":
act = action[2]
value = action[3]
elif command[1] == "actionban":
act = command[2]
value = command[3]
self.__server.setActionBan(name, act, value)
return self.__server.getActionBan(name, act)
elif action[1] == "actionunban":
act = action[2]
value = action[3]
elif command[1] == "actionunban":
act = command[2]
value = command[3]
self.__server.setActionUnban(name, act, value)
return self.__server.getActionUnban(name, act)
raise Exception("Invalid command (no set action or not yet implemented)")
def __actionGet(self, action):
name = action[0]
def __commandGet(self, command):
name = command[0]
# Logging
if name == "loglevel":
return self.__server.getLogLevel()
elif name == "logtarget":
return self.__server.getLogTarget()
# Filter
elif action[1] == "logpath":
elif command[1] == "logpath":
return self.__server.getLogPath(name)
elif action[1] == "ignoreip":
elif command[1] == "ignoreip":
return self.__server.getIgnoreIP(name)
elif action[1] == "timeregex":
elif command[1] == "timeregex":
return self.__server.getTimeRegex(name)
elif action[1] == "timepattern":
elif command[1] == "timepattern":
return self.__server.getTimePattern(name)
elif action[1] == "failregex":
elif command[1] == "failregex":
return self.__server.getFailRegex(name)
elif action[1] == "maxtime":
return self.__server.getMaxTime(name)
elif action[1] == "findtime":
elif command[1] == "ignoreregex":
return self.__server.getIgnoreRegex(name)
elif command[1] == "findtime":
return self.__server.getFindTime(name)
elif action[1] == "maxretry":
elif command[1] == "maxretry":
return self.__server.getMaxRetry(name)
# Action
elif action[1] == "bantime":
elif command[1] == "bantime":
return self.__server.getBanTime(name)
elif action[1] == "addaction":
elif command[1] == "addaction":
return self.__server.getLastAction(name).getName()
elif action[1] == "actionstart":
act = action[2]
elif command[1] == "actionstart":
act = command[2]
return self.__server.getActionStart(name, act)
elif action[1] == "actionstop":
act = action[2]
elif command[1] == "actionstop":
act = command[2]
return self.__server.getActionStop(name, act)
elif action[1] == "actioncheck":
act = action[2]
elif command[1] == "actioncheck":
act = command[2]
return self.__server.getActionCheck(name, act)
elif action[1] == "actionban":
act = action[2]
elif command[1] == "actionban":
act = command[2]
return self.__server.getActionBan(name, act)
elif action[1] == "actionunban":
act = action[2]
elif command[1] == "actionunban":
act = command[2]
return self.__server.getActionUnban(name, act)
raise Exception("Invalid command (no get action or not yet implemented)")
def status(self, action):
if len(action) == 0:
def status(self, command):
if len(command) == 0:
return self.__server.status()
else:
name = action[0]
name = command[0]
return self.__server.statusJail(name)
raise Exception("Invalid command (no status)")

View File

@ -18,18 +18,18 @@
# Author: Cyril Jaquier
#
# $Revision: 413 $
# $Revision: 473 $
__author__ = "Cyril Jaquier"
__version__ = "$Revision: 413 $"
__date__ = "$Date: 2006-10-17 23:13:11 +0200 (Tue, 17 Oct 2006) $"
__version__ = "$Revision: 473 $"
__date__ = "$Date: 2006-11-19 22:35:54 +0100 (Sun, 19 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
from distutils.core import setup
from version import version
from common.version import version
from os.path import isfile, join
from sys import exit, argv
from sys import argv
from glob import glob
longdesc = '''
@ -40,33 +40,33 @@ to reject the IP address or executes user defined
commands.'''
setup(
name = "fail2ban",
version = version,
description = "Ban IPs that make too many password failure",
long_description = longdesc,
author = "Cyril Jaquier",
author_email = "lostcontrol@users.sourceforge.net",
url = "http://fail2ban.sourceforge.net",
license = "GPL",
platforms = "Posix",
name = "fail2ban",
version = version,
description = "Ban IPs that make too many password failure",
long_description = longdesc,
author = "Cyril Jaquier",
author_email = "lostcontrol@users.sourceforge.net",
url = "http://fail2ban.sourceforge.net",
license = "GPL",
platforms = "Posix",
scripts = [
'fail2ban-client',
'fail2ban-server',
'fail2ban-client',
'fail2ban-server',
'fail2ban-regex'
],
py_modules = ['version'],
],
packages = [
'client',
'common',
'client',
'server'
],
],
data_files = [
('/etc/fail2ban',
('/etc/fail2ban',
glob("config/*.conf")
),
('/etc/fail2ban/filter.d',
),
('/etc/fail2ban/filter.d',
glob("config/filter.d/*.conf")
),
('/etc/fail2ban/action.d',
),
('/etc/fail2ban/action.d',
glob("config/action.d/*.conf")
)
]
@ -79,24 +79,30 @@ elements = {
"/etc/":
[
"fail2ban.conf"
],
],
"/usr/bin/":
[
"fail2ban.py"
],
],
"/usr/lib/fail2ban/firewall/":
[
"iptables.py",
"ipfwadm.py",
"iptables.py",
"ipfwadm.py",
"ipfw.py"
],
"/usr/lib/fail2ban/":
[
"version.py",
"protocol.py"
]
}
for dir in elements:
for f in elements[dir]:
path = join(dir, f)
for directory in elements:
for f in elements[directory]:
path = join(directory, f)
if isfile(path):
obsoleteFiles.append(path)
if obsoleteFiles:
print
print "Obsolete files from previous Fail2Ban versions were found on " \

View File

@ -24,7 +24,7 @@ __date__ = "$Date: 2006-07-17 00:21:58 +0200 (Mon, 17 Jul 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
import unittest, time
import unittest
from server.datedetector import DateDetector
from server.datetemplate import DateTemplate
@ -53,4 +53,15 @@ class DateDetectorTest(unittest.TestCase):
self.assertEqual(self.__datedetector.getTime(log), date)
self.assertEqual(self.__datedetector.getUnixTime(log), dateUnix)
def testDefaultTempate(self):
self.__datedetector.setDefaultRegex("^\S{3}\s{1,2}\d{1,2} \d{2}:\d{2}:\d{2}")
self.__datedetector.setDefaultPattern("%b %d %H:%M:%S")
log = "Jan 23 21:59:59 [sshd] error: PAM: Authentication failure"
date = [2005, 1, 23, 21, 59, 59, 1, 23, -1]
dateUnix = 1106513999.0
self.assertEqual(self.__datedetector.getTime(log), date)
self.assertEqual(self.__datedetector.getUnixTime(log), dateUnix)