From 24a8d07c20da396dac0cc2f26f0ab4a14c236cef Mon Sep 17 00:00:00 2001 From: Enrico Labedzki Date: Sun, 28 Apr 2013 10:44:31 +0200 Subject: [PATCH 1/7] added new date format support for ASSP SMTP Proxy --- ChangeLog | 6 ++++-- THANKS | 1 + TODO | 2 ++ config/filter.d/assp.conf | 33 +++++++++++++++++++++++++++++++ config/jail.conf | 7 +++++++ server/datedetector.py | 7 ++++++- server/datetemplate.py | 12 +++++++++++ testcases/datedetectortestcase.py | 1 + testcases/files/logs/assp | 13 ++++++++++++ 9 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 config/filter.d/assp.conf create mode 100644 testcases/files/logs/assp diff --git a/ChangeLog b/ChangeLog index fde414f4..0224431f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,10 +4,10 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ================================================================================ -Fail2Ban (version 0.8.9) 2013/04/XX +Fail2Ban (version 0.8.9) 2013/04/28 ================================================================================ -ver. 0.8.9 (2013/04/XXX) - wanna-be-stable +ver. 0.8.9 (2013/04/28) - wanna-be-stable ---------- Although primarily a bugfix release, it incorporates many new @@ -68,6 +68,8 @@ Borreli, blotus: Soulard Morgan * [f336d9f] Add filter for webmin. Closes gh-99. - Enhancements: + Enrico Labedzki + * [???????] Added Datew format for ASSP SMTP Proxy. Steven Hiscocks * [3d6791f] Ensure restart of Actions after a check fails occurs consistently. Closes gh-172. diff --git a/THANKS b/THANKS index f207d71e..9545d43a 100644 --- a/THANKS +++ b/THANKS @@ -16,6 +16,7 @@ Daniel B. Cid Daniel Black David Nutter Eric Gerbier +Enrico Labedzki Guillaume Delvit Hanno 'Rince' Wagner Iain Lea diff --git a/TODO b/TODO index 61bdc093..33263d3e 100644 --- a/TODO +++ b/TODO @@ -13,6 +13,8 @@ Legend: # partially done * done +- more detailed explaination in DEVELOP for new developers (eg. howto build this HEX numbers in ChangeLog) + - Run tests though all filters/examples files - (see sshd example file) as unit test diff --git a/config/filter.d/assp.conf b/config/filter.d/assp.conf new file mode 100644 index 00000000..055fb9fe --- /dev/null +++ b/config/filter.d/assp.conf @@ -0,0 +1,33 @@ +# Fail2Ban configuration file +# for Anti-Spam SMTP Proxy Server also known as ASSP +# Honmepage: http://www.magicvillage.de/~Fritz_Borgstedt/assp/0003D91C-8000001C/ +# ProjektSite: http://sourceforge.net/projects/assp/?source=directory +# +# Author: Enrico Labedzki (enrico.labedzki@deiwos.de) +# + +[Definition] + +# Option: failregex +# Notes.: regex to match the SMTP failure messages in the logfile. The +# host must be matched by a group named "host". The tag "" can +# be used for standard IP/hostname matching and is only an alias for +# (?:::f{4,6}:)?(?P\S+) +# Values: TEXT +# +# Examples: Apr-27-13 02:33:09 Blocking 217.194.197.97 - too much AUTH errors (41); +# Dec-29-12 17:10:31 [SSL-out] 200.247.87.82 SSL negotiation with client failed: SSL accept attempt failed with unknown errorerror:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol; +# Dec-30-12 04:01:47 [SSL-out] 81.82.232.66 max sender authentication errors (5) exceeded +__assp_actions = (dropping|refusing) + +failregex = max sender authentication errors \(\d+\) exceeded -- %(__assp_actions)s connection - after reply: \d{3} \d{1}\.\d{1}.\d{1} Error: authentication failed: [a-zA-Z0-9]+;$ + SSL negotiation with client failed: SSL accept attempt failed with unknown error.*:unknown protocol;$ + Blocking - too much AUTH errors \(\d+\);$ + + +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# +ignoreregex = + diff --git a/config/jail.conf b/config/jail.conf index 7569cd2f..86425b9c 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -89,6 +89,13 @@ action = iptables[name=sasl, port=smtp, protocol=tcp] sendmail-whois[name=sasl, dest=you@example.com] logpath = /var/log/mail.log +# ASSP SMTP Proxy Jail +[assp] +enabled = false +port = 25,465,587 +filter = assp +logpath = /root/path/to/assp/logs/maillog.txt + # Here we use TCP-Wrappers instead of Netfilter/Iptables. "ignoreregex" is # used to avoid banning the user "myuser". diff --git a/server/datedetector.py b/server/datedetector.py index a54e072d..8ebdc949 100644 --- a/server/datedetector.py +++ b/server/datedetector.py @@ -29,7 +29,7 @@ __license__ = "GPL" import time, logging -from datetemplate import DateStrptime, DateTai64n, DateEpoch, DateISO8601 +from datetemplate import DateStrptime, DateTai64n, DateEpoch, DateISO8601, DateASSPlike from threading import Lock # Gets the instance of the logger. @@ -161,6 +161,11 @@ class DateDetector: template.setRegex("^\d{2}\d{2}\d{2} +\d{1,2}:\d{2}:\d{2}") template.setPattern("%y%m%d %H:%M:%S") self._appendTemplate(template) + # ASSP: Apr-27-13 02:33:06 + template = DateASSPlike() + template.setName("ASSP like date format") + template.setRegex("^[a-zA-Z]{3}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}") + self._appendTemplate(template) finally: self.__lock.release() diff --git a/server/datetemplate.py b/server/datetemplate.py index 51b8bb1e..55f6d7e4 100644 --- a/server/datetemplate.py +++ b/server/datetemplate.py @@ -218,3 +218,15 @@ class DateISO8601(DateTemplate): value = dateMatch.group() date = list(iso8601.parse_date(value).timetuple()) return date + + +class DateASSPlike(DateTemplate): + + def __init__(self): + DateTemplate.__init__(self) + + def getDate(self, line): + # there is no need to parse the date. + # ASSP doesn't buffer the log output. + return MyTime.gmtime() + diff --git a/testcases/datedetectortestcase.py b/testcases/datedetectortestcase.py index 7c3c7140..3bf7bf0f 100644 --- a/testcases/datedetectortestcase.py +++ b/testcases/datedetectortestcase.py @@ -85,6 +85,7 @@ class DateDetectorTest(unittest.TestCase): "2005-01-23T21:59:59-05:00Z", #ISO 8601 with TZ "<01/23/05@21:59:59>", "050123 21:59:59", # MySQL + "Apr-27-13 01:27:45", # ASSP like ): log = sdate + "[sshd] error: PAM: Authentication failure" # exclude diff --git a/testcases/files/logs/assp b/testcases/files/logs/assp new file mode 100644 index 00000000..99363001 --- /dev/null +++ b/testcases/files/logs/assp @@ -0,0 +1,13 @@ +Apr-07-13 07:08:36 [SSL-out] 68.171.223.68 SSL negotiation with client failed: SSL accept attempt failed with unknown errorerror:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol; +Apr-07-13 07:08:36 [SSL-out] 68.171.223.68 SSL negotiation with client failed: SSL accept attempt failed with unknown errorerror:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol; +Apr-07-13 07:10:37 [SSL-out] 68.171.223.68 SSL negotiation with client failed: SSL accept attempt failed with unknown errorerror:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol; +Apr-07-13 07:12:37 [SSL-out] 68.171.223.68 SSL negotiation with client failed: SSL accept attempt failed with unknown errorerror:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol; +Apr-07-13 07:14:36 [SSL-out] 68.171.223.68 SSL negotiation with client failed: SSL accept attempt failed with unknown errorerror:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol; +Apr-27-13 02:25:09 Blocking 217.194.197.97 - too much AUTH errors (8); +Apr-27-13 02:25:09 Blocking 217.194.197.97 - too much AUTH errors (9); +Apr-27-13 02:25:09 Blocking 217.194.197.97 - too much AUTH errors (10); +Apr-27-13 02:25:10 [SSL-out] 217.194.197.97 max sender authentication errors (5) exceeded -- dropping connection - after reply: 535 5.7.8 Error: authentication failed: UGFzc3dvcmQ6; +Apr-27-13 02:25:10 [SSL-out] 217.194.197.97 max sender authentication errors (5) exceeded -- dropping connection - after reply: 535 5.7.8 Error: authentication failed: UGFzc3dvcmQ6; +Apr-27-13 02:25:10 [SSL-out] 217.194.197.97 max sender authentication errors (5) exceeded -- dropping connection - after reply: 535 5.7.8 Error: authentication failed: UGFzc3dvcmQ6; +Apr-27-13 02:25:11 [SSL-out] 217.194.197.97 max sender authentication errors (5) exceeded -- dropping connection - after reply: 535 5.7.8 Error: authentication failed: UGFzc3dvcmQ6; + From ba8f012637b2b6d6ddb211d379dffc4834ff0152 Mon Sep 17 00:00:00 2001 From: Enrico Labedzki Date: Sun, 28 Apr 2013 22:18:55 +0200 Subject: [PATCH 2/7] fixed little things --- ChangeLog | 6 +++--- server/datedetector.py | 1 + server/datetemplate.py | 15 ++++++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0224431f..47f213bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,10 +4,10 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ================================================================================ -Fail2Ban (version 0.8.9) 2013/04/28 +Fail2Ban (version 0.8.9) 2013/04/XX ================================================================================ -ver. 0.8.9 (2013/04/28) - wanna-be-stable +ver. 0.8.9 (2013/04/XX) - wanna-be-stable ---------- Although primarily a bugfix release, it incorporates many new @@ -69,7 +69,7 @@ Borreli, blotus: * [f336d9f] Add filter for webmin. Closes gh-99. - Enhancements: Enrico Labedzki - * [???????] Added Datew format for ASSP SMTP Proxy. + * [1524b07] Added Datew format for ASSP SMTP Proxy. Steven Hiscocks * [3d6791f] Ensure restart of Actions after a check fails occurs consistently. Closes gh-172. diff --git a/server/datedetector.py b/server/datedetector.py index 8ebdc949..33270105 100644 --- a/server/datedetector.py +++ b/server/datedetector.py @@ -165,6 +165,7 @@ class DateDetector: template = DateASSPlike() template.setName("ASSP like date format") template.setRegex("^[a-zA-Z]{3}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}") + template.setPattern("%b-%d-%y %H:%M:%S") self._appendTemplate(template) finally: self.__lock.release() diff --git a/server/datetemplate.py b/server/datetemplate.py index 55f6d7e4..dccd6419 100644 --- a/server/datetemplate.py +++ b/server/datetemplate.py @@ -224,9 +224,18 @@ class DateASSPlike(DateTemplate): def __init__(self): DateTemplate.__init__(self) + self.__pattern = "" + + def setPattern(self, pattern): + self.__pattern = pattern.strip() + + def getPattern(self): + return self.__pattern def getDate(self, line): - # there is no need to parse the date. - # ASSP doesn't buffer the log output. - return MyTime.gmtime() + date = None + dateMatch = self.matchDate(line) + if dateMatch: + date = list(time.strptime(dateMatch.group(), self.getPattern())) + return date From 9185c070ebdf8d0c20a8ec0868c0092ce0996338 Mon Sep 17 00:00:00 2001 From: Enrico Labedzki Date: Wed, 1 May 2013 02:25:05 +0200 Subject: [PATCH 3/7] changed from DateASSPlike class to DateStrptime --- server/datedetector.py | 6 +++--- server/datetemplate.py | 19 ------------------- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/server/datedetector.py b/server/datedetector.py index 33270105..8ece81fb 100644 --- a/server/datedetector.py +++ b/server/datedetector.py @@ -29,7 +29,7 @@ __license__ = "GPL" import time, logging -from datetemplate import DateStrptime, DateTai64n, DateEpoch, DateISO8601, DateASSPlike +from datetemplate import DateStrptime, DateTai64n, DateEpoch, DateISO8601 from threading import Lock # Gets the instance of the logger. @@ -162,8 +162,8 @@ class DateDetector: template.setPattern("%y%m%d %H:%M:%S") self._appendTemplate(template) # ASSP: Apr-27-13 02:33:06 - template = DateASSPlike() - template.setName("ASSP like date format") + template = DateStrptime() + template.setName("Month-Day-Year Hour:Minute:Second") template.setRegex("^[a-zA-Z]{3}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}") template.setPattern("%b-%d-%y %H:%M:%S") self._appendTemplate(template) diff --git a/server/datetemplate.py b/server/datetemplate.py index dccd6419..01492755 100644 --- a/server/datetemplate.py +++ b/server/datetemplate.py @@ -220,22 +220,3 @@ class DateISO8601(DateTemplate): return date -class DateASSPlike(DateTemplate): - - def __init__(self): - DateTemplate.__init__(self) - self.__pattern = "" - - def setPattern(self, pattern): - self.__pattern = pattern.strip() - - def getPattern(self): - return self.__pattern - - def getDate(self, line): - date = None - dateMatch = self.matchDate(line) - if dateMatch: - date = list(time.strptime(dateMatch.group(), self.getPattern())) - return date - From 07aee8cd335f56b43f65188815fd98d94254c4fa Mon Sep 17 00:00:00 2001 From: Enrico Labedzki Date: Wed, 1 May 2013 02:35:46 +0200 Subject: [PATCH 4/7] as daniel desires --- config/jail.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/jail.conf b/config/jail.conf index 86425b9c..8b82d1d7 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -92,8 +92,8 @@ logpath = /var/log/mail.log # ASSP SMTP Proxy Jail [assp] enabled = false -port = 25,465,587 filter = assp +action = iptables-multiport[name=assp,port="25,465,587"] logpath = /root/path/to/assp/logs/maillog.txt # Here we use TCP-Wrappers instead of Netfilter/Iptables. "ignoreregex" is From e27385e87304951478d3b3c88dafc1a7a593f838 Mon Sep 17 00:00:00 2001 From: Enrico Labedzki Date: Wed, 1 May 2013 03:42:13 +0200 Subject: [PATCH 5/7] as yaroslav wishes --- server/datetemplate.py | 1 - 1 file changed, 1 deletion(-) diff --git a/server/datetemplate.py b/server/datetemplate.py index 01492755..d404cf68 100644 --- a/server/datetemplate.py +++ b/server/datetemplate.py @@ -219,4 +219,3 @@ class DateISO8601(DateTemplate): date = list(iso8601.parse_date(value).timetuple()) return date - From 36b0d78ff88aa9d4558fd24d9ea1859d8063c3e7 Mon Sep 17 00:00:00 2001 From: Enrico Labedzki Date: Wed, 1 May 2013 04:51:56 +0200 Subject: [PATCH 6/7] tight control of the filter for ASSP --- config/filter.d/assp.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/filter.d/assp.conf b/config/filter.d/assp.conf index 055fb9fe..b1bfc082 100644 --- a/config/filter.d/assp.conf +++ b/config/filter.d/assp.conf @@ -20,9 +20,9 @@ # Dec-30-12 04:01:47 [SSL-out] 81.82.232.66 max sender authentication errors (5) exceeded __assp_actions = (dropping|refusing) -failregex = max sender authentication errors \(\d+\) exceeded -- %(__assp_actions)s connection - after reply: \d{3} \d{1}\.\d{1}.\d{1} Error: authentication failed: [a-zA-Z0-9]+;$ +failregex = max sender authentication errors \(\d{,3}\) exceeded -- %(__assp_actions)s connection - after reply: \d{3} \d{1}\.\d{1}.\d{1} Error: authentication failed: [a-zA-Z0-9]+;$ SSL negotiation with client failed: SSL accept attempt failed with unknown error.*:unknown protocol;$ - Blocking - too much AUTH errors \(\d+\);$ + Blocking - too much AUTH errors \(\d{,3}\);$ # Option: ignoreregex From fd01649a61065b41abc8490a4c04074e36ee7c13 Mon Sep 17 00:00:00 2001 From: Enrico Labedzki Date: Thu, 2 May 2013 06:19:39 +0200 Subject: [PATCH 7/7] fixed test date thx to steven --- testcases/datedetectortestcase.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcases/datedetectortestcase.py b/testcases/datedetectortestcase.py index 3bf7bf0f..a3d90f22 100644 --- a/testcases/datedetectortestcase.py +++ b/testcases/datedetectortestcase.py @@ -85,7 +85,7 @@ class DateDetectorTest(unittest.TestCase): "2005-01-23T21:59:59-05:00Z", #ISO 8601 with TZ "<01/23/05@21:59:59>", "050123 21:59:59", # MySQL - "Apr-27-13 01:27:45", # ASSP like + "Jan-23-05 21:59:59", # ASSP like ): log = sdate + "[sshd] error: PAM: Authentication failure" # exclude