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 ver. 0.7.4 (2006/11/01) - beta
---------- ----------
- Improved configuration files. Thanks to Yaroslav Halchenko - Improved configuration files. Thanks to Yaroslav Halchenko

View File

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

54
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 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 the user. Fail2Ban can read multiple log files such as sshd
or Apache web server ones. 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 website: http://fail2ban.sourceforge.net
Installation: Installation:
@ -27,8 +28,8 @@ Optional:
To install, just do: To install, just do:
> tar xvfj fail2ban-0.7.4.tar.bz2 > tar xvfj fail2ban-0.7.5.tar.bz2
> cd fail2ban-0.7.4 > cd fail2ban-0.7.5
> python setup.py install > python setup.py install
This will install Fail2Ban into /usr/lib/fail2ban. The This will install Fail2Ban into /usr/lib/fail2ban. The
@ -38,48 +39,21 @@ Gentoo: ebuilds are available on the website.
Debian: Fail2Ban is in Debian unstable. Debian: Fail2Ban is in Debian unstable.
RedHat: packages are available on the website. 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 > 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: Configuration:
-------------- --------------
You can configure fail2ban using the files in /etc/fail2ban You can configure Fail2ban using the files in /etc/fail2ban.
or using command line. Here are the available command line It is possible to configure the server using commands sent to
options (not complete yet): it by fail2ban-client. The available commands are described
in the man page of fail2ban-client. Please refer to it or to
Options: the website: http://fail2ban.sourceforge.net
-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>
Contact: Contact:
-------- --------
@ -98,7 +72,7 @@ Kévin Drapel, Marvin Rouge, Sireyessire, Robert Edeker,
Tom Pike, Iain Lea, Andrey G. Grozin, Yaroslav Halchenko, Tom Pike, Iain Lea, Andrey G. Grozin, Yaroslav Halchenko,
Jonathan Kamens, Stephen Gildea, Markus Hoffmann, Mark Jonathan Kamens, Stephen Gildea, Markus Hoffmann, Mark
Edgington, Patrick Börjesson, kojiro, zugeschmiert, Tyler, Edgington, Patrick Börjesson, kojiro, zugeschmiert, Tyler,
Nick Munger, Christoph Haas Nick Munger, Christoph Haas, Justin Shore, Joël Bertrand
License: License:
-------- --------

12
TODO
View File

@ -4,7 +4,7 @@
|_| \__,_|_|_/___|_.__/\__,_|_||_| |_| \__,_|_|_/___|_.__/\__,_|_||_|
============================================================= =============================================================
ToDo $Revision: 446 $ ToDo $Revision: 468 $
============================================================= =============================================================
Legend: Legend:
@ -13,7 +13,9 @@ Legend:
# partially done # partially done
* 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 - Fix the cPickle issue with Python 2.5
@ -26,14 +28,8 @@ Legend:
# see Feature Request Tracking System at SourceForge.net # see Feature Request Tracking System at SourceForge.net
- improve installation process (better prefix support)
# improve documentation and website for user # improve documentation and website for user
# better return values in function # 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 # refactoring in server.py, actions.py, filter.py

View File

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

View File

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

View File

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

View File

