Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Upgraded to fresh upstream 0.7.5

  • Loading branch information...
commit 325366066ea005f3ade80ae55647753c89076750 2 parents a82e3dc + f366a0b
@yarikoptic yarikoptic authored
Showing with 1,102 additions and 595 deletions.
  1. +25 −1 CHANGELOG
  2. +1 −1  PKG-INFO
  3. +15 −41 README
  4. +4 −8 TODO
  5. +6 −4 client/configreader.py
  6. +4 −4 client/csocket.py
  7. +7 −4 client/filterreader.py
  8. +12 −6 client/jailreader.py
  9. +25 −0 common/__init__.py
  10. +107 −0 common/protocol.py
  11. +4 −4 { → common}/version.py
  12. +4 −5 config/action.d/hostsdeny.conf
  13. +3 −4 config/action.d/ipfw.conf
  14. +4 −5 config/action.d/iptables.conf
  15. +4 −5 config/action.d/mail-whois.conf
  16. +4 −5 config/action.d/mail.conf
  17. +3 −4 config/action.d/shorewall.conf
  18. +11 −3 config/filter.d/apache-auth.conf
  19. +10 −2 config/filter.d/apache-noscript.conf
  20. +10 −2 config/filter.d/courierlogin.conf
  21. +10 −2 config/filter.d/couriersmtp.conf
  22. +10 −2 config/filter.d/postfix.conf
  23. +10 −2 config/filter.d/proftpd.conf
  24. +10 −2 config/filter.d/qmail.conf
  25. +10 −2 config/filter.d/sasl.conf
  26. +10 −3 config/filter.d/sshd.conf
  27. +11 −3 config/filter.d/vsftpd.conf
  28. +15 −8 config/jail.conf
  29. +26 −31 fail2ban-client
  30. +1 −1  fail2ban-regex
  31. +13 −11 fail2ban-server
  32. +4 −4 fail2ban-testcases
  33. +2 −2 files/redhat-initd
  34. +186 −30 man/fail2ban-client.1
  35. +2 −2 man/fail2ban-regex.1
  36. +4 −3 man/fail2ban-server.1
  37. +23 −0 man/generate-man
  38. +31 −19 server/actions.py
  39. +14 −19 server/banmanager.py
  40. +1 −2  server/datedetector.py
  41. +2 −2 server/datetemplate.py
  42. +73 −43 server/filter.py
  43. +7 −6 server/filtergamin.py
  44. +4 −3 server/filterpoll.py
  45. +18 −58 server/jail.py
  46. +70 −12 server/jails.py
  47. +96 −61 server/server.py
  48. +125 −120 server/transmitter.py
  49. +38 −32 setup.py
  50. +13 −2 testcases/datedetectortestcase.py
