From 61fe328a356e34c6e718d97b06496ba9a180bd9a Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Thu, 6 Mar 2008 00:18:55 +0000 Subject: [PATCH 01/23] - Prepared for future 0.8.3 git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@675 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 6 +++++- README | 6 +++--- common/version.py | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2702b195..652d297d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,9 +4,13 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ============================================================= -Fail2Ban (version 0.8.2) 2008/03/06 +Fail2Ban (version 0.8.3) 2008/??/?? ============================================================= +ver. 0.8.3 (2008/??/??) - stable +---------- + + ver. 0.8.2 (2008/03/06) - stable ---------- - Fixed named filter. Thanks to Yaroslav Halchenko diff --git a/README b/README index d9e1e3f0..7d2a4281 100644 --- a/README +++ b/README @@ -4,7 +4,7 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ============================================================= -Fail2Ban (version 0.8.2) 2008/03/06 +Fail2Ban (version 0.8.3) 2008/??/?? ============================================================= Fail2Ban scans log files like /var/log/pwdfail and bans IP @@ -28,8 +28,8 @@ Optional: To install, just do: -> tar xvfj fail2ban-0.8.2.tar.bz2 -> cd fail2ban-0.8.2 +> tar xvfj fail2ban-0.8.3.tar.bz2 +> cd fail2ban-0.8.3 > python setup.py install This will install Fail2Ban into /usr/share/fail2ban. The diff --git a/common/version.py b/common/version.py index 55ced039..79c66b15 100644 --- a/common/version.py +++ b/common/version.py @@ -24,4 +24,4 @@ __date__ = "$Date$" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" -version = "0.8.2" +version = "0.8.2-SVN" From d645a8fe473a91373498229a67243248679b7a80 Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Thu, 6 Mar 2008 00:21:52 +0000 Subject: [PATCH 02/23] - Process failtickets as long as failmanager is not empty. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@676 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 2 +- server/filtergamin.py | 5 +++-- server/filterpoll.py | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 652d297d..f59b8d79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,7 +9,7 @@ Fail2Ban (version 0.8.3) 2008/??/?? ver. 0.8.3 (2008/??/??) - stable ---------- - +- Process failtickets as long as failmanager is not empty. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/server/filtergamin.py b/server/filtergamin.py index a7a74e5d..5d124c7b 100644 --- a/server/filtergamin.py +++ b/server/filtergamin.py @@ -108,8 +108,9 @@ class FilterGamin(FileFilter): if self.__modified: try: - ticket = self.failManager.toBan() - self.jail.putFailTicket(ticket) + while True: + ticket = self.failManager.toBan() + self.jail.putFailTicket(ticket) except FailManagerEmpty: self.failManager.cleanup(MyTime.time()) self.dateDetector.sortTemplate() diff --git a/server/filterpoll.py b/server/filterpoll.py index 3f17fcc8..47d12a47 100644 --- a/server/filterpoll.py +++ b/server/filterpoll.py @@ -103,8 +103,9 @@ class FilterPoll(FileFilter): if self.__modified: try: - ticket = self.failManager.toBan() - self.jail.putFailTicket(ticket) + while True: + ticket = self.failManager.toBan() + self.jail.putFailTicket(ticket) except FailManagerEmpty: self.failManager.cleanup(MyTime.time()) self.dateDetector.sortTemplate() From d9f9a318027b54c383437c6691519180ac410c45 Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Mon, 10 Mar 2008 22:03:34 +0000 Subject: [PATCH 03/23] - Added "pam-generic" filter and more configuration fixes. Thanks to Yaroslav Halchenko. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@677 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 2 ++ MANIFEST | 1 + config/filter.d/pam-generic.conf | 25 +++++++++++++++++++++++++ config/filter.d/proftpd.conf | 2 +- 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 config/filter.d/pam-generic.conf diff --git a/ChangeLog b/ChangeLog index f59b8d79..a6eb4369 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,8 @@ Fail2Ban (version 0.8.3) 2008/??/?? ver. 0.8.3 (2008/??/??) - stable ---------- - Process failtickets as long as failmanager is not empty. +- Added "pam-generic" filter and more configuration fixes. + Thanks to Yaroslav Halchenko. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/MANIFEST b/MANIFEST index 264d37c1..cff2f3df 100644 --- a/MANIFEST +++ b/MANIFEST @@ -68,6 +68,7 @@ config/filter.d/postfix.conf config/filter.d/proftpd.conf config/filter.d/pure-ftpd.conf config/filter.d/qmail.conf +config/filter.d/pam-generic.conf config/filter.d/sasl.conf config/filter.d/sshd.conf config/filter.d/sshd-ddos.conf diff --git a/config/filter.d/pam-generic.conf b/config/filter.d/pam-generic.conf new file mode 100644 index 00000000..55e9efd0 --- /dev/null +++ b/config/filter.d/pam-generic.conf @@ -0,0 +1,25 @@ +# Fail2Ban configuration file for generic PAM authentication errors +# +# Author: Yaroslav Halchenko +# +# $Revision: $ +# + +[Definition] + +# if you want to catch only login erros from specific daemons, use smth like +#_ttys_re=(?:ssh|pure-ftpd|ftp) +# To catch all failed logins +_ttys_re=\S* + +# +# Shortcuts for easier comprehension of the failregex +__pid_re=(?:\[\d+\]) +__pam_re=\(?pam_unix(?:\(\S+\))?\)?:? +__pam_combs_re=(?:%(__pid_re)s?:\s+%(__pam_re)s|%(__pam_re)s%(__pid_re)s?:) + +# Option: failregex +# Notes.: regex to match the password failures messages in the logfile. +# Values: TEXT +# +failregex = \s\S+ \S+%(__pam_combs_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=%(_ttys_re)s ruser=\S* rhost=(?:\s+user=.*)?\s*$ diff --git a/config/filter.d/proftpd.conf b/config/filter.d/proftpd.conf index 4d71bf2a..852fb59c 100644 --- a/config/filter.d/proftpd.conf +++ b/config/filter.d/proftpd.conf @@ -14,7 +14,7 @@ # (?:::f{4,6}:)?(?P\S+) # Values: TEXT # -failregex = \(\S+\[\]\)[: -]+ USER \S+: no such user found from \S+ \[[0-9.]+\] to \S+:\S+$ +failregex = \(\S+\[\]\)[: -]+ USER \S+: no such user found from \S+ \[\S+\] to \S+:\S+$ \(\S+\[\]\)[: -]+ USER \S+ \(Login failed\): Incorrect password\.$ \(\S+\[\]\)[: -]+ SECURITY VIOLATION: \S+ login attempted\.$ \(\S+\[\]\)[: -]+ Maximum login attempts \(\d+\) exceeded$ From c1bc33b3ccdf32cb9bfd14d7a94c79c159f274fd Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Mon, 10 Mar 2008 22:34:46 +0000 Subject: [PATCH 04/23] - Create /var/run/fail2ban during install. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@678 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- setup.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.py b/setup.py index 2c852add..1e43771f 100755 --- a/setup.py +++ b/setup.py @@ -68,6 +68,9 @@ setup( ), ('/etc/fail2ban/action.d', glob("config/action.d/*.conf") + ), + ('/var/run/fail2ban', + '' ) ] ) From 19d251d78560ff41853fe853dd738dd62487c13b Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Mon, 10 Mar 2008 22:39:40 +0000 Subject: [PATCH 05/23] - Fixed socket path in redhat and suse init script. Thanks to Jim Wight. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@679 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 2 ++ files/redhat-initd | 2 +- files/suse-initd | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a6eb4369..4983803c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,8 @@ ver. 0.8.3 (2008/??/??) - stable - Process failtickets as long as failmanager is not empty. - Added "pam-generic" filter and more configuration fixes. Thanks to Yaroslav Halchenko. +- Fixed socket path in redhat and suse init script. Thanks to + Jim Wight. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/files/redhat-initd b/files/redhat-initd index 529aef25..75c7f808 100755 --- a/files/redhat-initd +++ b/files/redhat-initd @@ -27,7 +27,7 @@ start() { echo -n $"Starting fail2ban: " getpid if [ -z "$pid" ]; then - rm -rf /tmp/fail2ban.sock # in case of unclean shutdown + rm -rf /var/run/fail2ban/fail2ban.sock # in case of unclean shutdown $FAIL2BAN start > /dev/null RETVAL=$? fi diff --git a/files/suse-initd b/files/suse-initd index bbd679aa..ecd55d9a 100755 --- a/files/suse-initd +++ b/files/suse-initd @@ -16,7 +16,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/usr/sbin:/usr/bin:/bin FAIL2BAN_BIN=/usr/local/bin/fail2ban-client FAIL2BAN_SERVER=/usr/local/bin/fail2ban-server -FAIL2BAN_SOCKET=/tmp/fail2ban.sock +FAIL2BAN_SOCKET=/var/run/fail2ban/fail2ban.sock test -x $FAIL2BAN_BIN || { echo "$FAIL2BAN_BIN not installed"; if [ "$1" = "stop" ]; then exit 0; else exit 5; fi; } From b174a2e8585678b8bb1d4dd7a0a678fce1f93fcf Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Thu, 13 Mar 2008 21:40:16 +0000 Subject: [PATCH 06/23] - Fixed PID file while started in daemon mode. Thanks to Christian Jobic who submitted a similar patch. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@680 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 2 ++ server/server.py | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4983803c..06173d06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,8 @@ ver. 0.8.3 (2008/??/??) - stable Thanks to Yaroslav Halchenko. - Fixed socket path in redhat and suse init script. Thanks to Jim Wight. +- Fixed PID file while started in daemon mode. Thanks to + Christian Jobic who submitted a similar patch. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/server/server.py b/server/server.py index f363ca6e..7a6640f3 100644 --- a/server/server.py +++ b/server/server.py @@ -59,15 +59,6 @@ class Server: def start(self, sock, force = False): logSys.info("Starting Fail2ban v" + version.version) - # Creates a PID file. - try: - logSys.debug("Creating PID file %s" % Server.PID_FILE) - pidFile = open(Server.PID_FILE, 'w') - pidFile.write("%s\n" % os.getpid()) - pidFile.close() - except IOError, e: - logSys.error("Unable to create PID file: %s" % e) - # Install signal handlers signal.signal(signal.SIGTERM, self.__sigTERMhandler) signal.signal(signal.SIGINT, self.__sigTERMhandler) @@ -81,6 +72,16 @@ class Server: else: logSys.error("Could not create daemon") raise ServerInitializationError("Could not create daemon") + + # Creates a PID file. + try: + logSys.debug("Creating PID file %s" % Server.PID_FILE) + pidFile = open(Server.PID_FILE, 'w') + pidFile.write("%s\n" % os.getpid()) + pidFile.close() + except IOError, e: + logSys.error("Unable to create PID file: %s" % e) + # Start the communication logSys.debug("Starting communication") try: From b757c08f4073a31a5fb7114df121ee636dc8f0ff Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Mon, 17 Mar 2008 23:18:07 +0000 Subject: [PATCH 07/23] - Fixed "fail2ban-client get logpath". Bug #1916986. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@681 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 1 + server/server.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 06173d06..d1e280a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,6 +16,7 @@ ver. 0.8.3 (2008/??/??) - stable Jim Wight. - Fixed PID file while started in daemon mode. Thanks to Christian Jobic who submitted a similar patch. +- Fixed "fail2ban-client get logpath". Bug #1916986. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/server/server.py b/server/server.py index 7a6640f3..ecfe45c4 100644 --- a/server/server.py +++ b/server/server.py @@ -165,7 +165,8 @@ class Server: self.__jails.getFilter(name).delLogPath(fileName) def getLogPath(self, name): - return self.__jails.getFilter(name).getLogPath() + return [m.getFileName() + for m in self.__jails.getFilter(name).getLogPath()] def setFindTime(self, name, value): self.__jails.getFilter(name).setFindTime(value) From 56357d18df96a97a4c525ca109171b7c9116aa8c Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Mon, 7 Apr 2008 22:25:16 +0000 Subject: [PATCH 08/23] - Changed some log level. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@682 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 1 + server/action.py | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index d1e280a1..157fd0d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,7 @@ ver. 0.8.3 (2008/??/??) - stable - Fixed PID file while started in daemon mode. Thanks to Christian Jobic who submitted a similar patch. - Fixed "fail2ban-client get logpath". Bug #1916986. +- Changed some log levels. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/server/action.py b/server/action.py index d2c3ca5c..f55d9a6d 100644 --- a/server/action.py +++ b/server/action.py @@ -106,7 +106,7 @@ class Action: def setActionStart(self, value): self.__actionStart = value - logSys.info("Set actionStart = %s" % value) + logSys.debug("Set actionStart = %s" % value) ## # Get the "start" command. @@ -135,7 +135,7 @@ class Action: def setActionBan(self, value): self.__actionBan = value - logSys.info("Set actionBan = %s" % value) + logSys.debug("Set actionBan = %s" % value) ## # Get the "ban" command. @@ -160,7 +160,7 @@ class Action: def setActionUnban(self, value): self.__actionUnban = value - logSys.info("Set actionUnban = %s" % value) + logSys.debug("Set actionUnban = %s" % value) ## # Get the "unban" command. @@ -185,7 +185,7 @@ class Action: def setActionCheck(self, value): self.__actionCheck = value - logSys.info("Set actionCheck = %s" % value) + logSys.debug("Set actionCheck = %s" % value) ## # Get the "check" command. @@ -202,7 +202,7 @@ class Action: def setActionStop(self, value): self.__actionStop = value - logSys.info("Set actionStop = %s" % value) + logSys.debug("Set actionStop = %s" % value) ## # Get the "stop" command. From a32f04b0cb1d35bd0daa08d136bf6c7b1115fe7a Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Mon, 7 Apr 2008 22:41:19 +0000 Subject: [PATCH 09/23] - Added gssftpd filter. Thanks to Kevin Zembower. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@683 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 1 + MANIFEST | 1 + config/filter.d/gssftpd.conf | 14 ++++++++++++++ 3 files changed, 16 insertions(+) create mode 100644 config/filter.d/gssftpd.conf diff --git a/ChangeLog b/ChangeLog index 157fd0d5..27ac505d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,7 @@ ver. 0.8.3 (2008/??/??) - stable Christian Jobic who submitted a similar patch. - Fixed "fail2ban-client get logpath". Bug #1916986. - Changed some log levels. +- Added gssftpd filter. Thanks to Kevin Zembower. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/MANIFEST b/MANIFEST index cff2f3df..877720af 100644 --- a/MANIFEST +++ b/MANIFEST @@ -63,6 +63,7 @@ config/filter.d/apache-overflows.conf config/filter.d/courierlogin.conf config/filter.d/couriersmtp.conf config/filter.d/exim.conf +config/filter.d/gssftpd.conf config/filter.d/named-refused.conf config/filter.d/postfix.conf config/filter.d/proftpd.conf diff --git a/config/filter.d/gssftpd.conf b/config/filter.d/gssftpd.conf new file mode 100644 index 00000000..15fe6871 --- /dev/null +++ b/config/filter.d/gssftpd.conf @@ -0,0 +1,14 @@ +# Fail2Ban configuration file for wuftpd +# +# Author: Kevin Zembower (copied from wsftpd.conf) +# +# $Revision: 1 $ +# + +[Definition] + +# Option: failregex +# Notes.: regex to match the password failures messages in the logfile. +# Values: TEXT +# +failregex = ftpd(?:\[\d+\])?:\s+repeated login failures from \(\S+\)$ From 7dde8d6694b0c2099ab43768f4fe46d1aa53bed0 Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Mon, 7 Apr 2008 22:45:37 +0000 Subject: [PATCH 10/23] - Added svn:keywords. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@684 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- config/filter.d/gssftpd.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/filter.d/gssftpd.conf b/config/filter.d/gssftpd.conf index 15fe6871..af1c39c2 100644 --- a/config/filter.d/gssftpd.conf +++ b/config/filter.d/gssftpd.conf @@ -2,7 +2,7 @@ # # Author: Kevin Zembower (copied from wsftpd.conf) # -# $Revision: 1 $ +# $Revision$ # [Definition] From 46dab37bfeaf617f73fe96d14e5fc22c80d9d3cf Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Mon, 7 Apr 2008 22:49:47 +0000 Subject: [PATCH 11/23] - Added "Day/Month/Year Hour:Minute:Second" date template. Thanks to Dennis Winter. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@685 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 2 ++ server/datedetector.py | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index 27ac505d..a28d8656 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,6 +19,8 @@ ver. 0.8.3 (2008/??/??) - stable - Fixed "fail2ban-client get logpath". Bug #1916986. - Changed some log levels. - Added gssftpd filter. Thanks to Kevin Zembower. +- Added "Day/Month/Year Hour:Minute:Second" date template. + Thanks to Dennis Winter. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/server/datedetector.py b/server/datedetector.py index bc257e36..564fcd3d 100644 --- a/server/datedetector.py +++ b/server/datedetector.py @@ -67,6 +67,12 @@ class DateDetector: template.setRegex("\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}") template.setPattern("%Y/%m/%d %H:%M:%S") self.__templates.append(template) + # simple date too (from x11vnc) + template = DateStrptime() + template.setName("Day/Month/Year Hour:Minute:Second") + template.setRegex("\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}") + template.setPattern("%d/%m/%Y %H:%M:%S") + self.__templates.append(template) # Apache format [31/Oct/2006:09:22:55 -0000] template = DateStrptime() template.setName("Day/Month/Year:Hour:Minute:Second") From 4bc6a93ce2588638b06968fd4ce28c0b405c8bab Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Mon, 12 May 2008 08:25:17 +0000 Subject: [PATCH 12/23] =?UTF-8?q?-=20Fixed=20ignoreregex=20processing=20in?= =?UTF-8?q?=20fail2ban-client.=20Thanks=20to=20Ren=C3=A9=20Berber.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@689 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 2 ++ client/jailreader.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a28d8656..818b2532 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,6 +21,8 @@ ver. 0.8.3 (2008/??/??) - stable - Added gssftpd filter. Thanks to Kevin Zembower. - Added "Day/Month/Year Hour:Minute:Second" date template. Thanks to Dennis Winter. +- Fixed ignoreregex processing in fail2ban-client. Thanks to + René Berber. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/client/jailreader.py b/client/jailreader.py index 5ba44034..14684e43 100644 --- a/client/jailreader.py +++ b/client/jailreader.py @@ -122,7 +122,7 @@ class JailReader(ConfigReader): 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.append(["set", self.__name, "addignoreregex", self.__opts[opt]]) stream.extend(self.__filter.convert()) for action in self.__actions: stream.extend(action.convert()) From 7f37df4a599b6c6770eebf9bbc2c76bb5a3896d4 Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Mon, 12 May 2008 08:34:42 +0000 Subject: [PATCH 13/23] - Better (correct) fix for ignoreregex in jail.[conf|local]. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@690 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- client/jailreader.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/jailreader.py b/client/jailreader.py index 14684e43..63177f30 100644 --- a/client/jailreader.py +++ b/client/jailreader.py @@ -122,7 +122,10 @@ class JailReader(ConfigReader): elif opt == "failregex": stream.append(["set", self.__name, "failregex", self.__opts[opt]]) elif opt == "ignoreregex": - stream.append(["set", self.__name, "addignoreregex", self.__opts[opt]]) + for regex in self.__opts[opt].split('\n'): + # Do not send a command if the rule is empty. + if regex != '': + stream.append(["set", self.__name, "addignoreregex", regex]) stream.extend(self.__filter.convert()) for action in self.__actions: stream.extend(action.convert()) From 298adc4d4323d95f9f8c1300766969caa3495d2b Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Sun, 18 May 2008 19:53:18 +0000 Subject: [PATCH 14/23] - Added ISO 8601 date/time format. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@692 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- COPYING | 29 ++++++++++ ChangeLog | 1 + MANIFEST | 1 + server/datedetector.py | 8 ++- server/datetemplate.py | 23 +++++++- server/iso8601.py | 123 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 181 insertions(+), 4 deletions(-) create mode 100644 server/iso8601.py diff --git a/COPYING b/COPYING index d511905c..aae0eb8f 100644 --- a/COPYING +++ b/COPYING @@ -1,3 +1,7 @@ +The following copyright applies to all files present in the Fail2ban package, +except if a different copyright is explicitly defined in this file. + + GNU GENERAL PUBLIC LICENSE Version 2, June 1991 @@ -337,3 +341,28 @@ proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. + +--------------------------------- +The file server/iso8601.py is licensed under the following terms. + + +Copyright (c) 2007 Michael Twomey + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ChangeLog b/ChangeLog index 818b2532..e1148c21 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,7 @@ ver. 0.8.3 (2008/??/??) - stable Thanks to Dennis Winter. - Fixed ignoreregex processing in fail2ban-client. Thanks to René Berber. +- Added ISO 8601 date/time format. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/MANIFEST b/MANIFEST index 877720af..11ed92af 100644 --- a/MANIFEST +++ b/MANIFEST @@ -21,6 +21,7 @@ server/asyncserver.py server/filter.py server/filtergamin.py server/filterpoll.py +server/iso8601.py server/server.py server/actions.py server/faildata.py diff --git a/server/datedetector.py b/server/datedetector.py index 564fcd3d..794b385a 100644 --- a/server/datedetector.py +++ b/server/datedetector.py @@ -26,9 +26,7 @@ __license__ = "GPL" import time, logging -from datetemplate import DateStrptime -from datetemplate import DateTai64n -from datetemplate import DateEpoch +from datetemplate import DateStrptime, DateTai64n, DateEpoch, DateISO8601 from threading import Lock # Gets the instance of the logger. @@ -99,6 +97,10 @@ class DateDetector: template = DateEpoch() template.setName("Epoch") self.__templates.append(template) + # ISO 8601 + template = DateISO8601() + template.setName("ISO 8601") + self.__templates.append(template) finally: self.__lock.release() diff --git a/server/datetemplate.py b/server/datetemplate.py index 59dc4745..806e2823 100644 --- a/server/datetemplate.py +++ b/server/datetemplate.py @@ -28,6 +28,7 @@ __license__ = "GPL" import re, time from mytime import MyTime +import iso8601 class DateTemplate: @@ -163,4 +164,24 @@ class DateTai64n(DateTemplate): value = dateMatch.group() seconds_since_epoch = value[2:17] date = list(time.gmtime(int(seconds_since_epoch, 16))) - return date \ No newline at end of file + return date + + +class DateISO8601(DateTemplate): + + def __init__(self): + DateTemplate.__init__(self) + date_re = "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}" \ + ".[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?" \ + "(Z|(([-+])([0-9]{2}):([0-9]{2})))?" + self.setRegex(date_re) + + def getDate(self, line): + date = None + dateMatch = self.matchDate(line) + if dateMatch: + # Parses the date. + value = dateMatch.group() + print value + date = list(iso8601.parse_date(value).utctimetuple()) + return date diff --git a/server/iso8601.py b/server/iso8601.py new file mode 100644 index 00000000..71dccfea --- /dev/null +++ b/server/iso8601.py @@ -0,0 +1,123 @@ +# Copyright (c) 2007 Michael Twomey +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +"""ISO 8601 date time string parsing + +Basic usage: +>>> import iso8601 +>>> iso8601.parse_date("2007-01-25T12:00:00Z") +datetime.datetime(2007, 1, 25, 12, 0, tzinfo=) +>>> + +""" + +from datetime import datetime, timedelta, tzinfo +import re + +__all__ = ["parse_date", "ParseError"] + +# Adapted from http://delete.me.uk/2005/03/iso8601.html +ISO8601_REGEX = re.compile(r"(?P[0-9]{4})(-(?P[0-9]{1,2})(-(?P[0-9]{1,2})" + r"((?P.)(?P[0-9]{2}):(?P[0-9]{2})(:(?P[0-9]{2})(\.(?P[0-9]+))?)?" + r"(?PZ|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?" +) +TIMEZONE_REGEX = re.compile("(?P[+-])(?P[0-9]{2}).(?P[0-9]{2})") + +class ParseError(Exception): + """Raised when there is a problem parsing a date string""" + +# Yoinked from python docs +ZERO = timedelta(0) +class Utc(tzinfo): + """UTC + + """ + def utcoffset(self, dt): + return ZERO + + def tzname(self, dt): + return "UTC" + + def dst(self, dt): + return ZERO +UTC = Utc() + +class FixedOffset(tzinfo): + """Fixed offset in hours and minutes from UTC + + """ + def __init__(self, offset_hours, offset_minutes, name): + self.__offset = timedelta(hours=offset_hours, minutes=offset_minutes) + self.__name = name + + def utcoffset(self, dt): + return self.__offset + + def tzname(self, dt): + return self.__name + + def dst(self, dt): + return ZERO + + def __repr__(self): + return "" % self.__name + +def parse_timezone(tzstring, default_timezone=UTC): + """Parses ISO 8601 time zone specs into tzinfo offsets + + """ + if tzstring == "Z": + return default_timezone + # This isn't strictly correct, but it's common to encounter dates without + # timezones so I'll assume the default (which defaults to UTC). + # Addresses issue 4. + if tzstring is None: + return default_timezone + m = TIMEZONE_REGEX.match(tzstring) + prefix, hours, minutes = m.groups() + hours, minutes = int(hours), int(minutes) + if prefix == "-": + hours = -hours + minutes = -minutes + return FixedOffset(hours, minutes, tzstring) + +def parse_date(datestring, default_timezone=UTC): + """Parses ISO 8601 dates into datetime objects + + The timezone is parsed from the date string. However it is quite common to + have dates without a timezone (not strictly correct). In this case the + default timezone specified in default_timezone is used. This is UTC by + default. + """ + if not isinstance(datestring, basestring): + raise ParseError("Expecting a string %r" % datestring) + m = ISO8601_REGEX.match(datestring) + if not m: + raise ParseError("Unable to parse date string %r" % datestring) + groups = m.groupdict() + tz = parse_timezone(groups["timezone"], default_timezone=default_timezone) + if groups["fraction"] is None: + groups["fraction"] = 0 + else: + groups["fraction"] = int(float("0.%s" % groups["fraction"]) * 1e6) + return datetime(int(groups["year"]), int(groups["month"]), int(groups["day"]), + int(groups["hour"]), int(groups["minute"]), int(groups["second"]), + int(groups["fraction"]), tz) From 8da2fe515a51d86d67cfda29c828d02d630481f5 Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Mon, 19 May 2008 21:05:32 +0000 Subject: [PATCH 16/23] - Added and changed some logging level and messages. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@696 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 2 +- server/filter.py | 2 +- server/filtergamin.py | 2 +- server/filterpoll.py | 2 +- server/jail.py | 7 +++++-- server/server.py | 16 +++++++++++----- 6 files changed, 20 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index e1148c21..a6b33b25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,13 +17,13 @@ ver. 0.8.3 (2008/??/??) - stable - Fixed PID file while started in daemon mode. Thanks to Christian Jobic who submitted a similar patch. - Fixed "fail2ban-client get logpath". Bug #1916986. -- Changed some log levels. - Added gssftpd filter. Thanks to Kevin Zembower. - Added "Day/Month/Year Hour:Minute:Second" date template. Thanks to Dennis Winter. - Fixed ignoreregex processing in fail2ban-client. Thanks to René Berber. - Added ISO 8601 date/time format. +- Added and changed some logging level and messages. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/server/filter.py b/server/filter.py index dd9115d5..f9901150 100644 --- a/server/filter.py +++ b/server/filter.py @@ -68,7 +68,7 @@ class Filter(JailThread): self.dateDetector = DateDetector() self.dateDetector.addDefaultTemplate() - logSys.info("Created Filter") + logSys.debug("Created Filter") ## diff --git a/server/filtergamin.py b/server/filtergamin.py index 5d124c7b..d2b06fee 100644 --- a/server/filtergamin.py +++ b/server/filtergamin.py @@ -53,7 +53,7 @@ class FilterGamin(FileFilter): self.__modified = False # Gamin monitor self.monitor = gamin.WatchMonitor() - logSys.info("Created FilterGamin") + logSys.debug("Created FilterGamin") def callback(self, path, event): diff --git a/server/filterpoll.py b/server/filterpoll.py index 47d12a47..621816ed 100644 --- a/server/filterpoll.py +++ b/server/filterpoll.py @@ -54,7 +54,7 @@ class FilterPoll(FileFilter): ## The time of the last modification of the file. self.__lastModTime = dict() self.__file404Cnt = dict() - logSys.info("Created FilterPoll") + logSys.debug("Created FilterPoll") ## # Add a log file path diff --git a/server/jail.py b/server/jail.py index 363097a6..7b4a2719 100644 --- a/server/jail.py +++ b/server/jail.py @@ -37,6 +37,7 @@ class Jail: self.__name = name self.__queue = Queue.Queue() self.__filter = None + logSys.info("Creating new jail '%s'" % self.__name) if backend == "polling": self.__initPoller() else: @@ -47,14 +48,14 @@ class Jail: self.__action = Actions(self) def __initPoller(self): - logSys.info("Using poller") + logSys.info("Jail '%s' uses poller" % self.__name) from filterpoll import FilterPoll self.__filter = FilterPoll(self) def __initGamin(self): # Try to import gamin import gamin - logSys.info("Using Gamin") + logSys.info("Jail '%s' uses Gamin" % self.__name) from filtergamin import FilterGamin self.__filter = FilterGamin(self) @@ -82,12 +83,14 @@ class Jail: def start(self): self.__filter.start() self.__action.start() + logSys.info("Jail '%s' started" % self.__name) def stop(self): self.__filter.stop() self.__action.stop() self.__filter.join() self.__action.join() + logSys.info("Jail '%s' stopped" % self.__name) def isAlive(self): isAlive0 = self.__filter.isAlive() diff --git a/server/server.py b/server/server.py index ecfe45c4..53058bbf 100644 --- a/server/server.py +++ b/server/server.py @@ -46,11 +46,11 @@ class Server: self.__daemon = daemon self.__transm = Transmitter(self) self.__asyncServer = AsyncServer(self.__transm) - self.__logLevel = 3 - self.__logTarget = "STDOUT" + self.__logLevel = None + self.__logTarget = None # Set logging level - self.setLogLevel(self.__logLevel) - self.setLogTarget(self.__logTarget) + self.setLogLevel(3) + self.setLogTarget("STDOUT") def __sigTERMhandler(self, signum, frame): logSys.debug("Caught signal %d. Exiting" % signum) @@ -66,6 +66,7 @@ class Server: # First set the mask to only allow access to owner os.umask(0077) if self.__daemon: + logSys.info("Starting in daemon mode") ret = self.__createDaemon() if ret: logSys.info("Daemon started") @@ -345,7 +346,6 @@ class Server: logSys.error("Unable to log to " + target) logSys.info("Logging to previous target " + self.__logTarget) return False - self.__logTarget = target # Removes previous handlers for handler in logging.getLogger("fail2ban").handlers: # Closes the handler. @@ -354,6 +354,12 @@ class Server: # tell the handler to use this format hdlr.setFormatter(formatter) logging.getLogger("fail2ban").addHandler(hdlr) + # Does not display this message at startup. + if not self.__logTarget == None: + logSys.info("Changed logging target to %s for Fail2ban v%s" % + (target, version.version)) + # Sets the logging target. + self.__logTarget = target return True finally: self.__loggingLock.release() From 11c8c71014a6043d5120eb2c56e7617d82d2cded Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Wed, 21 May 2008 22:17:00 +0000 Subject: [PATCH 17/23] - Added missing ignoreregex to filters. Thanks to Klaus Lehmann. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@699 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 2 ++ config/filter.d/gssftpd.conf | 6 ++++++ config/filter.d/named-refused.conf | 6 +++++- config/filter.d/pam-generic.conf | 6 ++++++ config/filter.d/wuftpd.conf | 6 ++++++ 5 files changed, 25 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a6b33b25..699d99ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24,6 +24,8 @@ ver. 0.8.3 (2008/??/??) - stable René Berber. - Added ISO 8601 date/time format. - Added and changed some logging level and messages. +- Added missing ignoreregex to filters. Thanks to Klaus + Lehmann. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/config/filter.d/gssftpd.conf b/config/filter.d/gssftpd.conf index af1c39c2..8c166309 100644 --- a/config/filter.d/gssftpd.conf +++ b/config/filter.d/gssftpd.conf @@ -12,3 +12,9 @@ # Values: TEXT # failregex = ftpd(?:\[\d+\])?:\s+repeated login failures from \(\S+\)$ + +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = diff --git a/config/filter.d/named-refused.conf b/config/filter.d/named-refused.conf index 74014644..c2c06a8f 100644 --- a/config/filter.d/named-refused.conf +++ b/config/filter.d/named-refused.conf @@ -28,4 +28,8 @@ __line_prefix=(?:\s\S+ %(__daemon_combs_re)s\s+)? # failregex = %(__line_prefix)sclient #\S+: query(?: \(cache\))? '.*' denied\s*$ - +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = diff --git a/config/filter.d/pam-generic.conf b/config/filter.d/pam-generic.conf index 55e9efd0..7e48a08d 100644 --- a/config/filter.d/pam-generic.conf +++ b/config/filter.d/pam-generic.conf @@ -23,3 +23,9 @@ __pam_combs_re=(?:%(__pid_re)s?:\s+%(__pam_re)s|%(__pam_re)s%(__pid_re)s?:) # Values: TEXT # failregex = \s\S+ \S+%(__pam_combs_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=%(_ttys_re)s ruser=\S* rhost=(?:\s+user=.*)?\s*$ + +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = diff --git a/config/filter.d/wuftpd.conf b/config/filter.d/wuftpd.conf index 2d08022d..56ba499f 100644 --- a/config/filter.d/wuftpd.conf +++ b/config/filter.d/wuftpd.conf @@ -12,3 +12,9 @@ # Values: TEXT # failregex = wu-ftpd(?:\[\d+\])?:\s+\(pam_unix\)\s+authentication failure.* rhost=$ + +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = From cc62cd70760344b00f827a2cb1a28abfa218c170 Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Mon, 14 Jul 2008 21:56:07 +0000 Subject: [PATCH 18/23] - Use poll instead of select in asyncore.loop. This should solve the "Unknown error 514". Thanks to Michael Geiger and Klaus Lehmann. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@700 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 3 +++ server/asyncserver.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 699d99ad..6acd529d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,6 +26,9 @@ ver. 0.8.3 (2008/??/??) - stable - Added and changed some logging level and messages. - Added missing ignoreregex to filters. Thanks to Klaus Lehmann. +- Use poll instead of select in asyncore.loop. This should + solve the "Unknown error 514". Thanks to Michael Geiger and + Klaus Lehmann. ver. 0.8.2 (2008/03/06) - stable ---------- diff --git a/server/asyncserver.py b/server/asyncserver.py index 548a8226..13a74dac 100644 --- a/server/asyncserver.py +++ b/server/asyncserver.py @@ -132,7 +132,7 @@ class AsyncServer(asyncore.dispatcher): # Sets the init flag. self.__init = True # TODO Add try..catch - asyncore.loop() + asyncore.loop(use_poll = True) ## # Stops the communication server. From 9ed39a4387c935222b95a071a1176c1a561115e0 Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Wed, 16 Jul 2008 21:11:42 +0000 Subject: [PATCH 19/23] - Send file if the number of lines is greater or equal and not only equal to the limit. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@701 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- config/action.d/mail-buffered.conf | 2 +- config/action.d/sendmail-buffered.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/action.d/mail-buffered.conf b/config/action.d/mail-buffered.conf index 750bfca9..8a33d0ea 100644 --- a/config/action.d/mail-buffered.conf +++ b/config/action.d/mail-buffered.conf @@ -50,7 +50,7 @@ actioncheck = # actionban = printf %%b "`date`: ( failures)\n" >> LINE=$( wc -l | awk '{ print $1 }' ) - if [ $LINE -eq ]; then + if [ $LINE -ge ]; then printf %%b "Hi,\n These hosts have been banned by Fail2Ban.\n `cat ` diff --git a/config/action.d/sendmail-buffered.conf b/config/action.d/sendmail-buffered.conf index 698981a0..de8166ad 100644 --- a/config/action.d/sendmail-buffered.conf +++ b/config/action.d/sendmail-buffered.conf @@ -59,7 +59,7 @@ actioncheck = # actionban = printf %%b "`date`: ( failures)\n" >> LINE=$( wc -l | awk '{ print $1 }' ) - if [ $LINE -eq ]; then + if [ $LINE -ge ]; then printf %%b "Subject: [Fail2Ban] : summary From: Fail2Ban <> To: \n From 2ca9261bb39d65e6094d9f27459a3af267d0379c Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Wed, 16 Jul 2008 22:10:44 +0000 Subject: [PATCH 20/23] - Prepared for 0.8.3 git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@702 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- ChangeLog | 4 ++-- README | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6acd529d..c54efc49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,10 +4,10 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ============================================================= -Fail2Ban (version 0.8.3) 2008/??/?? +Fail2Ban (version 0.8.3) 2008/07/17 ============================================================= -ver. 0.8.3 (2008/??/??) - stable +ver. 0.8.3 (2008/07/17) - stable ---------- - Process failtickets as long as failmanager is not empty. - Added "pam-generic" filter and more configuration fixes. diff --git a/README b/README index 7d2a4281..d413aca7 100644 --- a/README +++ b/README @@ -4,7 +4,7 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ============================================================= -Fail2Ban (version 0.8.3) 2008/??/?? +Fail2Ban (version 0.8.3) 2008/07/17 ============================================================= Fail2Ban scans log files like /var/log/pwdfail and bans IP From a779bfc65526f518b6d6cae07b65aed21c8ecdcb Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Thu, 17 Jul 2008 11:21:51 -0400 Subject: [PATCH 21/23] Adjusted vcs paths --- debian/changelog | 6 ++++++ debian/control | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 0c1aa85d..71f6df9b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +fail2ban (0.8.1-4) UNRELEASED; urgency=low + + * Adjusted vcs paths + + -- Yaroslav Halchenko Thu, 17 Jul 2008 11:21:15 -0400 + fail2ban (0.8.1-3) unstable; urgency=low * Added Vcs- fields, moved Homepage into source header's field diff --git a/debian/control b/debian/control index 1ae7275b..415bb903 100644 --- a/debian/control +++ b/debian/control @@ -6,8 +6,8 @@ Build-Depends: debhelper (>= 5.0.37.2), python Build-Depends-Indep: python-central (>= 0.5.6) XS-Python-Version: current, >= 2.4 Homepage: http://www.fail2ban.org -Vcs-Browser: http://git.onerussian.com/?p=fail2ban -Vcs-git: http://git.onerussian.com/vcs/fail2ban +Vcs-Browser: http://git.onerussian.com/?p=deb/fail2ban.git +Vcs-git: http://git.onerussian.com/vcs/deb/fail2ban.git Standards-Version: 3.7.3 From 24c8340d813cf6c0783090583173fb5f84bb9fc7 Mon Sep 17 00:00:00 2001 From: Cyril Jaquier Date: Thu, 17 Jul 2008 21:28:51 +0000 Subject: [PATCH 22/23] - Prepared for 0.8.3. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@703 a942ae1a-1317-0410-a47c-b1dcaea8d605 --- common/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/version.py b/common/version.py index 79c66b15..8da11b94 100644 --- a/common/version.py +++ b/common/version.py @@ -24,4 +24,4 @@ __date__ = "$Date$" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" -version = "0.8.2-SVN" +version = "0.8.3" From 68e22af143249de34003860372f4f9a84de101dd Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Mon, 21 Jul 2008 10:13:13 -0400 Subject: [PATCH 23/23] Imported Upstream version 0.8.3 --- COPYING | 29 ++++++ ChangeLog | 25 ++++- PKG-INFO | 2 +- README | 6 +- client/jailreader.py | 11 ++- common/version.py | 8 +- config/action.d/mail-buffered.conf | 4 +- config/action.d/sendmail-buffered.conf | 4 +- config/filter.d/gssftpd.conf | 20 ++++ config/filter.d/named-refused.conf | 8 +- config/filter.d/pam-generic.conf | 31 +++++++ config/filter.d/proftpd.conf | 4 +- config/filter.d/wuftpd.conf | 8 +- files/redhat-initd | 2 +- files/suse-initd | 2 +- server/action.py | 16 ++-- server/asyncserver.py | 2 +- server/datedetector.py | 20 ++-- server/datetemplate.py | 29 +++++- server/filter.py | 8 +- server/filtergamin.py | 13 +-- server/filterpoll.py | 13 +-- server/iso8601.py | 123 +++++++++++++++++++++++++ server/jail.py | 13 ++- server/server.py | 52 ++++++----- setup.py | 9 +- 26 files changed, 373 insertions(+), 89 deletions(-) create mode 100644 config/filter.d/gssftpd.conf create mode 100644 config/filter.d/pam-generic.conf create mode 100644 server/iso8601.py diff --git a/COPYING b/COPYING index d511905c..aae0eb8f 100644 --- a/COPYING +++ b/COPYING @@ -1,3 +1,7 @@ +The following copyright applies to all files present in the Fail2ban package, +except if a different copyright is explicitly defined in this file. + + GNU GENERAL PUBLIC LICENSE Version 2, June 1991 @@ -337,3 +341,28 @@ proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. + +--------------------------------- +The file server/iso8601.py is licensed under the following terms. + + +Copyright (c) 2007 Michael Twomey + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ChangeLog b/ChangeLog index 2702b195..c54efc49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,9 +4,32 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ============================================================= -Fail2Ban (version 0.8.2) 2008/03/06 +Fail2Ban (version 0.8.3) 2008/07/17 ============================================================= +ver. 0.8.3 (2008/07/17) - stable +---------- +- Process failtickets as long as failmanager is not empty. +- Added "pam-generic" filter and more configuration fixes. + Thanks to Yaroslav Halchenko. +- Fixed socket path in redhat and suse init script. Thanks to + Jim Wight. +- Fixed PID file while started in daemon mode. Thanks to + Christian Jobic who submitted a similar patch. +- Fixed "fail2ban-client get logpath". Bug #1916986. +- Added gssftpd filter. Thanks to Kevin Zembower. +- Added "Day/Month/Year Hour:Minute:Second" date template. + Thanks to Dennis Winter. +- Fixed ignoreregex processing in fail2ban-client. Thanks to + René Berber. +- Added ISO 8601 date/time format. +- Added and changed some logging level and messages. +- Added missing ignoreregex to filters. Thanks to Klaus + Lehmann. +- Use poll instead of select in asyncore.loop. This should + solve the "Unknown error 514". Thanks to Michael Geiger and + Klaus Lehmann. + ver. 0.8.2 (2008/03/06) - stable ---------- - Fixed named filter. Thanks to Yaroslav Halchenko diff --git a/PKG-INFO b/PKG-INFO index 74670ebd..4a30de06 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: fail2ban -Version: 0.8.2 +Version: 0.8.3 Summary: Ban IPs that make too many password failure Home-page: http://www.fail2ban.org Author: Cyril Jaquier diff --git a/README b/README index d9e1e3f0..d413aca7 100644 --- a/README +++ b/README @@ -4,7 +4,7 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ============================================================= -Fail2Ban (version 0.8.2) 2008/03/06 +Fail2Ban (version 0.8.3) 2008/07/17 ============================================================= Fail2Ban scans log files like /var/log/pwdfail and bans IP @@ -28,8 +28,8 @@ Optional: To install, just do: -> tar xvfj fail2ban-0.8.2.tar.bz2 -> cd fail2ban-0.8.2 +> tar xvfj fail2ban-0.8.3.tar.bz2 +> cd fail2ban-0.8.3 > python setup.py install This will install Fail2Ban into /usr/share/fail2ban. The diff --git a/client/jailreader.py b/client/jailreader.py index af245ae1..c77aad57 100644 --- a/client/jailreader.py +++ b/client/jailreader.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 659 $ +# $Revision: 690 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 659 $" -__date__ = "$Date: 2008-03-05 00:09:30 +0100 (Wed, 05 Mar 2008) $" +__version__ = "$Revision: 690 $" +__date__ = "$Date: 2008-05-12 10:34:42 +0200 (Mon, 12 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -122,7 +122,10 @@ class JailReader(ConfigReader): elif opt == "failregex": stream.append(["set", self.__name, "failregex", self.__opts[opt]]) elif opt == "ignoreregex": - stream.append(["set", self.__name, "ignoreregex", self.__opts[opt]]) + for regex in self.__opts[opt].split('\n'): + # Do not send a command if the rule is empty. + if regex != '': + stream.append(["set", self.__name, "addignoreregex", regex]) stream.extend(self.__filter.convert()) for action in self.__actions: stream.extend(action.convert()) diff --git a/common/version.py b/common/version.py index 3dd7f9bf..416848bb 100644 --- a/common/version.py +++ b/common/version.py @@ -16,12 +16,12 @@ # Author: Cyril Jaquier # -# $Revision: 673 $ +# $Revision: 703 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 673 $" -__date__ = "$Date: 2008-03-06 00:19:45 +0100 (Thu, 06 Mar 2008) $" +__version__ = "$Revision: 703 $" +__date__ = "$Date: 2008-07-17 23:28:51 +0200 (Thu, 17 Jul 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" -version = "0.8.2" +version = "0.8.3" diff --git a/config/action.d/mail-buffered.conf b/config/action.d/mail-buffered.conf index da7f2d68..04788ab9 100644 --- a/config/action.d/mail-buffered.conf +++ b/config/action.d/mail-buffered.conf @@ -2,7 +2,7 @@ # # Author: Cyril Jaquier # -# $Revision: 668 $ +# $Revision: 701 $ # [Definition] @@ -50,7 +50,7 @@ actioncheck = # actionban = printf %%b "`date`: ( failures)\n" >> LINE=$( wc -l | awk '{ print $1 }' ) - if [ $LINE -eq ]; then + if [ $LINE -ge ]; then printf %%b "Hi,\n These hosts have been banned by Fail2Ban.\n `cat ` diff --git a/config/action.d/sendmail-buffered.conf b/config/action.d/sendmail-buffered.conf index c37a71d2..90a482de 100644 --- a/config/action.d/sendmail-buffered.conf +++ b/config/action.d/sendmail-buffered.conf @@ -2,7 +2,7 @@ # # Author: Cyril Jaquier # -# $Revision: 660 $ +# $Revision: 701 $ # [Definition] @@ -59,7 +59,7 @@ actioncheck = # actionban = printf %%b "`date`: ( failures)\n" >> LINE=$( wc -l | awk '{ print $1 }' ) - if [ $LINE -eq ]; then + if [ $LINE -ge ]; then printf %%b "Subject: [Fail2Ban] : summary From: Fail2Ban <> To: \n diff --git a/config/filter.d/gssftpd.conf b/config/filter.d/gssftpd.conf new file mode 100644 index 00000000..ee000ed9 --- /dev/null +++ b/config/filter.d/gssftpd.conf @@ -0,0 +1,20 @@ +# Fail2Ban configuration file for wuftpd +# +# Author: Kevin Zembower (copied from wsftpd.conf) +# +# $Revision: 699 $ +# + +[Definition] + +# Option: failregex +# Notes.: regex to match the password failures messages in the logfile. +# Values: TEXT +# +failregex = ftpd(?:\[\d+\])?:\s+repeated login failures from \(\S+\)$ + +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = diff --git a/config/filter.d/named-refused.conf b/config/filter.d/named-refused.conf index c6aed9bb..69b36970 100644 --- a/config/filter.d/named-refused.conf +++ b/config/filter.d/named-refused.conf @@ -4,7 +4,7 @@ # # Author: Yaroslav Halchenko # -# $Revision: 616 $ +# $Revision: 699 $ # [Definition] @@ -28,4 +28,8 @@ __line_prefix=(?:\s\S+ %(__daemon_combs_re)s\s+)? # failregex = %(__line_prefix)sclient #\S+: query(?: \(cache\))? '.*' denied\s*$ - +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = diff --git a/config/filter.d/pam-generic.conf b/config/filter.d/pam-generic.conf new file mode 100644 index 00000000..7e48a08d --- /dev/null +++ b/config/filter.d/pam-generic.conf @@ -0,0 +1,31 @@ +# Fail2Ban configuration file for generic PAM authentication errors +# +# Author: Yaroslav Halchenko +# +# $Revision: $ +# + +[Definition] + +# if you want to catch only login erros from specific daemons, use smth like +#_ttys_re=(?:ssh|pure-ftpd|ftp) +# To catch all failed logins +_ttys_re=\S* + +# +# Shortcuts for easier comprehension of the failregex +__pid_re=(?:\[\d+\]) +__pam_re=\(?pam_unix(?:\(\S+\))?\)?:? +__pam_combs_re=(?:%(__pid_re)s?:\s+%(__pam_re)s|%(__pam_re)s%(__pid_re)s?:) + +# Option: failregex +# Notes.: regex to match the password failures messages in the logfile. +# Values: TEXT +# +failregex = \s\S+ \S+%(__pam_combs_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=%(_ttys_re)s ruser=\S* rhost=(?:\s+user=.*)?\s*$ + +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = diff --git a/config/filter.d/proftpd.conf b/config/filter.d/proftpd.conf index 52a741e8..552c2935 100644 --- a/config/filter.d/proftpd.conf +++ b/config/filter.d/proftpd.conf @@ -2,7 +2,7 @@ # # Author: Yaroslav Halchenko # -# $Revision: 665 $ +# $Revision: 677 $ # [Definition] @@ -14,7 +14,7 @@ # (?:::f{4,6}:)?(?P\S+) # Values: TEXT # -failregex = \(\S+\[\]\)[: -]+ USER \S+: no such user found from \S+ \[[0-9.]+\] to \S+:\S+$ +failregex = \(\S+\[\]\)[: -]+ USER \S+: no such user found from \S+ \[\S+\] to \S+:\S+$ \(\S+\[\]\)[: -]+ USER \S+ \(Login failed\): Incorrect password\.$ \(\S+\[\]\)[: -]+ SECURITY VIOLATION: \S+ login attempted\.$ \(\S+\[\]\)[: -]+ Maximum login attempts \(\d+\) exceeded$ diff --git a/config/filter.d/wuftpd.conf b/config/filter.d/wuftpd.conf index 7c2a8acb..0bf997b1 100644 --- a/config/filter.d/wuftpd.conf +++ b/config/filter.d/wuftpd.conf @@ -2,7 +2,7 @@ # # Author: Yaroslav Halchenko # -# $Revision: 592 $ +# $Revision: 699 $ # [Definition] @@ -12,3 +12,9 @@ # Values: TEXT # failregex = wu-ftpd(?:\[\d+\])?:\s+\(pam_unix\)\s+authentication failure.* rhost=$ + +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = diff --git a/files/redhat-initd b/files/redhat-initd index 529aef25..75c7f808 100755 --- a/files/redhat-initd +++ b/files/redhat-initd @@ -27,7 +27,7 @@ start() { echo -n $"Starting fail2ban: " getpid if [ -z "$pid" ]; then - rm -rf /tmp/fail2ban.sock # in case of unclean shutdown + rm -rf /var/run/fail2ban/fail2ban.sock # in case of unclean shutdown $FAIL2BAN start > /dev/null RETVAL=$? fi diff --git a/files/suse-initd b/files/suse-initd index bbd679aa..ecd55d9a 100755 --- a/files/suse-initd +++ b/files/suse-initd @@ -16,7 +16,7 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/usr/sbin:/usr/bin:/bin FAIL2BAN_BIN=/usr/local/bin/fail2ban-client FAIL2BAN_SERVER=/usr/local/bin/fail2ban-server -FAIL2BAN_SOCKET=/tmp/fail2ban.sock +FAIL2BAN_SOCKET=/var/run/fail2ban/fail2ban.sock test -x $FAIL2BAN_BIN || { echo "$FAIL2BAN_BIN not installed"; if [ "$1" = "stop" ]; then exit 0; else exit 5; fi; } diff --git a/server/action.py b/server/action.py index 438d6fae..70f4c378 100644 --- a/server/action.py +++ b/server/action.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 635 $ +# $Revision: 682 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 635 $" -__date__ = "$Date: 2007-12-16 22:38:04 +0100 (Sun, 16 Dec 2007) $" +__version__ = "$Revision: 682 $" +__date__ = "$Date: 2008-04-08 00:25:16 +0200 (Tue, 08 Apr 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -106,7 +106,7 @@ class Action: def setActionStart(self, value): self.__actionStart = value - logSys.info("Set actionStart = %s" % value) + logSys.debug("Set actionStart = %s" % value) ## # Get the "start" command. @@ -135,7 +135,7 @@ class Action: def setActionBan(self, value): self.__actionBan = value - logSys.info("Set actionBan = %s" % value) + logSys.debug("Set actionBan = %s" % value) ## # Get the "ban" command. @@ -160,7 +160,7 @@ class Action: def setActionUnban(self, value): self.__actionUnban = value - logSys.info("Set actionUnban = %s" % value) + logSys.debug("Set actionUnban = %s" % value) ## # Get the "unban" command. @@ -185,7 +185,7 @@ class Action: def setActionCheck(self, value): self.__actionCheck = value - logSys.info("Set actionCheck = %s" % value) + logSys.debug("Set actionCheck = %s" % value) ## # Get the "check" command. @@ -202,7 +202,7 @@ class Action: def setActionStop(self, value): self.__actionStop = value - logSys.info("Set actionStop = %s" % value) + logSys.debug("Set actionStop = %s" % value) ## # Get the "stop" command. diff --git a/server/asyncserver.py b/server/asyncserver.py index 548a8226..13a74dac 100644 --- a/server/asyncserver.py +++ b/server/asyncserver.py @@ -132,7 +132,7 @@ class AsyncServer(asyncore.dispatcher): # Sets the init flag. self.__init = True # TODO Add try..catch - asyncore.loop() + asyncore.loop(use_poll = True) ## # Stops the communication server. diff --git a/server/datedetector.py b/server/datedetector.py index c47a67c4..4198a1cd 100644 --- a/server/datedetector.py +++ b/server/datedetector.py @@ -16,19 +16,17 @@ # Author: Cyril Jaquier # -# $Revision: 645 $ +# $Revision: 692 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 645 $" -__date__ = "$Date: 2008-01-16 23:55:04 +0100 (Wed, 16 Jan 2008) $" +__version__ = "$Revision: 692 $" +__date__ = "$Date: 2008-05-18 21:53:18 +0200 (Sun, 18 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" import time, logging -from datetemplate import DateStrptime -from datetemplate import DateTai64n -from datetemplate import DateEpoch +from datetemplate import DateStrptime, DateTai64n, DateEpoch, DateISO8601 from threading import Lock # Gets the instance of the logger. @@ -67,6 +65,12 @@ class DateDetector: template.setRegex("\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}") template.setPattern("%Y/%m/%d %H:%M:%S") self.__templates.append(template) + # simple date too (from x11vnc) + template = DateStrptime() + template.setName("Day/Month/Year Hour:Minute:Second") + template.setRegex("\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}") + template.setPattern("%d/%m/%Y %H:%M:%S") + self.__templates.append(template) # Apache format [31/Oct/2006:09:22:55 -0000] template = DateStrptime() template.setName("Day/Month/Year:Hour:Minute:Second") @@ -93,6 +97,10 @@ class DateDetector: template = DateEpoch() template.setName("Epoch") self.__templates.append(template) + # ISO 8601 + template = DateISO8601() + template.setName("ISO 8601") + self.__templates.append(template) finally: self.__lock.release() diff --git a/server/datetemplate.py b/server/datetemplate.py index 25c2d71d..18d433d6 100644 --- a/server/datetemplate.py +++ b/server/datetemplate.py @@ -17,17 +17,18 @@ # Author: Cyril Jaquier # -# $Revision: 652 $ +# $Revision: 692 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 652 $" -__date__ = "$Date: 2008-02-29 00:01:30 +0100 (Fri, 29 Feb 2008) $" +__version__ = "$Revision: 692 $" +__date__ = "$Date: 2008-05-18 21:53:18 +0200 (Sun, 18 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" import re, time from mytime import MyTime +import iso8601 class DateTemplate: @@ -163,4 +164,24 @@ class DateTai64n(DateTemplate): value = dateMatch.group() seconds_since_epoch = value[2:17] date = list(time.gmtime(int(seconds_since_epoch, 16))) - return date \ No newline at end of file + return date + + +class DateISO8601(DateTemplate): + + def __init__(self): + DateTemplate.__init__(self) + date_re = "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}" \ + ".[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?" \ + "(Z|(([-+])([0-9]{2}):([0-9]{2})))?" + self.setRegex(date_re) + + def getDate(self, line): + date = None + dateMatch = self.matchDate(line) + if dateMatch: + # Parses the date. + value = dateMatch.group() + print value + date = list(iso8601.parse_date(value).utctimetuple()) + return date diff --git a/server/filter.py b/server/filter.py index 0cf5b08b..6ccd81fe 100644 --- a/server/filter.py +++ b/server/filter.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 656 $ +# $Revision: 696 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 656 $" -__date__ = "$Date: 2008-03-04 01:17:56 +0100 (Tue, 04 Mar 2008) $" +__version__ = "$Revision: 696 $" +__date__ = "$Date: 2008-05-19 23:05:32 +0200 (Mon, 19 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -68,7 +68,7 @@ class Filter(JailThread): self.dateDetector = DateDetector() self.dateDetector.addDefaultTemplate() - logSys.info("Created Filter") + logSys.debug("Created Filter") ## diff --git a/server/filtergamin.py b/server/filtergamin.py index 635ebb70..445e9b8d 100644 --- a/server/filtergamin.py +++ b/server/filtergamin.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 649 $ +# $Revision: 696 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 649 $" -__date__ = "$Date: 2008-02-02 18:04:11 +0100 (Sat, 02 Feb 2008) $" +__version__ = "$Revision: 696 $" +__date__ = "$Date: 2008-05-19 23:05:32 +0200 (Mon, 19 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -53,7 +53,7 @@ class FilterGamin(FileFilter): self.__modified = False # Gamin monitor self.monitor = gamin.WatchMonitor() - logSys.info("Created FilterGamin") + logSys.debug("Created FilterGamin") def callback(self, path, event): @@ -108,8 +108,9 @@ class FilterGamin(FileFilter): if self.__modified: try: - ticket = self.failManager.toBan() - self.jail.putFailTicket(ticket) + while True: + ticket = self.failManager.toBan() + self.jail.putFailTicket(ticket) except FailManagerEmpty: self.failManager.cleanup(MyTime.time()) self.dateDetector.sortTemplate() diff --git a/server/filterpoll.py b/server/filterpoll.py index 98ad0296..00b26b2d 100644 --- a/server/filterpoll.py +++ b/server/filterpoll.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 649 $ +# $Revision: 696 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 649 $" -__date__ = "$Date: 2008-02-02 18:04:11 +0100 (Sat, 02 Feb 2008) $" +__version__ = "$Revision: 696 $" +__date__ = "$Date: 2008-05-19 23:05:32 +0200 (Mon, 19 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -54,7 +54,7 @@ class FilterPoll(FileFilter): ## The time of the last modification of the file. self.__lastModTime = dict() self.__file404Cnt = dict() - logSys.info("Created FilterPoll") + logSys.debug("Created FilterPoll") ## # Add a log file path @@ -103,8 +103,9 @@ class FilterPoll(FileFilter): if self.__modified: try: - ticket = self.failManager.toBan() - self.jail.putFailTicket(ticket) + while True: + ticket = self.failManager.toBan() + self.jail.putFailTicket(ticket) except FailManagerEmpty: self.failManager.cleanup(MyTime.time()) self.dateDetector.sortTemplate() diff --git a/server/iso8601.py b/server/iso8601.py new file mode 100644 index 00000000..71dccfea --- /dev/null +++ b/server/iso8601.py @@ -0,0 +1,123 @@ +# Copyright (c) 2007 Michael Twomey +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +"""ISO 8601 date time string parsing + +Basic usage: +>>> import iso8601 +>>> iso8601.parse_date("2007-01-25T12:00:00Z") +datetime.datetime(2007, 1, 25, 12, 0, tzinfo=) +>>> + +""" + +from datetime import datetime, timedelta, tzinfo +import re + +__all__ = ["parse_date", "ParseError"] + +# Adapted from http://delete.me.uk/2005/03/iso8601.html +ISO8601_REGEX = re.compile(r"(?P[0-9]{4})(-(?P[0-9]{1,2})(-(?P[0-9]{1,2})" + r"((?P.)(?P[0-9]{2}):(?P[0-9]{2})(:(?P[0-9]{2})(\.(?P[0-9]+))?)?" + r"(?PZ|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?" +) +TIMEZONE_REGEX = re.compile("(?P[+-])(?P[0-9]{2}).(?P[0-9]{2})") + +class ParseError(Exception): + """Raised when there is a problem parsing a date string""" + +# Yoinked from python docs +ZERO = timedelta(0) +class Utc(tzinfo): + """UTC + + """ + def utcoffset(self, dt): + return ZERO + + def tzname(self, dt): + return "UTC" + + def dst(self, dt): + return ZERO +UTC = Utc() + +class FixedOffset(tzinfo): + """Fixed offset in hours and minutes from UTC + + """ + def __init__(self, offset_hours, offset_minutes, name): + self.__offset = timedelta(hours=offset_hours, minutes=offset_minutes) + self.__name = name + + def utcoffset(self, dt): + return self.__offset + + def tzname(self, dt): + return self.__name + + def dst(self, dt): + return ZERO + + def __repr__(self): + return "" % self.__name + +def parse_timezone(tzstring, default_timezone=UTC): + """Parses ISO 8601 time zone specs into tzinfo offsets + + """ + if tzstring == "Z": + return default_timezone + # This isn't strictly correct, but it's common to encounter dates without + # timezones so I'll assume the default (which defaults to UTC). + # Addresses issue 4. + if tzstring is None: + return default_timezone + m = TIMEZONE_REGEX.match(tzstring) + prefix, hours, minutes = m.groups() + hours, minutes = int(hours), int(minutes) + if prefix == "-": + hours = -hours + minutes = -minutes + return FixedOffset(hours, minutes, tzstring) + +def parse_date(datestring, default_timezone=UTC): + """Parses ISO 8601 dates into datetime objects + + The timezone is parsed from the date string. However it is quite common to + have dates without a timezone (not strictly correct). In this case the + default timezone specified in default_timezone is used. This is UTC by + default. + """ + if not isinstance(datestring, basestring): + raise ParseError("Expecting a string %r" % datestring) + m = ISO8601_REGEX.match(datestring) + if not m: + raise ParseError("Unable to parse date string %r" % datestring) + groups = m.groupdict() + tz = parse_timezone(groups["timezone"], default_timezone=default_timezone) + if groups["fraction"] is None: + groups["fraction"] = 0 + else: + groups["fraction"] = int(float("0.%s" % groups["fraction"]) * 1e6) + return datetime(int(groups["year"]), int(groups["month"]), int(groups["day"]), + int(groups["hour"]), int(groups["minute"]), int(groups["second"]), + int(groups["fraction"]), tz) diff --git a/server/jail.py b/server/jail.py index 1d006de3..ca123e88 100644 --- a/server/jail.py +++ b/server/jail.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 567 $ +# $Revision: 696 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 567 $" -__date__ = "$Date: 2007-03-26 23:17:31 +0200 (Mon, 26 Mar 2007) $" +__version__ = "$Revision: 696 $" +__date__ = "$Date: 2008-05-19 23:05:32 +0200 (Mon, 19 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -37,6 +37,7 @@ class Jail: self.__name = name self.__queue = Queue.Queue() self.__filter = None + logSys.info("Creating new jail '%s'" % self.__name) if backend == "polling": self.__initPoller() else: @@ -47,14 +48,14 @@ class Jail: self.__action = Actions(self) def __initPoller(self): - logSys.info("Using poller") + logSys.info("Jail '%s' uses poller" % self.__name) from filterpoll import FilterPoll self.__filter = FilterPoll(self) def __initGamin(self): # Try to import gamin import gamin - logSys.info("Using Gamin") + logSys.info("Jail '%s' uses Gamin" % self.__name) from filtergamin import FilterGamin self.__filter = FilterGamin(self) @@ -82,12 +83,14 @@ class Jail: def start(self): self.__filter.start() self.__action.start() + logSys.info("Jail '%s' started" % self.__name) def stop(self): self.__filter.stop() self.__action.stop() self.__filter.join() self.__action.join() + logSys.info("Jail '%s' stopped" % self.__name) def isAlive(self): isAlive0 = self.__filter.isAlive() diff --git a/server/server.py b/server/server.py index 01254af8..941fc43c 100644 --- a/server/server.py +++ b/server/server.py @@ -16,11 +16,11 @@ # Author: Cyril Jaquier # -# $Revision: 647 $ +# $Revision: 696 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 647 $" -__date__ = "$Date: 2008-01-20 17:30:35 +0100 (Sun, 20 Jan 2008) $" +__version__ = "$Revision: 696 $" +__date__ = "$Date: 2008-05-19 23:05:32 +0200 (Mon, 19 May 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -46,11 +46,11 @@ class Server: self.__daemon = daemon self.__transm = Transmitter(self) self.__asyncServer = AsyncServer(self.__transm) - self.__logLevel = 3 - self.__logTarget = "STDOUT" + self.__logLevel = None + self.__logTarget = None # Set logging level - self.setLogLevel(self.__logLevel) - self.setLogTarget(self.__logTarget) + self.setLogLevel(3) + self.setLogTarget("STDOUT") def __sigTERMhandler(self, signum, frame): logSys.debug("Caught signal %d. Exiting" % signum) @@ -59,6 +59,21 @@ class Server: def start(self, sock, force = False): logSys.info("Starting Fail2ban v" + version.version) + # Install signal handlers + signal.signal(signal.SIGTERM, self.__sigTERMhandler) + signal.signal(signal.SIGINT, self.__sigTERMhandler) + + # First set the mask to only allow access to owner + os.umask(0077) + if self.__daemon: + logSys.info("Starting in daemon mode") + ret = self.__createDaemon() + if ret: + logSys.info("Daemon started") + else: + logSys.error("Could not create daemon") + raise ServerInitializationError("Could not create daemon") + # Creates a PID file. try: logSys.debug("Creating PID file %s" % Server.PID_FILE) @@ -68,19 +83,6 @@ class Server: except IOError, e: logSys.error("Unable to create PID file: %s" % e) - # Install signal handlers - signal.signal(signal.SIGTERM, self.__sigTERMhandler) - signal.signal(signal.SIGINT, self.__sigTERMhandler) - - # First set the mask to only allow access to owner - os.umask(0077) - if self.__daemon: - ret = self.__createDaemon() - if ret: - logSys.info("Daemon started") - else: - logSys.error("Could not create daemon") - raise ServerInitializationError("Could not create daemon") # Start the communication logSys.debug("Starting communication") try: @@ -164,7 +166,8 @@ class Server: self.__jails.getFilter(name).delLogPath(fileName) def getLogPath(self, name): - return self.__jails.getFilter(name).getLogPath() + return [m.getFileName() + for m in self.__jails.getFilter(name).getLogPath()] def setFindTime(self, name, value): self.__jails.getFilter(name).setFindTime(value) @@ -343,7 +346,6 @@ class Server: logSys.error("Unable to log to " + target) logSys.info("Logging to previous target " + self.__logTarget) return False - self.__logTarget = target # Removes previous handlers for handler in logging.getLogger("fail2ban").handlers: # Closes the handler. @@ -352,6 +354,12 @@ class Server: # tell the handler to use this format hdlr.setFormatter(formatter) logging.getLogger("fail2ban").addHandler(hdlr) + # Does not display this message at startup. + if not self.__logTarget == None: + logSys.info("Changed logging target to %s for Fail2ban v%s" % + (target, version.version)) + # Sets the logging target. + self.__logTarget = target return True finally: self.__loggingLock.release() diff --git a/setup.py b/setup.py index d30b6810..c0f6c649 100755 --- a/setup.py +++ b/setup.py @@ -18,11 +18,11 @@ # Author: Cyril Jaquier # -# $Revision: 671 $ +# $Revision: 678 $ __author__ = "Cyril Jaquier" -__version__ = "$Revision: 671 $" -__date__ = "$Date: 2008-03-06 00:12:41 +0100 (Thu, 06 Mar 2008) $" +__version__ = "$Revision: 678 $" +__date__ = "$Date: 2008-03-10 23:34:46 +0100 (Mon, 10 Mar 2008) $" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" @@ -68,6 +68,9 @@ setup( ), ('/etc/fail2ban/action.d', glob("config/action.d/*.conf") + ), + ('/var/run/fail2ban', + '' ) ] )