@ -16,11 +16,11 @@
# Author: Cyril Jaquier # Author: Cyril Jaquier
# #
# $Revision: 438 $ # $Revision: 470 $
__author__ = "Cyril Jaquier" __author__ = "Cyril Jaquier"
__version__ = "$Revision: 438 $" __version__ = "$Revision: 470 $"
__date__ = "$Date: 2006-10-31 00:02:05 +0100 (Tue, 31 Oct 2006) $" __date__ = "$Date: 2006-11-18 16:15:58 +0100 (Sat, 18 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
@ -60,8 +60,10 @@ class JailReader(ConfigReader):
["string", "logpath", "/var/log/messages"], ["string", "logpath", "/var/log/messages"],
["string", "backend", "auto"], ["string", "backend", "auto"],
["int", "maxretry", 3], ["int", "maxretry", 3],
["int", "maxtime", 600], ["int", "findtime", 600],
["int", "bantime", 600], ["int", "bantime", 600],
["string", "failregex", None],
["string", "ignoreregex", None],
["string", "ignoreip", None], ["string", "ignoreip", None],
["string", "filter", ""], ["string", "filter", ""],
["string", "action", ""]] ["string", "action", ""]]
@ -111,10 +113,14 @@ class JailReader(ConfigReader):
elif opt == "ignoreip": elif opt == "ignoreip":
for ip in self.__opts[opt].split(): for ip in self.__opts[opt].split():
stream.append(["set", self.__name, "addignoreip", ip]) stream.append(["set", self.__name, "addignoreip", ip])
elif opt == "maxtime": elif opt == "findtime":
stream.append(["set", self.__name, "maxtime", self.__opts[opt]]) stream.append(["set", self.__name, "findtime", self.__opts[opt]])
elif opt == "bantime": elif opt == "bantime":
stream.append(["set", self.__name, "bantime", self.__opts[opt]]) 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()) stream.extend(self.__filter.convert())
for action in self.__actions: for action in self.__actions:
stream.extend(action.convert()) 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 # Author: Cyril Jaquier
# #
# $Revision: 446 $ # $Revision: 480 $
__author__ = "Cyril Jaquier" __author__ = "Cyril Jaquier"
__version__ = "$Revision: 446 $" __version__ = "$Revision: 480 $"
__date__ = "$Date: 2006-11-01 23:13:44 +0100 (Wed, 01 Nov 2006) $" __date__ = "$Date: 2006-12-07 22:47:53 +0100 (Thu, 07 Dec 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
version = "0.7.4" version = "0.7.5"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,13 +2,21 @@
# #
# Author: Cyril Jaquier # Author: Cyril Jaquier
# #
# $Revision: 394 $ # $Revision: 471 $
# #
[Definition] [Definition]
# Option: failregex # 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 # 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] [Definition]
# Option: failregex # 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 # 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] [Definition]
# Option: failregex # 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 # 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] [Definition]
# Option: failregex # 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 # 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] [Definition]
# Option: failregex # 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 # 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] [Definition]
# Option: failregex # 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 # 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] [Definition]
# Option: failregex # 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 # 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] [Definition]
# Option: failregex # 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 # 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 # Author: Cyril Jaquier
# #
# $Revision: 394 $ # $Revision: 471 $
# #
[Definition] [Definition]
# Option: failregex # 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 # 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 # Author: Cyril Jaquier
# #
# $Revision: 394 $ # $Revision: 471 $
# #
[Definition] [Definition]
# Option: failregex # 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 # 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 # Author: Cyril Jaquier
# #
# $Revision: 421 $ # $Revision: 470 $
# #
# The DEFAULT allows a global definition of the options. They can be override # The DEFAULT allows a global definition of the options. They can be override
@ -10,9 +10,14 @@
[DEFAULT] [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 ignoreip = 127.0.0.1
# "bantime" is the number of seconds that a host is banned.
bantime = 600 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 maxretry = 3
# "backend" specifies the backend used to get files modification. Available # "backend" specifies the backend used to get files modification. Available
@ -66,7 +71,8 @@ action = iptables[name=SSH, port=ssh, protocol=tcp]
logpath = /var/log/sshd.log logpath = /var/log/sshd.log
maxretry = 5 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] [ssh-tcpwrapper]
@ -74,6 +80,7 @@ enabled = false
filter = sshd filter = sshd
action = hostsdeny action = hostsdeny
mail-whois[name=SSH, dest=yourmail@mail.com] mail-whois[name=SSH, dest=yourmail@mail.com]
ignoreregex = for myuser from
logpath = /var/log/sshd.log logpath = /var/log/sshd.log
# This jail demonstrates the use of wildcards in "logpath". # This jail demonstrates the use of wildcards in "logpath".

View File

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

View File

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

View File

@ -17,11 +17,11 @@
# Author: Cyril Jaquier # Author: Cyril Jaquier
# #
# $Revision: 406 $ # $Revision: 472 $
__author__ = "Cyril Jaquier" __author__ = "Cyril Jaquier"
__version__ = "$Revision: 406 $" __version__ = "$Revision: 472 $"
__date__ = "$Date: 2006-10-05 00:17:53 +0200 (Thu, 05 Oct 2006) $" __date__ = "$Date: 2006-11-19 22:26:47 +0100 (Sun, 19 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
@ -31,7 +31,7 @@ import getopt, sys
# fix for bug #343821 # fix for bug #343821
sys.path.insert(1, "/usr/lib/fail2ban") sys.path.insert(1, "/usr/lib/fail2ban")
from version import version from common.version import version
from server.server import Server from server.server import Server
## ##
@ -71,7 +71,8 @@ class Fail2banServer:
print "and bans the corresponding IP addresses using firewall rules." print "and bans the corresponding IP addresses using firewall rules."
print print
print "Only use this command for debugging purpose. Start the server with" 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
print "Options:" print "Options:"
print " -b start in background" print " -b start in background"
@ -113,6 +114,7 @@ class Fail2banServer:
optList, args = getopt.getopt(self.__argv[1:], cmdOpts, cmdLongOpts) optList, args = getopt.getopt(self.__argv[1:], cmdOpts, cmdLongOpts)
except getopt.GetoptError: except getopt.GetoptError:
self.dispUsage() self.dispUsage()
sys.exit(-1)
self.__getCmdLineOptions(optList) self.__getCmdLineOptions(optList)

View File

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

View File

@ -77,8 +77,8 @@ case "$1" in
fi fi
;; ;;
restart) restart)
start
stop stop
start
;; ;;
*) *)
echo $"Usage: $0 {start|stop|status|restart}" 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. .\" 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 .SH NAME
fail2ban-client \- configure and control the server fail2ban-client \- configure and control the server
.SH SYNOPSIS .SH SYNOPSIS
.B fail2ban-client .B fail2ban-client
[\fIOPTIONS\fR]... \fI<COMMAND>\fR [\fIOPTIONS\fR]... \fI<COMMAND>\fR
.SH DESCRIPTION .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. and bans the corresponding IP addresses using firewall rules.
.SH OPTIONS .SH OPTIONS
.TP .TP
@ -38,47 +38,203 @@ display this help message
print the version print the version
.SH COMMAND .SH COMMAND
.TP .TP
start \fBstart\fR
start the server and the jails starts the server and the jails
.TP .TP
reload \fBreload\fR
reload the configuration reloads the configuration
.TP .TP
stop \fBstop\fR
stop all jails and terminate the server stops all jails and terminate the
server
.TP .TP
status \fBstatus\fR
get the current status gets the current status of the
server
.TP .TP
set loglevel <LEVEL> \fBping\fR
set loglevel to <LEVEL> tests if the server is alive
.TP .TP
get loglevel \fBset loglevel <LEVEL>\fR
get loglevel sets logging level to <LEVEL>. 0
is minimal, 4 is debug
.TP .TP
set logtarget <TARGET> \fBget loglevel\fR
set log target to <TARGET> gets the logging level
.TP .TP
get logtarget \fBset logtarget <TARGET>\fR
get log target sets logging target to <TARGET>.
Can be STDOUT, STDERR, SYSLOG or a
file
.TP .TP
add <JAIL> [BACKEND] \fBget logtarget\fR
create <JAIL> using [BACKEND] gets logging target
.TP .TP
set <JAIL> <CMD> \fBadd <JAIL> <BACKEND>\fR
set the <CMD> value for <JAIL> creates <JAIL> using <BACKEND>
.TP .TP
get <JAIL> <CMD> \fBset <JAIL> idle on|off\fR
get the <CMD> value for <JAIL> sets the idle state of <JAIL>
.TP .TP
start <JAIL> \fBset <JAIL> addignoreip <IP>\fR
start <JAIL> adds <IP> to the ignore list of
<JAIL>
.TP .TP
stop <JAIL> \fBset <JAIL> delignoreip <IP>\fR
stop <JAIL>. The jail is removed removes <IP> from the ignore list
of <JAIL>
.TP .TP
status <JAIL> \fBset <JAIL> addlogpath <FILE>\fR
get the current status of <JAIL> 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 .SH FILES
\fI/etc/fail2ban/*\fR \fI/etc/fail2ban/*\fR
.SH AUTHOR .SH AUTHOR

View File

@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. .\" 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 .SH NAME
fail2ban-regex \- test Fail2ban "failregex" option fail2ban-regex \- test Fail2ban "failregex" option
.SH SYNOPSIS .SH SYNOPSIS
.B fail2ban-regex .B fail2ban-regex
\fI<logline> <failregex>\fR \fI<logline> <failregex>\fR
.SH DESCRIPTION .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. and bans the corresponding IP addresses using firewall rules.
.PP .PP
This tools can test and benchmark your regular expressions for the "failregex" 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. .\" 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 .SH NAME
fail2ban-server \- start the server fail2ban-server \- start the server
.SH SYNOPSIS .SH SYNOPSIS
.B fail2ban-server .B fail2ban-server
[\fIOPTIONS\fR] [\fIOPTIONS\fR]
.SH DESCRIPTION .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. and bans the corresponding IP addresses using firewall rules.
.PP .PP
Only use this command for debugging purpose. Start the server with 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 .SH OPTIONS
.TP .TP
\fB\-b\fR \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 help2man --section=1 --no-info --include=fail2ban-client.h2m --output fail2ban-client.1 ../fail2ban-client
echo "[done]" echo "[done]"
echo -n "Patching fail2ban-client " echo -n "Patching fail2ban-client "
# Changes the title.
sed -i -e 's/.SS "Command:"/.SH COMMAND/' fail2ban-client.1 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]" echo "[done]"
# fail2ban-server # fail2ban-server

View File

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

View File

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

View File

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

View File

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

View File

@ -16,11 +16,11 @@
# Author: Cyril Jaquier # Author: Cyril Jaquier
# #
# $Revision: 440 $ # $Revision: 471 $
__author__ = "Cyril Jaquier" __author__ = "Cyril Jaquier"
__version__ = "$Revision: 440 $" __version__ = "$Revision: 471 $"
__date__ = "$Date: 2006-10-31 23:24:34 +0100 (Tue, 31 Oct 2006) $" __date__ = "$Date: 2006-11-19 22:25:51 +0100 (Sun, 19 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
@ -56,7 +56,6 @@ class Filter(JailThread):
self.jail = jail self.jail = jail
## The failures manager. ## The failures manager.
self.failManager = FailManager() self.failManager = FailManager()
self.modified = False
## The log file handler. ## The log file handler.
self.__crtHandler = None self.__crtHandler = None
self.__crtFilename = None self.__crtFilename = None
@ -65,6 +64,9 @@ class Filter(JailThread):
## The regular expression matching the failure. ## The regular expression matching the failure.
self.__failRegex = '' self.__failRegex = ''
self.__failRegexObj = None self.__failRegexObj = None
## The regular expression with expression to ignore.
self.__ignoreRegex = ''
self.__ignoreRegexObj = None
## The amount of time to look back. ## The amount of time to look back.
self.__findTime = 6000 self.__findTime = 6000
## The ignore IP list. ## The ignore IP list.
@ -164,11 +166,18 @@ class Filter(JailThread):
def setFailRegex(self, value): def setFailRegex(self, value):
try: try:
self.__failRegexObj = re.compile(value) if value.lstrip() == '':
self.__failRegex = value self.__failRegex = value
logSys.info("Set failregex = %s" % 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: 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. # Get the regular expression which matches the failure.
@ -178,6 +187,32 @@ class Filter(JailThread):
def getFailRegex(self): def getFailRegex(self):
return self.__failRegex 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. # Set the time needed to find a failure.
# #
@ -187,6 +222,7 @@ class Filter(JailThread):
def setFindTime(self, value): def setFindTime(self, value):
self.__findTime = value self.__findTime = value
self.failManager.setMaxTime(value)
logSys.info("Set findtime = %s" % value) logSys.info("Set findtime = %s" % value)
## ##
@ -214,23 +250,6 @@ class Filter(JailThread):
def getMaxRetry(self): def getMaxRetry(self):
return self.failManager.getMaxRetry() 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. # Main loop.
# #
@ -394,11 +413,20 @@ class Filter(JailThread):
def findFailure(self, line): def findFailure(self, line):
failList = list() failList = list()
# Checks if failregex is defined.
if self.__failRegexObj == None: if self.__failRegexObj == None:
logSys.error("No failregex is set") logSys.error("No failregex is set")
else: return failList
# Checks if ignoreregex is defined.
if not self.__ignoreRegexObj == None:
match = self.__ignoreRegexObj.search(line)
if match:
# The ignoreregex matched. Return.
logSys.debug("Ignoring this line")
return failList
match = self.__failRegexObj.search(line) match = self.__failRegexObj.search(line)
if match: if match:
# The failregex matched.
date = self.dateDetector.getUnixTime(match.string) date = self.dateDetector.getUnixTime(match.string)
if date == None: if date == None:
logSys.debug("Found a match but no valid date/time found " logSys.debug("Found a match but no valid date/time found "
@ -451,6 +479,8 @@ class DNSUtils:
try: try:
return socket.gethostbyname_ex(dns)[2] return socket.gethostbyname_ex(dns)[2]
except socket.gaierror: except socket.gaierror:
logSys.warn("Unable to find a corresponding IP address for %s"
% dns)
return list() return list()
@staticmethod @staticmethod

View File

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

View File

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

View File

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

View File

@ -28,29 +28,63 @@ __license__ = "GPL"
from jail import Jail from jail import Jail
from threading import Lock 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: class Jails:
##
# Constructor.
def __init__(self): def __init__(self):
self.__lock = Lock() self.__lock = Lock()
self.__jails = dict() 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): def add(self, name, backend):
try:
self.__lock.acquire() self.__lock.acquire()
if self.__jails.has_key(name): if self.__jails.has_key(name):
self.__lock.release()
raise DuplicateJailException(name) raise DuplicateJailException(name)
else: else:
self.__jails[name] = Jail(name, backend) self.__jails[name] = Jail(name, backend)
finally:
self.__lock.release() 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): def remove(self, name):
try:
self.__lock.acquire() self.__lock.acquire()
if self.__jails.has_key(name): if self.__jails.has_key(name):
del self.__jails[name] del self.__jails[name]
self.__lock.release()
else: else:
self.__lock.release()
raise UnknownJailException(name) raise UnknownJailException(name)
finally:
self.__lock.release()
##
# 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): def get(self, name):
try: try:
@ -63,6 +97,13 @@ class Jails:
finally: finally:
self.__lock.release() 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): def getAction(self, name):
try: try:
self.__lock.acquire() self.__lock.acquire()
@ -74,6 +115,13 @@ class Jails:
finally: finally:
self.__lock.release() 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): def getFilter(self, name):
try: try:
self.__lock.acquire() self.__lock.acquire()
@ -85,6 +133,11 @@ class Jails:
finally: finally:
self.__lock.release() self.__lock.release()
##
# Returns the jails.
#
# Returns a copy of the jails list.
def getAll(self): def getAll(self):
try: try:
self.__lock.acquire() self.__lock.acquire()
@ -92,6 +145,11 @@ class Jails:
finally: finally:
self.__lock.release() self.__lock.release()
##
# Returns the size of the jails.
#
# Returns the number of jails.
def size(self): def size(self):
try: try:
self.__lock.acquire() self.__lock.acquire()

View File

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

View File

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

View File

@ -18,18 +18,18 @@
# Author: Cyril Jaquier # Author: Cyril Jaquier
# #
# $Revision: 413 $ # $Revision: 473 $
__author__ = "Cyril Jaquier" __author__ = "Cyril Jaquier"
__version__ = "$Revision: 413 $" __version__ = "$Revision: 473 $"
__date__ = "$Date: 2006-10-17 23:13:11 +0200 (Tue, 17 Oct 2006) $" __date__ = "$Date: 2006-11-19 22:35:54 +0100 (Sun, 19 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
from distutils.core import setup from distutils.core import setup
from version import version from common.version import version
from os.path import isfile, join from os.path import isfile, join
from sys import exit, argv from sys import argv
from glob import glob from glob import glob
longdesc = ''' longdesc = '''
@ -54,8 +54,8 @@ setup(
'fail2ban-server', 'fail2ban-server',
'fail2ban-regex' 'fail2ban-regex'
], ],
py_modules = ['version'],
packages = [ packages = [
'common',
'client', 'client',
'server' 'server'
], ],
@ -89,14 +89,20 @@ elements = {
"iptables.py", "iptables.py",
"ipfwadm.py", "ipfwadm.py",
"ipfw.py" "ipfw.py"
],
"/usr/lib/fail2ban/":
[
"version.py",
"protocol.py"
] ]
} }
for dir in elements: for directory in elements:
for f in elements[dir]: for f in elements[directory]:
path = join(dir, f) path = join(directory, f)
if isfile(path): if isfile(path):
obsoleteFiles.append(path) obsoleteFiles.append(path)
if obsoleteFiles: if obsoleteFiles:
print print
print "Obsolete files from previous Fail2Ban versions were found on " \ 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" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
import unittest, time import unittest
from server.datedetector import DateDetector from server.datedetector import DateDetector
from server.datetemplate import DateTemplate from server.datetemplate import DateTemplate
@ -54,3 +54,14 @@ class DateDetectorTest(unittest.TestCase):
self.assertEqual(self.__datedetector.getTime(log), date) self.assertEqual(self.__datedetector.getTime(log), date)
self.assertEqual(self.__datedetector.getUnixTime(log), dateUnix) 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)