View
26 CHANGELOG
@@ -4,9 +4,33 @@
|_| \__,_|_|_/___|_.__/\__,_|_||_|
=============================================================
-Fail2Ban (version 0.7.4) 2006/11/01
+Fail2Ban (version 0.7.5) 2006/12/07
=============================================================
+ver. 0.7.5 (2006/12/07) - beta
+----------
+- Do not ban a host that is currently banned. Thanks to
+ Yaroslav Halchenko
+- The supported tags in "action(un)ban" are <ip>, <failures>
+ and <time>
+- Fixed refactoring bug (getLastcommand -> getLastAction)
+- Added option "ignoreregex" in filter scripts and jail.conf.
+ Feature Request #1283304
+- Fixed a bug in user defined time regex/pattern
+- Improved documentation
+- Moved version.py and protocol.py to common/
+- Merged "maxtime" option with "findtime"
+- Added "<HOST>" tag support in failregex which matches
+ default IP address/hostname. "(?P<host>\S)" is still valid
+ and supported
+- Fixed exception when calling fail2ban-server with unknown
+ option
+- Fixed Debian bug 400162. The "socket" option is now handled
+ correctly by fail2ban-client
+- Fixed RedHat init script. Thanks to Justin Shore
+- Changed timeout to 30 secondes before assuming the server
+ cannot be started. Thanks to Joël Bertrand
+
ver. 0.7.4 (2006/11/01) - beta
----------
- Improved configuration files. Thanks to Yaroslav Halchenko
View
2  PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.0
Name: fail2ban
-Version: 0.7.4
+Version: 0.7.5
Summary: Ban IPs that make too many password failure
Home-page: http://fail2ban.sourceforge.net
Author: Cyril Jaquier
View
56 README
@@ -4,7 +4,7 @@
|_| \__,_|_|_/___|_.__/\__,_|_||_|
=============================================================
-Fail2Ban (version 0.7.4) 2006/11/01
+Fail2Ban (version 0.7.5) 2006/12/07
=============================================================
Fail2Ban scans log files like /var/log/pwdfail and bans IP
@@ -13,7 +13,8 @@ rules to reject the IP address. These rules can be defined by
the user. Fail2Ban can read multiple log files such as sshd
or Apache web server ones.
-Documentation, FAQ, HOWTOs are available on the project
+This README is a quick introduction to Fail2ban. More
+documentation, FAQ, HOWTOs are available on the project
website: http://fail2ban.sourceforge.net
Installation:
@@ -27,8 +28,8 @@ Optional:
To install, just do:
-> tar xvfj fail2ban-0.7.4.tar.bz2
-> cd fail2ban-0.7.4
+> tar xvfj fail2ban-0.7.5.tar.bz2
+> cd fail2ban-0.7.5
> python setup.py install
This will install Fail2Ban into /usr/lib/fail2ban. The
@@ -38,54 +39,27 @@ Gentoo: ebuilds are available on the website.
Debian: Fail2Ban is in Debian unstable.
RedHat: packages are available on the website.
-Fail2Ban should now be correctly installed. Just type:
+Fail2Ban should be correctly installed now. Just type:
> fail2ban-client -h
-to see if everything is alright.
+to see if everything is alright. You should always use
+fail2ban-client and never call fail2ban-server directly.
Configuration:
--------------
-You can configure fail2ban using the files in /etc/fail2ban
-or using command line. Here are the available command line
-options (not complete yet):
-
-Options:
- -c <DIR> configuration directory
- -s <FILE> socket path
- -d dump configuration. For debugging
- -i interactive mode
- -v increase verbosity
- -q decrease verbosity
- -x force execution of the server
- -h, --help display this help message
- -V, --version print the version
-
-Command:
- start start the server and the jails
- reload reload the configuration
- stop stop all jails and terminate the
- server
- status get the current status
-
- set loglevel <LEVEL> set loglevel to <LEVEL>
- get loglevel get loglevel
- set logtarget <TARGET> set log target to <TARGET>
- get logtarget get log target
-
- add <JAIL> [BACKEND] create <JAIL> using [BACKEND]
- set <JAIL> <CMD> set the <CMD> value for <JAIL>
- get <JAIL> <CMD> get the <CMD> value for <JAIL>
- start <JAIL> start <JAIL>
- stop <JAIL> stop <JAIL>. The jail is removed
- status <JAIL> get the current status of <JAIL>
+You can configure Fail2ban using the files in /etc/fail2ban.
+It is possible to configure the server using commands sent to
+it by fail2ban-client. The available commands are described
+in the man page of fail2ban-client. Please refer to it or to
+the website: http://fail2ban.sourceforge.net
Contact:
--------
You need some new features, you found bugs or you just
-appreciate this program, you can contact me at :
+appreciate this program, you can contact me at:
Website: http://fail2ban.sourceforge.net
@@ -98,7 +72,7 @@ Kévin Drapel, Marvin Rouge, Sireyessire, Robert Edeker,
Tom Pike, Iain Lea, Andrey G. Grozin, Yaroslav Halchenko,
Jonathan Kamens, Stephen Gildea, Markus Hoffmann, Mark
Edgington, Patrick Börjesson, kojiro, zugeschmiert, Tyler,
-Nick Munger, Christoph Haas
+Nick Munger, Christoph Haas, Justin Shore, Joël Bertrand
License:
--------
View
12 TODO
@@ -4,7 +4,7 @@
|_| \__,_|_|_/___|_.__/\__,_|_||_|
=============================================================
-ToDo $Revision: 446 $
+ToDo $Revision: 468 $
=============================================================
Legend:
@@ -13,7 +13,9 @@ Legend:
# partially done
* done
-- Add gettext support (I8N)
+- Better handling of the protocol in transmitter.py
+
+- Add gettext support (I18N)
- Fix the cPickle issue with Python 2.5
@@ -26,14 +28,8 @@ Legend:
# see Feature Request Tracking System at SourceForge.net
-- improve installation process (better prefix support)
-
# improve documentation and website for user
# better return values in function
-? restart automatically the daemon if an exception occurs.
-
-- do not close socket after a send
-
# refactoring in server.py, actions.py, filter.py
View
10 client/configreader.py
@@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
-# $Revision: 433 $
+# $Revision: 458 $
__author__ = "Cyril Jaquier"
-__version__ = "$Revision: 433 $"
-__date__ = "$Date: 2006-10-24 21:40:51 +0200 (Tue, 24 Oct 2006) $"
+__version__ = "$Revision: 458 $"
+__date__ = "$Date: 2006-11-12 15:52:36 +0100 (Sun, 12 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@@ -69,6 +69,7 @@ def read(self, filename):
# 0 -> the type of the option
# 1 -> the name of the option
# 2 -> the default value for the option
+
def getOptions(self, sec, options, pOptions = None):
values = dict()
for option in options:
@@ -88,7 +89,8 @@ def getOptions(self, sec, options, pOptions = None):
values[option[1]] = option[2]
except NoOptionError:
if not option[2] == None:
- logSys.warn("No '" + option[1] + "' defined in '" + sec + "'")
+ logSys.warn("'%s' not defined in '%s'. Using default value"
+ % (option[1], sec))
values[option[1]] = option[2]
except ValueError:
logSys.warn("Wrong value for '" + option[1] + "' in '" + sec +
View
8 client/csocket.py
@@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
-# $Revision: 443 $
+# $Revision: 459 $
__author__ = "Cyril Jaquier"
-__version__ = "$Revision: 443 $"
-__date__ = "$Date: 2006-11-01 00:36:59 +0100 (Wed, 01 Nov 2006) $"
+__version__ = "$Revision: 459 $"
+__date__ = "$Date: 2006-11-12 22:55:57 +0100 (Sun, 12 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@@ -41,7 +41,7 @@ def __init__(self, sock = "/tmp/fail2ban.sock"):
def send(self, msg):
# Convert every list member to string
- obj = dumps(map(str, msg), HIGHEST_PROTOCOL)
+ obj = dumps([str(m) for m in msg], HIGHEST_PROTOCOL)
self.__csock.send(obj + CSocket.END_STRING)
ret = self.receive(self.__csock)
self.__csock.close()
View
11 client/filterreader.py
@@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
-# $Revision: 433 $
+# $Revision: 458 $
__author__ = "Cyril Jaquier"
-__version__ = "$Revision: 433 $"
-__date__ = "$Date: 2006-10-24 21:40:51 +0200 (Tue, 24 Oct 2006) $"
+__version__ = "$Revision: 458 $"
+__date__ = "$Date: 2006-11-12 15:52:36 +0100 (Sun, 12 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@@ -55,6 +55,7 @@ def read(self):
def getOptions(self, pOpts):
opts = [["string", "timeregex", None],
["string", "timepattern", None],
+ ["string", "ignoreregex", ""],
["string", "failregex", ""]]
self.__opts = ConfigReader.getOptions(self, "Definition", opts, pOpts)
@@ -66,6 +67,8 @@ def convert(self):
elif opt == "timepattern":
stream.append(["set", self.__name, "timepattern", self.__opts[opt]])
elif opt == "failregex":
- stream.append(["set", self.__name, "failregex", self.__opts[opt]])
+ stream.append(["set", self.__name, "failregex", self.__opts[opt]])
+ elif opt == "ignoreregex":
+ stream.append(["set", self.__name, "ignoreregex", self.__opts[opt]])
return stream
View
18 client/jailreader.py
@@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
-# $Revision: 438 $
+# $Revision: 470 $
__author__ = "Cyril Jaquier"
-__version__ = "$Revision: 438 $"
-__date__ = "$Date: 2006-10-31 00:02:05 +0100 (Tue, 31 Oct 2006) $"
+__version__ = "$Revision: 470 $"
+__date__ = "$Date: 2006-11-18 16:15:58 +0100 (Sat, 18 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@@ -60,8 +60,10 @@ def getOptions(self):
["string", "logpath", "/var/log/messages"],
["string", "backend", "auto"],
["int", "maxretry", 3],
- ["int", "maxtime", 600],
+ ["int", "findtime", 600],
["int", "bantime", 600],
+ ["string", "failregex", None],
+ ["string", "ignoreregex", None],
["string", "ignoreip", None],
["string", "filter", ""],
["string", "action", ""]]
@@ -111,10 +113,14 @@ def convert(self):
elif opt == "ignoreip":
for ip in self.__opts[opt].split():
stream.append(["set", self.__name, "addignoreip", ip])
- elif opt == "maxtime":
- stream.append(["set", self.__name, "maxtime", self.__opts[opt]])
+ elif opt == "findtime":
+ stream.append(["set", self.__name, "findtime", self.__opts[opt]])
elif opt == "bantime":
stream.append(["set", self.__name, "bantime", self.__opts[opt]])
+ elif opt == "failregex":
+ stream.append(["set", self.__name, "failregex", self.__opts[opt]])
+ elif opt == "ignoreregex":
+ stream.append(["set", self.__name, "ignoreregex", self.__opts[opt]])
stream.extend(self.__filter.convert())
for action in self.__actions:
stream.extend(action.convert())
View
25 common/__init__.py
@@ -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"
View
107 common/protocol.py
@@ -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
8 version.py → common/version.py
@@ -16,12 +16,12 @@
# Author: Cyril Jaquier
#
-# $Revision: 446 $
+# $Revision: 480 $
__author__ = "Cyril Jaquier"
-__version__ = "$Revision: 446 $"
-__date__ = "$Date: 2006-11-01 23:13:44 +0100 (Wed, 01 Nov 2006) $"
+__version__ = "$Revision: 480 $"
+__date__ = "$Date: 2006-12-07 22:47:53 +0100 (Thu, 07 Dec 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
-version = "0.7.4"
+version = "0.7.5"
View
9 config/action.d/hostsdeny.conf
@@ -2,7 +2,7 @@
#
# Author: Cyril Jaquier
#
-# $Revision: 394 $
+# $Revision: 455 $
#
[Definition]
@@ -30,8 +30,7 @@ actioncheck =
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
-# <failtime> unix timestamp of the last failure
-# <bantime> unix timestamp of the ban time
+# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = IP=<ip> &&
@@ -41,8 +40,8 @@ actionban = IP=<ip> &&
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
-# <bantime> unix timestamp of the ban time
-# <unbantime> unix timestamp of the unban time
+# <failures> number of failures
+# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = IP=<ip> &&
View
7 config/action.d/ipfw.conf
@@ -34,8 +34,7 @@ actioncheck =
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
-# <failtime> unix timestamp of the last failure
-# <bantime> unix timestamp of the ban time
+# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = ipfw add deny tcp from <ip> to <localhost> <port>
@@ -45,8 +44,8 @@ actionban = ipfw add deny tcp from <ip> to <localhost> <port>
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
-# <bantime> unix timestamp of the ban time
-# <unbantime> unix timestamp of the unban time
+# <failures> number of failures
+# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = ipfw delete `ipfw list | grep -i <ip> | awk '{print $1;}'`
View
9 config/action.d/iptables.conf
@@ -2,7 +2,7 @@
#
# Author: Cyril Jaquier
#
-# $Revision: 394 $
+# $Revision: 455 $
#
[Definition]
@@ -34,8 +34,7 @@ actioncheck = iptables -L INPUT | grep -q fail2ban-<name>
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
-# <failtime> unix timestamp of the last failure
-# <bantime> unix timestamp of the ban time
+# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
@@ -44,8 +43,8 @@ actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
-# <bantime> unix timestamp of the ban time
-# <unbantime> unix timestamp of the unban time
+# <failures> number of failures
+# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
View
9 config/action.d/mail-whois.conf
@@ -36,8 +36,7 @@ actioncheck =
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
-# <failtime> unix timestamp of the last failure
-# <bantime> unix timestamp of the ban time
+# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = echo -en "Hi,\n
@@ -52,8 +51,8 @@ actionban = echo -en "Hi,\n
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
-# <bantime> unix timestamp of the ban time
-# <unbantime> unix timestamp of the unban time
+# <failures> number of failures
+# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban =
@@ -64,7 +63,7 @@ actionunban =
#
name = default
-# Destinataire of the mail
+# Destination/Addressee of the mail
#
dest = root
View
9 config/action.d/mail.conf
@@ -36,8 +36,7 @@ actioncheck =
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
-# <failtime> unix timestamp of the last failure
-# <bantime> unix timestamp of the ban time
+# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = echo -en "Hi,\n
@@ -50,8 +49,8 @@ actionban = echo -en "Hi,\n
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
-# <bantime> unix timestamp of the ban time
-# <unbantime> unix timestamp of the unban time
+# <failures> number of failures
+# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban =
@@ -62,7 +61,7 @@ actionunban =
#
name = default
-# Destinataire of the mail
+# Destination/Addressee of the mail
#
dest = root
View
7 config/action.d/shorewall.conf
@@ -30,8 +30,7 @@ actioncheck =
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
-# <failtime> unix timestamp of the last failure
-# <bantime> unix timestamp of the ban time
+# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = shorewall reject <ip>
@@ -40,8 +39,8 @@ actionban = shorewall reject <ip>
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
-# <bantime> unix timestamp of the ban time
-# <unbantime> unix timestamp of the unban time
+# <failures> number of failures
+# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = shorewall allow <ip>
View
14 config/filter.d/apache-auth.conf
@@ -2,13 +2,21 @@
#
# Author: Cyril Jaquier
#
-# $Revision: 394 $
+# $Revision: 471 $
#
[Definition]
# Option: failregex
-# Notes.: regex to match the password failure messages in the logfile.
+# Notes.: regex to match the password failure messages in the logfile. The
+# host must be matched by a group named "host". The tag "<HOST>" can
+# be used for standard IP/hostname matching.
# Values: TEXT
#
-failregex = [[]client (?P<host>\S*)[]] user .*(?:: authentication failure|not found)
+failregex = [[]client <HOST>[]] user .*(?:: authentication failure|not found)
+
+# Option: ignoreregex
+# Notes.: regex to ignore. If this regex matches, the line is ignored.
+# Values: TEXT
+#
+ignoreregex =
View
12 config/filter.d/apache-noscript.conf
@@ -8,7 +8,15 @@
[Definition]
# Option: failregex
-# Notes.: regex to match the password failure messages in the logfile.
+# Notes.: regex to match the password failure messages in the logfile. The
+# host must be matched by a group named "host". The tag "<HOST>" can
+# be used for standard IP/hostname matching.
# Values: TEXT
#
-failregex = [[]client (?P<host>\S*)[]] File does not exist: .*(\.php|\.asp)
+failregex = [[]client <HOST>[]] File does not exist: .*(\.php|\.asp)
+
+# Option: ignoreregex
+# Notes.: regex to ignore. If this regex matches, the line is ignored.
+# Values: TEXT
+#
+ignoreregex =
View
12 config/filter.d/courierlogin.conf
@@ -9,7 +9,15 @@
[Definition]
# Option: failregex
-# Notes.: regex to match the password failures messages in the logfile.
+# Notes.: regex to match the password failures messages in the logfile. The
+# host must be matched by a group named "host". The tag "<HOST>" can
+# be used for standard IP/hostname matching.
# Values: TEXT
#
-failregex = LOGIN FAILED, ip=\[::ffff:(?P<host>\S*)\]$
+failregex = LOGIN FAILED, ip=\[<HOST>\]$
+
+# Option: ignoreregex
+# Notes.: regex to ignore. If this regex matches, the line is ignored.
+# Values: TEXT
+#
+ignoreregex =
View
12 config/filter.d/couriersmtp.conf
@@ -8,7 +8,15 @@
[Definition]
# Option: failregex
-# Notes.: regex to match the password failures messages in the logfile.
+# Notes.: regex to match the password failures messages in the logfile. The
+# host must be matched by a group named "host". The tag "<HOST>" can
+# be used for standard IP/hostname matching.
# Values: TEXT
#
-failregex = error,relay=(?:::f{4,6}:)?(?P<host>\S*),.*550 User unknown
+failregex = error,relay=<HOST>,.*550 User unknown
+
+# Option: ignoreregex
+# Notes.: regex to ignore. If this regex matches, the line is ignored.
+# Values: TEXT
+#
+ignoreregex =
View
12 config/filter.d/postfix.conf
@@ -8,7 +8,15 @@
[Definition]
# Option: failregex
-# Notes.: regex to match the password failures messages in the logfile.
+# Notes.: regex to match the password failures messages in the logfile. The
+# host must be matched by a group named "host". The tag "<HOST>" can
+# be used for standard IP/hostname matching.
# Values: TEXT
#
-failregex = reject: RCPT from (.*)\[(?P<host>\S*)\]: 554
+failregex = reject: RCPT from (.*)\[<HOST>\]: 554
+
+# Option: ignoreregex
+# Notes.: regex to ignore. If this regex matches, the line is ignored.
+# Values: TEXT
+#
+ignoreregex =
View
12 config/filter.d/proftpd.conf
@@ -8,7 +8,15 @@
[Definition]
# Option: failregex
-# Notes.: regex to match the password failures messages in the logfile.
+# Notes.: regex to match the password failures messages in the logfile. The
+# host must be matched by a group named "host". The tag "<HOST>" can
+# be used for standard IP/hostname matching.
# Values: TEXT
#
-failregex = USER \S+: no such user found from \S* ?\[(?P<host>\S+)\] to \S+\s*$
+failregex = USER \S+: no such user found from \S* ?\[<HOST>\] to \S+\s*$
+
+# Option: ignoreregex
+# Notes.: regex to ignore. If this regex matches, the line is ignored.
+# Values: TEXT
+#
+ignoreregex =
View
12 config/filter.d/qmail.conf
@@ -8,7 +8,15 @@
[Definition]
# Option: failregex
-# Notes.: regex to match the password failures messages in the logfile.
+# Notes.: regex to match the password failures messages in the logfile. The
+# host must be matched by a group named "host". The tag "<HOST>" can
+# be used for standard IP/hostname matching.
# Values: TEXT
#
-failregex = (?:[\d,.]+[\d,.] rblsmtpd: |421 badiprbl: ip )(?P<host>\S*)
+failregex = (?:[\d,.]+[\d,.] rblsmtpd: |421 badiprbl: ip )<HOST>
+
+# Option: ignoreregex
+# Notes.: regex to ignore. If this regex matches, the line is ignored.
+# Values: TEXT
+#
+ignoreregex =
View
12 config/filter.d/sasl.conf
@@ -8,7 +8,15 @@
[Definition]
# Option: failregex
-# Notes.: regex to match the password failures messages in the logfile.
+# Notes.: regex to match the password failures messages in the logfile. The
+# host must be matched by a group named "host". The tag "<HOST>" can
+# be used for standard IP/hostname matching.
# Values: TEXT
#
-failregex = : warning: [-._\w]+\[(?P<host>[.\d]+)\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed$
+failregex = : warning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed$
+
+# Option: ignoreregex
+# Notes.: regex to ignore. If this regex matches, the line is ignored.
+# Values: TEXT
+#
+ignoreregex =
View
13 config/filter.d/sshd.conf
@@ -2,14 +2,21 @@
#
# Author: Cyril Jaquier
#
-# $Revision: 394 $
+# $Revision: 471 $
#
[Definition]
# Option: failregex
-# Notes.: regex to match the password failures messages in the logfile.
+# Notes.: regex to match the password failures messages in the logfile. The
+# host must be matched by a group named "host". The tag "<HOST>" can
+# be used for standard IP/hostname matching.
# Values: TEXT
#
-failregex = (?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) (?:::f{4,6}:)?(?P<host>\S*)
+failregex = (?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) <HOST>
+# Option: ignoreregex
+# Notes.: regex to ignore. If this regex matches, the line is ignored.
+# Values: TEXT
+#
+ignoreregex =
View
14 config/filter.d/vsftpd.conf
@@ -2,13 +2,21 @@
#
# Author: Cyril Jaquier
#
-# $Revision: 394 $
+# $Revision: 471 $
#
[Definition]
# Option: failregex
-# Notes.: regex to match the password failures messages in the logfile.
+# Notes.: regex to match the password failures messages in the logfile. The
+# host must be matched by a group named "host". The tag "<HOST>" can
+# be used for standard IP/hostname matching.
# Values: TEXT
#
-failregex = vsftpd: \(pam_unix\) authentication failure; .* rhost=(?P<host>\S*)
+failregex = vsftpd: \(pam_unix\) authentication failure; .* rhost=<HOST>
+
+# Option: ignoreregex
+# Notes.: regex to ignore. If this regex matches, the line is ignored.
+# Values: TEXT
+#
+ignoreregex =
View
23 config/jail.conf
@@ -2,7 +2,7 @@
#
# Author: Cyril Jaquier
#
-# $Revision: 421 $
+# $Revision: 470 $
#
# The DEFAULT allows a global definition of the options. They can be override
@@ -10,9 +10,14 @@
[DEFAULT]
-# "ignoreip" can be an IP address, a CIDR mask or a DNS host
+# "ignoreip" can be an IP address, a CIDR mask or a DNS host.
ignoreip = 127.0.0.1
+# "bantime" is the number of seconds that a host is banned.
bantime = 600
+# A host is banned if it has generated "maxretry" during the
+# last "findtime" seconds.
+findtime = 600
+# "maxretry" is the number of failures before a host get banned.
maxretry = 3
# "backend" specifies the backend used to get files modification. Available
@@ -66,15 +71,17 @@ action = iptables[name=SSH, port=ssh, protocol=tcp]
logpath = /var/log/sshd.log
maxretry = 5
-# Here we use TCP-Wrappers instead of Netfilter/Iptables.
+# Here we use TCP-Wrappers instead of Netfilter/Iptables. "ignoreregex" is
+# used to avoid banning the user "myuser".
[ssh-tcpwrapper]
-enabled = false
-filter = sshd
-action = hostsdeny
- mail-whois[name=SSH, dest=yourmail@mail.com]
-logpath = /var/log/sshd.log
+enabled = false
+filter = sshd
+action = hostsdeny
+ mail-whois[name=SSH, dest=yourmail@mail.com]
+ignoreregex = for myuser from
+logpath = /var/log/sshd.log
# This jail demonstrates the use of wildcards in "logpath".
# Moreover, it is possible to give other files on a new line.
View
57 fail2ban-client
@@ -17,11 +17,11 @@
# Author: Cyril Jaquier
#
-# $Revision: 444 $
+# $Revision: 477 $
__author__ = "Cyril Jaquier"
-__version__ = "$Revision: 444 $"
-__date__ = "$Date: 2006-11-01 23:03:48 +0100 (Wed, 01 Nov 2006) $"
+__version__ = "$Revision: 477 $"
+__date__ = "$Date: 2006-12-03 23:01:18 +0100 (Sun, 03 Dec 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@@ -33,7 +33,8 @@ import getopt, time, readline, shlex, socket
sys.path.insert(1, "/usr/lib/fail2ban")
# Now we can import our modules
-from version import version
+from common.version import version
+from common.protocol import printFormatted
from client.csocket import CSocket
from client.configurator import Configurator
from client.beautifier import Beautifier
@@ -91,22 +92,10 @@ class Fail2banClient:
print " -V, --version print the version"
print
print "Command:"
- print " start start the server and the jails"
- print " reload reload the configuration"
- print " stop stop all jails and terminate the server"
- print " status get the current status"
- print
- print " set loglevel <LEVEL> set loglevel to <LEVEL>"
- print " get loglevel get loglevel"
- print " set logtarget <TARGET> set log target to <TARGET>"
- print " get logtarget get log target"
- print
- print " add <JAIL> [BACKEND] create <JAIL> using [BACKEND]"
- print " set <JAIL> <CMD> set the <CMD> value for <JAIL>"
- print " get <JAIL> <CMD> get the <CMD> value for <JAIL>"
- print " start <JAIL> start <JAIL>"
- print " stop <JAIL> stop <JAIL>. The jail is removed"
- print " status <JAIL> get the current status of <JAIL>"
+
+ # Prints the protocol
+ printFormatted()
+
print
print "Report bugs to <lostcontrol@users.sourceforge.net>"
@@ -180,7 +169,8 @@ class Fail2banClient:
logSys.error("Server already running")
return False
else:
- self.__startServerAsync(self.__conf["force"])
+ self.__startServerAsync(self.__conf["socket"],
+ self.__conf["force"])
# Read the config while the server is starting
self.__readConfig()
try:
@@ -210,16 +200,20 @@ class Fail2banClient:
#
# Start the Fail2ban server in daemon mode.
- def __startServerAsync(self, force = False):
- args = list()
-
- args.append("fail2ban-server")
- args.append("-b")
- if force:
- args.append("-x")
-
+ def __startServerAsync(self, socket, force = False):
+ # Forks the current process.
pid = os.fork()
if pid == 0:
+ args = list()
+ args.append("fail2ban-server")
+ # Start in background mode.
+ args.append("-b")
+ # Set the socket path.
+ args.append("-s")
+ args.append(socket)
+ # Force the execution if needed.
+ if force:
+ args.append("-x")
try:
# Use the PATH env
os.execvp("fail2ban-server", args)
@@ -236,10 +230,11 @@ class Fail2banClient:
# Wait for the server to start
cnt = 0
while not self.__ping():
- if cnt > 10:
+ # The server has 30 secondes to start.
+ if cnt >= 300:
raise ServerExecutionException("Failed to start server")
time.sleep(0.1)
- cnt = cnt + 1
+ cnt += 1
def start(self, argv):
View
2  fail2ban-regex
@@ -31,7 +31,7 @@ import locale, getopt, sys, time, logging, gc
# fix for bug #343821
sys.path.insert(1, "/usr/lib/fail2ban")
-from version import version
+from common.version import version
from server.filter import Filter
# Gets the instance of the logger.
View
24 fail2ban-server
@@ -17,11 +17,11 @@
# Author: Cyril Jaquier
#
-# $Revision: 406 $
+# $Revision: 472 $
__author__ = "Cyril Jaquier"
-__version__ = "$Revision: 406 $"
-__date__ = "$Date: 2006-10-05 00:17:53 +0200 (Thu, 05 Oct 2006) $"
+__version__ = "$Revision: 472 $"
+__date__ = "$Date: 2006-11-19 22:26:47 +0100 (Sun, 19 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@@ -31,7 +31,7 @@ import getopt, sys
# fix for bug #343821
sys.path.insert(1, "/usr/lib/fail2ban")
-from version import version
+from common.version import version
from server.server import Server
##
@@ -71,15 +71,16 @@ class Fail2banServer:
print "and bans the corresponding IP addresses using firewall rules."
print
print "Only use this command for debugging purpose. Start the server with"
- print "fail2ban-client instead."
+ print "fail2ban-client instead. The default behaviour is to start the server"
+ print "in background."
print
print "Options:"
- print " -b start in background"
- print " -f start in foreground"
- print " -s <FILE> socket path"
- print " -x force execution of the server"
- print " -h, --help display this help message"
- print " -V, --version print the version"
+ print " -b start in background"
+ print " -f start in foreground"
+ print " -s <FILE> socket path"
+ print " -x force execution of the server"
+ print " -h, --help display this help message"
+ print " -V, --version print the version"
print
print "Report bugs to <lostcontrol@users.sourceforge.net>"
@@ -113,6 +114,7 @@ class Fail2banServer:
optList, args = getopt.getopt(self.__argv[1:], cmdOpts, cmdLongOpts)
except getopt.GetoptError:
self.dispUsage()
+ sys.exit(-1)
self.__getCmdLineOptions(optList)
View
8 fail2ban-testcases
@@ -17,11 +17,11 @@
# Author: Cyril Jaquier
#
-# $Revision: 429 $
+# $Revision: 467 $
__author__ = "Cyril Jaquier"
-__version__ = "$Revision: 429 $"
-__date__ = "$Date: 2006-10-23 22:13:21 +0200 (Mon, 23 Oct 2006) $"
+__version__ = "$Revision: 467 $"
+__date__ = "$Date: 2006-11-16 22:07:42 +0100 (Thu, 16 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@@ -32,7 +32,7 @@ import unittest, logging, sys
# fix for bug #343821
sys.path.insert(1, "/usr/lib/fail2ban")
-from version import version
+from common.version import version
from testcases import banmanagertestcase
from testcases import clientreadertestcase
from testcases import failmanagertestcase
View
4 files/redhat-initd
@@ -27,7 +27,7 @@ getpid() {
start() {
echo -n $"Starting fail2ban: "
getpid
- if [ -z "$pid"]; then
+ if [ -z "$pid" ]; then
$FAIL2BAN start > /dev/null
RETVAL=$?
fi
@@ -77,8 +77,8 @@ case "$1" in
fi
;;
restart)
+ stop
start
- stop
;;
*)
echo $"Usage: $0 {start|stop|status|restart}"
View
216 man/fail2ban-client.1
@@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
-.TH FAIL2BAN-CLIENT "1" "November 2006" "fail2ban-client v0.7.4" "User Commands"
+.TH FAIL2BAN-CLIENT "1" "December 2006" "fail2ban-client v0.7.4-SVN" "User Commands"
.SH NAME
fail2ban-client \- configure and control the server
.SH SYNOPSIS
.B fail2ban-client
[\fIOPTIONS\fR]... \fI<COMMAND>\fR
.SH DESCRIPTION
-Fail2Ban v0.7.4 reads log file that contains password failure report
+Fail2Ban v0.7.4\-SVN reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.SH OPTIONS
.TP
@@ -38,47 +38,203 @@ display this help message
print the version
.SH COMMAND
.TP
-start
-start the server and the jails
+\fBstart\fR
+starts the server and the jails
.TP
-reload
-reload the configuration
+\fBreload\fR
+reloads the configuration
.TP
-stop
-stop all jails and terminate the server
+\fBstop\fR
+stops all jails and terminate the
+server
.TP
-status
-get the current status
+\fBstatus\fR
+gets the current status of the
+server
.TP
-set loglevel <LEVEL>
-set loglevel to <LEVEL>
+\fBping\fR
+tests if the server is alive
.TP
-get loglevel
-get loglevel
+\fBset loglevel <LEVEL>\fR
+sets logging level to <LEVEL>. 0
+is minimal, 4 is debug
.TP
-set logtarget <TARGET>
-set log target to <TARGET>
+\fBget loglevel\fR
+gets the logging level
.TP
-get logtarget
-get log target
+\fBset logtarget <TARGET>\fR
+sets logging target to <TARGET>.
+Can be STDOUT, STDERR, SYSLOG or a
+file
.TP
-add <JAIL> [BACKEND]
-create <JAIL> using [BACKEND]
+\fBget logtarget\fR
+gets logging target
.TP
-set <JAIL> <CMD>
-set the <CMD> value for <JAIL>
+\fBadd <JAIL> <BACKEND>\fR
+creates <JAIL> using <BACKEND>
.TP
-get <JAIL> <CMD>
-get the <CMD> value for <JAIL>
+\fBset <JAIL> idle on|off\fR
+sets the idle state of <JAIL>
.TP
-start <JAIL>
-start <JAIL>
+\fBset <JAIL> addignoreip <IP>\fR
+adds <IP> to the ignore list of
+<JAIL>
.TP
-stop <JAIL>
-stop <JAIL>. The jail is removed
+\fBset <JAIL> delignoreip <IP>\fR
+removes <IP> from the ignore list
+of <JAIL>
.TP
-status <JAIL>
-get the current status of <JAIL>
+\fBset <JAIL> addlogpath <FILE>\fR
+adds <FILE> to the monitoring list
+of <JAIL>
+.TP
+\fBset <JAIL> dellogpath <FILE>\fR
+removes <FILE> to the monitoring
+list of <JAIL>
+.TP
+\fBset <JAIL> timeregex <REGEX>\fR
+sets the regular expression
+<REGEX> to match the date format
+for <JAIL>. This will disable the
+autodetection feature.
+.TP
+\fBset <JAIL> timepattern <PATTERN>\fR
+sets the pattern <PATTERN> to
+match the date format for <JAIL>.
+This will disable the
+autodetection feature.
+.TP
+\fBset <JAIL> failregex <REGEX>\fR
+sets the regular expression
+<REGEX> which must match failures
+for <JAIL>
+.TP
+\fBset <JAIL> ignoreregex <REGEX>\fR
+sets the regular expression
+<REGEX> which should match pattern
+to exclude for <JAIL>
+.TP
+\fBset <JAIL> findtime <TIME>\fR
+sets the number of seconds <TIME>
+for which the filter will look
+back for <JAIL>
+.TP
+\fBset <JAIL> bantime <TIME>\fR
+sets the number of seconds <TIME>
+a host will be banned for <JAIL>
+.TP
+\fBset <JAIL> maxretry <RETRY>\fR
+sets the number of failures
+<RETRY> before banning the host
+for <JAIL>
+.TP
+\fBset <JAIL> addaction <ACT>\fR
+adds a new action named <NAME> for
+<JAIL>
+.TP
+\fBset <JAIL> delaction <ACT>\fR
+removes the action <NAME> from
+<JAIL>
+.TP
+\fBset <JAIL> setcinfo <ACT> <KEY> <VALUE>\fR
+sets <VALUE> for <KEY> of the
+action <NAME> for <JAIL>
+.TP
+\fBset <JAIL> delcinfo <ACT> <KEY>\fR
+removes <KEY> for the action
+<NAME> for <JAIL>
+.TP
+\fBset <JAIL> actionstart <ACT> <CMD>\fR
+sets the start command <CMD> of
+the action <ACT> for <JAIL>
+.TP
+\fBset <JAIL> actionstop <ACT> <CMD>\fR
+sets the stop command <CMD> of the
+action <ACT> for <JAIL>
+.TP
+\fBset <JAIL> actioncheck <ACT> <CMD>\fR
+sets the check command <CMD> of
+the action <ACT> for <JAIL>
+.TP
+\fBset <JAIL> actionban <ACT> <CMD>\fR
+sets the ban command <CMD> of the
+action <ACT> for <JAIL>
+.TP
+\fBset <JAIL> actionunban <ACT> <CMD>\fR
+sets the unban command <CMD> of
+the action <ACT> for <JAIL>
+.TP
+\fBget <JAIL> logpath\fR
+gets the list of the monitored
+files for <JAIL>
+.TP
+\fBget <JAIL> ignoreip\fR
+gets the list of ignored IP
+addresses for <JAIL>
+.TP
+\fBget <JAIL> timeregex\fR
+gets the regular expression used
+for the time detection for <JAIL>
+.TP
+\fBget <JAIL> timepattern\fR
+gets the pattern used for the time
+detection for <JAIL>
+.TP
+\fBget <JAIL> failregex\fR
+gets the regular expression which
+matches the failures for <JAIL>
+.TP
+\fBget <JAIL> ignoreregex\fR
+gets the regular expression which
+matches patterns to ignore for
+<JAIL>
+.TP
+\fBget <JAIL> findtime\fR
+gets the time for which the filter
+will look back for failures for
+<JAIL>
+.TP
+\fBget <JAIL> bantime\fR
+gets the time a host is banned for
+<JAIL>
+.TP
+\fBget <JAIL> maxretry\fR
+gets the number of failures
+allowed for <JAIL>
+.TP
+\fBget <JAIL> addaction\fR
+gets the last action which has
+been added for <JAIL>
+.TP
+\fBget <JAIL> actionstart <ACT>\fR
+gets the start command for the
+action <ACT> for <JAIL>
+.TP
+\fBget <JAIL> actionstop <ACT>\fR
+gets the stop command for the
+action <ACT> for <JAIL>
+.TP
+\fBget <JAIL> actioncheck <ACT>\fR
+gets the check command for the
+action <ACT> for <JAIL>
+.TP
+\fBget <JAIL> actionban <ACT>\fR
+gets the ban command for the
+action <ACT> for <JAIL>
+.TP
+\fBget <JAIL> actionunban <ACT>\fR
+gets the unban command for the
+action <ACT> for <JAIL>
+.TP
+\fBstart <JAIL>\fR
+starts the jail <JAIL>
+.TP
+\fBstop <JAIL>\fR
+stops the jail <JAIL>. The jail is
+removed
+.TP
+\fBstatus <JAIL>\fR
+gets the current status of <JAIL>
.SH FILES
\fI/etc/fail2ban/*\fR
.SH AUTHOR
View
4 man/fail2ban-regex.1
@@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
-.TH FAIL2BAN-REGEX "1" "November 2006" "fail2ban-regex v0.7.4" "User Commands"
+.TH FAIL2BAN-REGEX "1" "December 2006" "fail2ban-regex v0.7.4-SVN" "User Commands"
.SH NAME
fail2ban-regex \- test Fail2ban "failregex" option
.SH SYNOPSIS
.B fail2ban-regex
\fI<logline> <failregex>\fR
.SH DESCRIPTION
-Fail2Ban v0.7.4 reads log file that contains password failure report
+Fail2Ban v0.7.4\-SVN reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.PP
This tools can test and benchmark your regular expressions for the "failregex"
View
7 man/fail2ban-server.1
@@ -1,16 +1,17 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
-.TH FAIL2BAN-SERVER "1" "November 2006" "fail2ban-server v0.7.4" "User Commands"
+.TH FAIL2BAN-SERVER "1" "December 2006" "fail2ban-server v0.7.4-SVN" "User Commands"
.SH NAME
fail2ban-server \- start the server
.SH SYNOPSIS
.B fail2ban-server
[\fIOPTIONS\fR]
.SH DESCRIPTION
-Fail2Ban v0.7.4 reads log file that contains password failure report
+Fail2Ban v0.7.4\-SVN reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.PP
Only use this command for debugging purpose. Start the server with
-fail2ban\-client instead.
+fail2ban\-client instead. The default behaviour is to start the server
+in background.
.SH OPTIONS
.TP
\fB\-b\fR
View
23 man/generate-man
@@ -5,7 +5,30 @@ echo -n "Generating fail2ban-client "
help2man --section=1 --no-info --include=fail2ban-client.h2m --output fail2ban-client.1 ../fail2ban-client
echo "[done]"
echo -n "Patching fail2ban-client "
+# Changes the title.
sed -i -e 's/.SS "Command:"/.SH COMMAND/' fail2ban-client.1
+# Sets bold font for commands.
+IFS="
+"
+NEXT=0
+FOUND=0
+LINES=$( cat fail2ban-client.1 )
+echo -n "" > fail2ban-client.1
+for LINE in $LINES; do
+ if [ "$LINE" = ".SH COMMAND" ]; then
+ FOUND=1
+ fi
+ if [ $NEXT -eq 1 ] && [ $FOUND -eq 1 ]; then
+ echo "\fB$LINE\fR" >> fail2ban-client.1
+ else
+ echo "$LINE" >> fail2ban-client.1
+ fi
+ if [ "$LINE" = ".TP" ]; then
+ NEXT=1
+ else
+ NEXT=0
+ fi
+done
echo "[done]"
# fail2ban-server
View
50 server/actions.py
@@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
-# $Revision: 433 $
+# $Revision: 455 $
__author__ = "Cyril Jaquier"
-__version__ = "$Revision: 433 $"
-__date__ = "$Date: 2006-10-24 21:40:51 +0200 (Tue, 24 Oct 2006) $"
+__version__ = "$Revision: 455 $"
+__date__ = "$Date: 2006-11-12 11:56:21 +0100 (Sun, 12 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@@ -134,11 +134,15 @@ def __checkBan(self):
bTicket = BanManager.createBanTicket(ticket)
aInfo["ip"] = bTicket.getIP()
aInfo["failures"] = bTicket.getAttempt()
- logSys.warn("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"]))
- for action in self.__actions:
- action.execActionBan(aInfo)
- self.__banManager.addBanTicket(bTicket)
- return True
+ aInfo["time"] = bTicket.getTime()
+ if self.__banManager.addBanTicket(bTicket):
+ logSys.warn("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"]))
+ for action in self.__actions:
+ action.execActionBan(aInfo)
+ return True
+ else:
+ logSys.warn("[%s] %s already banned" % (self.jail.getName(),
+ aInfo["ip"]))
return False
##
@@ -148,11 +152,7 @@ def __checkBan(self):
def __checkUnBan(self):
for ticket in self.__banManager.unBanList(MyTime.time()):
- aInfo = dict()
- aInfo["ip"] = ticket.getIP()
- logSys.warn("[%s] Unban %s" % (self.jail.getName(), aInfo["ip"]))
- for action in self.__actions:
- action.execActionUnban(aInfo)
+ self.__unBan(ticket)
##
# Flush the ban list.
@@ -162,11 +162,23 @@ def __checkUnBan(self):
def __flushBan(self):
logSys.debug("Flush ban list")
for ticket in self.__banManager.flushBanList():
- aInfo = dict()
- aInfo["ip"] = ticket.getIP()
- logSys.warn("[%s] Unban %s" % (self.jail.getName(), aInfo["ip"]))
- for action in self.__actions:
- action.execActionUnban(aInfo)
+ self.__unBan(ticket)
+
+ ##
+ # Unbans host corresponding to the ticket.
+ #
+ # Executes the actions in order to unban the host given in the
+ # ticket.
+
+ def __unBan(self, ticket):
+ aInfo = dict()
+ aInfo["ip"] = ticket.getIP()
+ aInfo["failures"] = ticket.getAttempt()
+ aInfo["time"] = ticket.getTime()
+ logSys.warn("[%s] Unban %s" % (self.jail.getName(), aInfo["ip"]))
+ for action in self.__actions:
+ action.execActionUnban(aInfo)
+
##
# Get the status of the filter.
@@ -176,7 +188,7 @@ def __flushBan(self):
# @return a list with tuple
def status(self):
- ret = [("Currently banned", self.__banManager.size()),
+ ret = [("Currently banned", self.__banManager.size()),
("Total banned", self.__banManager.getBanTotal())]
return ret
View
33 server/banmanager.py
@@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
-# $Revision: 433 $
+# $Revision: 454 $
__author__ = "Cyril Jaquier"
-__version__ = "$Revision: 433 $"
-__date__ = "$Date: 2006-10-24 21:40:51 +0200 (Tue, 24 Oct 2006) $"
+__version__ = "$Revision: 454 $"
+__date__ = "$Date: 2006-11-12 11:54:19 +0100 (Sun, 12 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@@ -136,14 +136,6 @@ def addBanTicket(self, ticket):
finally:
self.__lock.release()
- ##
- # Delete a ban ticket.
- #
- # Remove a BanTicket from the ban list.
- # @param ticket the ticket
-
- def __delBanTicket(self, ticket):
- self.__banList.remove(ticket)
##
# Get the size of the ban list.
@@ -177,20 +169,23 @@ def __inBanList(self, ticket):
# Return a list of BanTicket which need to be unbanned.
# @param time the time
# @return the list of ticket to unban
- # @todo Check the delete operation
def unBanList(self, time):
try:
self.__lock.acquire()
- uBList = list()
# Permanent banning
if self.__banTime < 0:
- return uBList
- for ticket in self.__banList:
- if ticket.getTime() < time - self.__banTime:
- uBList.append(ticket)
- self.__delBanTicket(ticket)
- return uBList
+ return list()
+
+ # Gets the list of ticket to remove.
+ unBanList = [ticket for ticket in self.__banList
+ if ticket.getTime() < time - self.__banTime]
+
+ # Removes tickets.
+ self.__banList = [ticket for ticket in self.__banList
+ if ticket not in unBanList]
+
+ return unBanList
finally:
self.__lock.release()
View
3  server/datedetector.py
@@ -26,7 +26,6 @@
import time, logging
-from datetemplate import DateTemplate
from datestrptime import DateStrptime
from datetai64n import DateTai64n
from dateepoch import DateEpoch
@@ -40,7 +39,7 @@ class DateDetector:
def __init__(self):
self.__lock = Lock()
self.__templates = list()
- self.__defTemplate = DateTemplate()
+ self.__defTemplate = DateStrptime()
def addDefaultTemplate(self):
# standard
View
4 server/datetemplate.py
@@ -42,14 +42,14 @@ def getName(self):
return self.__name
def setRegex(self, regex):
- self.__regex = regex
+ self.__regex = regex.strip()
self.__cRegex = re.compile(regex)
def getRegex(self):
return self.__regex
def setPattern(self, pattern):
- self.__pattern = pattern
+ self.__pattern = pattern.strip()
def getPattern(self):
return self.__pattern
View
116 server/filter.py
@@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
-# $Revision: 440 $
+# $Revision: 471 $
__author__ = "Cyril Jaquier"
-__version__ = "$Revision: 440 $"
-__date__ = "$Date: 2006-10-31 23:24:34 +0100 (Tue, 31 Oct 2006) $"
+__version__ = "$Revision: 471 $"
+__date__ = "$Date: 2006-11-19 22:25:51 +0100 (Sun, 19 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@@ -56,7 +56,6 @@ def __init__(self, jail):
self.jail = jail
## The failures manager.
self.failManager = FailManager()
- self.modified = False
## The log file handler.
self.__crtHandler = None
self.__crtFilename = None
@@ -65,6 +64,9 @@ def __init__(self, jail):
## The regular expression matching the failure.
self.__failRegex = ''
self.__failRegexObj = None
+ ## The regular expression with expression to ignore.
+ self.__ignoreRegex = ''
+ self.__ignoreRegexObj = None
## The amount of time to look back.
self.__findTime = 6000
## The ignore IP list.
@@ -164,11 +166,18 @@ def getTimePattern(self):
def setFailRegex(self, value):
try:
- self.__failRegexObj = re.compile(value)
- self.__failRegex = value
- logSys.info("Set failregex = %s" % value)
+ if value.lstrip() == '':
+ self.__failRegex = value
+ self.__failRegexObj = None
+ else:
+ # Replace "<HOST>" with default regular expression for host.
+ regex = value.replace("<HOST>", "(?:::f{4,6}:)?(?P<host>\S+)")
+ self.__failRegex = regex
+ self.__failRegexObj = re.compile(regex)
+ logSys.info("Set failregex = %s" % self.__failRegex)
except sre_constants.error:
- logSys.error("Unable to compile regular expression " + value)
+ logSys.error("Unable to compile regular expression " +
+ self.__failRegex)
##
# Get the regular expression which matches the failure.
@@ -179,6 +188,32 @@ def getFailRegex(self):
return self.__failRegex
##
+ # Set the regular expression which matches the failure.
+ #
+ # The regular expression can also match any other pattern than failures
+ # and thus can be used for many purporse.
+ # @param value the regular expression
+
+ def setIgnoreRegex(self, value):
+ try:
+ if value.lstrip() == '':
+ self.__ignoreRegexObj = None
+ else:
+ self.__ignoreRegexObj = re.compile(value)
+ self.__ignoreRegex = value
+ logSys.info("Set ignoreregex = %s" % value)
+ except sre_constants.error:
+ logSys.error("Unable to compile regular expression " + value)
+
+ ##
+ # Get the regular expression which matches the failure.
+ #
+ # @return the regular expression
+
+ def getIgnoreRegex(self):
+ return self.__ignoreRegex
+
+ ##
# Set the time needed to find a failure.
#
# This value tells the filter how long it has to take failures into
@@ -187,6 +222,7 @@ def getFailRegex(self):
def setFindTime(self, value):
self.__findTime = value
+ self.failManager.setMaxTime(value)
logSys.info("Set findtime = %s" % value)
##
@@ -215,23 +251,6 @@ def getMaxRetry(self):
return self.failManager.getMaxRetry()
##
- # Set the maximum time a failure stays in the list.
- #
- # @param value the maximum time
-
- def setMaxTime(self, value):
- self.failManager.setMaxTime(value)
- logSys.info("Set maxTime = %s" % value)
-
- ##
- # Get the maximum time a failure stays in the list.
- #
- # @return the time value
-
- def getMaxTime(self):
- return self.failManager.getMaxTime()
-
- ##
# Main loop.
#
# This function is the main loop of the thread. It checks if the
@@ -394,26 +413,35 @@ def getFailures(self, filename):
def findFailure(self, line):
failList = list()
+ # Checks if failregex is defined.
if self.__failRegexObj == None:
logSys.error("No failregex is set")
- else:
- match = self.__failRegexObj.search(line)
+ return failList
+ # Checks if ignoreregex is defined.
+ if not self.__ignoreRegexObj == None:
+ match = self.__ignoreRegexObj.search(line)
if match:
- date = self.dateDetector.getUnixTime(match.string)
- if date == None:
- logSys.debug("Found a match but no valid date/time found "
- + "for " + match.string + ". Please contact "
- + "the author in order to get support for "
- + "this format")
- else:
- try:
- ipMatch = DNSUtils.textToIp(match.group("host"))
- if ipMatch:
- for ip in ipMatch:
- failList.append([ip, date])
- except IndexError:
- logSys.error("There is no 'host' group in the rule. " +
- "Please correct your configuration.")
+ # The ignoreregex matched. Return.
+ logSys.debug("Ignoring this line")
+ return failList
+ match = self.__failRegexObj.search(line)
+ if match:
+ # The failregex matched.
+ date = self.dateDetector.getUnixTime(match.string)
+ if date == None:
+ logSys.debug("Found a match but no valid date/time found "
+ + "for " + match.string + ". Please contact "
+ + "the author in order to get support for "
+ + "this format")
+ else:
+ try:
+ ipMatch = DNSUtils.textToIp(match.group("host"))
+ if ipMatch:
+ for ip in ipMatch:
+ failList.append([ip, date])
+ except IndexError:
+ logSys.error("There is no 'host' group in the rule. " +
+ "Please correct your configuration.")
return failList
@@ -425,7 +453,7 @@ def findFailure(self, line):
# @return a list with tuple
def status(self):
- ret = [("Currently failed", self.failManager.size()),
+ ret = [("Currently failed", self.failManager.size()),
("Total failed", self.failManager.getFailTotal())]
return ret
@@ -451,6 +479,8 @@ def dnsToIp(dns):
try:
return socket.gethostbyname_ex(dns)[2]
except socket.gaierror:
+ logSys.warn("Unable to find a corresponding IP address for %s"
+ % dns)
return list()
@staticmethod
View
13 server/filtergamin.py
@@ -16,11 +16,11 @@
# Author: Cyril Jaquier
#
-# $Revision: 418 $
+# $Revision: 451 $
__author__ = "Cyril Jaquier"
-__version__ = "$Revision: 418 $"
-__date__ = "$Date: 2006-10-19 00:30:57 +0200 (Thu, 19 Oct 2006) $"
+__version__ = "$Revision: 451 $"
+__date__ = "$Date: 2006-11-06 23:47:24 +0100 (Mon, 06 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
@@ -50,6 +50,7 @@ class FilterGamin(Filter):
def __init__(self, jail):
Filter.__init__(self, jail)
+ self.__modified = False
# Gamin monitor
self.monitor = gamin.WatchMonitor()
logSys.info("Created FilterGamin")
@@ -60,7 +61,7 @@ def callback(self, path, event):
if event in (gamin.GAMCreated, gamin.GAMChanged, gamin.GAMExists):
logSys.debug("File changed: " + path)
self.getFailures(path)
- self.modified = True
+ self.__modified = True
##
@@ -105,14 +106,14 @@ def run(self):
if self.monitor.event_pending():
self.monitor.handle_events()
- if self.modified:
+ if self.__modified:
try:
ticket = self.failManager.toBan()
self.jail.putFailTicket(ticket)
except FailManagerEmpty:
self.failManager.cleanup(MyTime.time())
self.dateDetector.sortTemplate()
- self.modified = False
+ self.__modified = False
time.sleep(self.getSleepTime())
else:
time.sleep(self.getSleepTime())
View
7 server/filterpoll.py
@@ -50,6 +50,7 @@ class FilterPoll(Filter):
def __init__(self, jail):
Filter.__init__(self, jail)
+ self.__modified = False
## The time of the last modification of the file.
self.__lastModTime = dict()
self.__file404Cnt = dict()
@@ -98,16 +99,16 @@ def run(self):
for f in self.getLogPath():
if self.isModified(f):
self.getFailures(f)
- self.modified = True
+ self.__modified = True
- if self.modified:
+ if self.__modified:
try:
ticket = self.failManager.toBan()
self.jail.putFailTicket(ticket)
except FailManagerEmpty:
self.failManager.cleanup(MyTime.time())
self.dateDetector.sortTemplate()
- self.modified = False
+ self.__modified = False
time.sleep(self.getSleepTime())
else:
time.sleep(self.getSleepTime())
View
76 server/jail.py
@@ -16,18 +16,17 @@
# Author: Cyril Jaquier
#
-# $Revision: 433 $
+# $Revision: 452 $
__author__ = "Cyril Jaquier"
-__version__ = "$Revision: 433 $"
-__date__ = "$Date: 2006-10-24 21:40:51 +0200 (Tue, 24 Oct 2006) $"
+__version__ = "$Revision: 452 $"
+__date__ = "$Date: 2006-11-06 23:48:46 +0100 (Mon, 06 Nov 2006) $"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
import Queue, logging
from actions import Actions
-from threading import Lock
# Gets the instance of the logger.
logSys = logging.getLogger("fail2ban.jail")
@@ -35,7 +34,6 @@
class Jail:
def __init__(self, name, backend = "auto"):
- self.__lock = Lock()
self.__name = name
self.__queue = Queue.Queue()
self.__filter = None
@@ -61,89 +59,51 @@ def __initGamin(self):
self.__filter = FilterGamin(self)
def setName(self, name):
- self.__lock.acquire()
self.__name = name
- self.__lock.release()
def getName(self):
- try:
- self.__lock.acquire()
- return self.__name
- finally:
- self.__lock.release()
+ return self.__name
def getFilter(self):
- try:
- self.__lock.acquire()
- return self.__filter
- finally:
- self.__lock.release()
+ return self.__filter
def getAction(self):
- try:
- self.__lock.acquire()
- return self.__action
- finally:
- self.__lock.release()
+ return self.__action
def putFailTicket(self, ticket):
- self.__lock.acquire()
self.__queue.put(ticket)
- self.__lock.release()
def getFailTicket(self):
try:
- self.__lock.acquire()
- try:
- return self.__queue.get(False)
- except Queue.Empty:
- return False
- finally:
- self.__lock.release()
+ return self.__queue.get(False)
+ except Queue.Empty:
+ return False
def start(self):
- self.__lock.acquire()
self.__filter.start()
self.__action.start()
- self.__lock.release()
def stop(self):
- self.__lock.acquire()
self.__filter.stop()
self.__action.stop()
- self.__lock.release()
self.__filter.join()
self.__action.join()
def isActive(self):
- try:
- self.__lock.acquire()
- isActive0 = self.__filter.isActive()
- isActive1 = self.__action.isActive()
- return isActive0 or isActive1
- finally:
- self.__lock.release()
+ isActive0 = self.__filter.isActive()
+ isActive1 = self.__action.isActive()
+ return isActive0 or isActive1
def setIdle(self, value):
- self.__lock.acquire()
self.__filter.setIdle(value)
self.__action.setIdle(value)
- self.__lock.release()
def getIdle(self):
- try:
- self.__lock.acquire()
- return self.__filter.getIdle() or self.__action.getIdle()
- finally: