From a1eaa5f75567698470da5d22b85ad6d3b7123ba4 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 1 Oct 2013 09:59:15 +1000 Subject: [PATCH 001/165] ENH: filter.d/selinxu added. Closes #296 --- ChangeLog | 2 ++ config/filter.d/selinux.conf | 19 +++++++++++++++++++ testcases/files/logs/selinux | 23 +++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 config/filter.d/selinux.conf create mode 100644 testcases/files/logs/selinux diff --git a/ChangeLog b/ChangeLog index 324b6ec2..d5ee9459 100644 --- a/ChangeLog +++ b/ChangeLog @@ -64,6 +64,8 @@ ver. 0.8.11 (2013/XX/XXX) - loves-unittests * filter.d/perdition.conf -- filter added Mark McKinstry * action.d/apf.conf - add action for Advanced Policy Firewall (apf) + Steven Hiscocks and Daniel Black + * filter.d/selinux -- add SELinux date and filter - Enhancements: François Boulogne and Frédéric diff --git a/config/filter.d/selinux.conf b/config/filter.d/selinux.conf new file mode 100644 index 00000000..3a6a0a50 --- /dev/null +++ b/config/filter.d/selinux.conf @@ -0,0 +1,19 @@ +# Fail2Ban configuration file for generic Selinux Errors authentication errors +# +# Author: Daniel Black +# +# +[Definition] + +_type = USER_(LOGIN|ERR|AUTH) +_uid = 0 +_auid = \d+ +_subj = (?:unconfined_u|system_u):system_r:sshd_t:s0-s0:c0\.c1023 + +_exe =/usr/sbin/sshd +_terminal = ssh + +_msg = op=\S+ acct=(?P<_quote_acct>"?)\S+(?P=_quote_acct) exe="%(_exe)s" hostname=(\?|(\d+\.){3}\d+) addr= terminal=%(_terminal)s res=failed + +failregex = ^type=%(_type)s msg=audit\(:\d+\): user pid=\d+ uid=%(_uid)s auid=%(_auid)s ses=\d+ subj=%(_subj)s msg='%(_msg)s'$ + diff --git a/testcases/files/logs/selinux b/testcases/files/logs/selinux new file mode 100644 index 00000000..c6cdfe15 --- /dev/null +++ b/testcases/files/logs/selinux @@ -0,0 +1,23 @@ +# failJSON: { "time": "2013-07-09T02:45:16", "match": true , "host": "173.242.116.187" } +type=USER_LOGIN msg=audit(1373330716.415:4063): user pid=11998 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=login acct="root" exe="/usr/sbin/sshd" hostname=? addr=173.242.116.187 terminal=ssh res=failed' + +# failJSON: { "time": "2013-07-09T02:45:17", "match": true , "host": "173.242.116.187" } +type=USER_LOGIN msg=audit(1373330717.441:4068): user pid=12000 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=login acct=28756E6B6E6F776E207573657229 exe="/usr/sbin/sshd" hostname=? addr=173.242.116.187 terminal=ssh res=failed' + +# failJSON: { "time": "2013-07-09T02:45:17", "match": true , "host": "173.242.116.187" } +type=USER_ERR msg=audit(1373330717.575:4070): user pid=12000 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=PAM:bad_ident acct="?" exe="/usr/sbin/sshd" hostname=173.242.116.187 addr=173.242.116.187 terminal=ssh res=failed' + +# failJSON: { "time": "2013-07-09T02:45:17", "match": true , "host": "173.242.116.187" } +type=USER_LOGIN msg=audit(1373330717.576:4073): user pid=12000 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=login acct=28696E76616C6964207573657229 exe="/usr/sbin/sshd" hostname=? addr=173.242.116.187 terminal=ssh res=failed' + +# failJSON: { "time": "2013-06-30T01:02:08", "match": true , "host": "113.240.248.18" } +type=USER_LOGIN msg=audit(1372546928.726:52008): user pid=21569 uid=0 auid=0 ses=76 subj=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=login acct="sshd" exe="/usr/sbin/sshd" hostname=? addr=113.240.248.18 terminal=ssh res=failed' + +# failJSON: { "time": "2013-06-30T03:58:20", "match": true , "host": "113.240.248.18" } +type=USER_ERR msg=audit(1372557500.401:61747): user pid=23684 uid=0 auid=0 ses=76 subj=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=PAM:bad_ident acct="?" exe="/usr/sbin/sshd" hostname=113.240.248.18 addr=113.240.248.18 terminal=ssh res=failed' + +# failJSON: { "time": "2013-06-30T03:58:20", "match": true , "host": "113.240.248.18" } +type=USER_LOGIN msg=audit(1372557500.402:61750): user pid=23684 uid=0 auid=0 ses=76 subj=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=login acct=28696E76616C6964207573657229 exe="/usr/sbin/sshd" hostname=? addr=113.240.248.18 terminal=ssh res=failed' + +# failJSON: { "time": "2013-07-06T18:48:00", "match": true , "host": "194.228.20.113" } +type=USER_AUTH msg=audit(1373129280.772:9): user pid=1277 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=pubkey acct="root" exe="/usr/sbin/sshd" hostname=? addr=194.228.20.113 terminal=ssh res=failed' From 4649cf960860354246ca5c397651b2b7437545bf Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 1 Oct 2013 20:21:45 +1000 Subject: [PATCH 002/165] ENH: separate selinux and selinux-ssh --- config/filter.d/selinux-ssh.conf | 21 +++++++++++++++++++ config/filter.d/selinux.conf | 19 ++++++++--------- testcases/files/logs/{selinux => selinux-ssh} | 0 testcases/samplestestcase.py | 7 ++++++- 4 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 config/filter.d/selinux-ssh.conf rename testcases/files/logs/{selinux => selinux-ssh} (100%) diff --git a/config/filter.d/selinux-ssh.conf b/config/filter.d/selinux-ssh.conf new file mode 100644 index 00000000..34bf65ab --- /dev/null +++ b/config/filter.d/selinux-ssh.conf @@ -0,0 +1,21 @@ +# Fail2Ban configuration file for SELinux ssh authentication errors +# +# Author: Daniel Black +# +# +[INCLUDES] + +after = selinux.conf + +[Definition] + +_type = USER_(LOGIN|ERR|AUTH) +_uid = 0 +_auid = \d+ +_subj = (?:unconfined_u|system_u):system_r:sshd_t:s0-s0:c0\.c1023 + +_exe =/usr/sbin/sshd +_terminal = ssh + +_msg = op=\S+ acct=(?P<_quote_acct>"?)\S+(?P=_quote_acct) exe="%(_exe)s" hostname=(\?|(\d+\.){3}\d+) addr= terminal=%(_terminal)s res=failed + diff --git a/config/filter.d/selinux.conf b/config/filter.d/selinux.conf index 3a6a0a50..143be189 100644 --- a/config/filter.d/selinux.conf +++ b/config/filter.d/selinux.conf @@ -1,19 +1,18 @@ -# Fail2Ban configuration file for generic Selinux Errors authentication errors +# Fail2Ban configuration file for generic SELinux audit messages # # Author: Daniel Black # # [Definition] -_type = USER_(LOGIN|ERR|AUTH) -_uid = 0 -_auid = \d+ -_subj = (?:unconfined_u|system_u):system_r:sshd_t:s0-s0:c0\.c1023 - -_exe =/usr/sbin/sshd -_terminal = ssh - -_msg = op=\S+ acct=(?P<_quote_acct>"?)\S+(?P=_quote_acct) exe="%(_exe)s" hostname=(\?|(\d+\.){3}\d+) addr= terminal=%(_terminal)s res=failed +# Things you must set before including this file. See selinux-ssh as an example. +# One of these must include a . +# +# _type +# _uid +# _auid +# _subj +# _msg failregex = ^type=%(_type)s msg=audit\(:\d+\): user pid=\d+ uid=%(_uid)s auid=%(_auid)s ses=\d+ subj=%(_subj)s msg='%(_msg)s'$ diff --git a/testcases/files/logs/selinux b/testcases/files/logs/selinux-ssh similarity index 100% rename from testcases/files/logs/selinux rename to testcases/files/logs/selinux-ssh diff --git a/testcases/samplestestcase.py b/testcases/samplestestcase.py index c7ff0b9a..35abb813 100644 --- a/testcases/samplestestcase.py +++ b/testcases/samplestestcase.py @@ -23,6 +23,7 @@ __copyright__ = "Copyright (c) 2013 Steven Hiscocks" __license__ = "GPL" import unittest, sys, os, fileinput, re, datetime, inspect +from ConfigParser import InterpolationMissingOptionError if sys.version_info >= (2, 6): import json @@ -60,7 +61,11 @@ def testSampleRegexsFactory(name): # Check filter exists filterConf = FilterReader(name, "jail", basedir=CONFIG_DIR) filterConf.read() - filterConf.getOptions({}) + try: + filterConf.getOptions({}) + except InterpolationMissingOptionError: + # some filters like selinux aren't complete + return for opt in filterConf.convert(): if opt[2] == "addfailregex": From 88d8111db1e054377d7088737585c934e730acaf Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 22 Oct 2013 23:18:10 +1100 Subject: [PATCH 003/165] DOC: changelog for selinux-ssh too --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d5ee9459..4d75213f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -65,7 +65,7 @@ ver. 0.8.11 (2013/XX/XXX) - loves-unittests Mark McKinstry * action.d/apf.conf - add action for Advanced Policy Firewall (apf) Steven Hiscocks and Daniel Black - * filter.d/selinux -- add SELinux date and filter + * filter.d/selinux{,-ssh} -- add SELinux date and filter - Enhancements: François Boulogne and Frédéric From 2b3e866f5f78ba791765de925238784c0113c5b6 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 22 Oct 2013 23:25:43 +1100 Subject: [PATCH 004/165] BF: log errors to syslog and respect the showRet parameter --- fail2ban-client | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fail2ban-client b/fail2ban-client index c18b7d55..1237680b 100755 --- a/fail2ban-client +++ b/fail2ban-client @@ -155,8 +155,9 @@ class Fail2banClient: if showRet: print beautifier.beautify(ret[1]) else: - logSys.debug("NOK: " + `ret[1].args`) - print beautifier.beautifyError(ret[1]) + logSys.error("NOK: " + `ret[1].args`) + if showRet: + print beautifier.beautifyError(ret[1]) return False except socket.error: if showRet: From 7e1482536fcd1f6c00a521b65b891c74a5bdcf03 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 23 Oct 2013 21:39:11 +1100 Subject: [PATCH 005/165] PKG: sasl -> postfix-sasl in Manifest --- MANIFEST | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MANIFEST b/MANIFEST index 768d0ae0..f5bdcab3 100644 --- a/MANIFEST +++ b/MANIFEST @@ -76,7 +76,7 @@ testcases/files/logs/postfix testcases/files/logs/proftpd testcases/files/logs/pure-ftpd testcases/files/logs/roundcube-auth -testcases/files/logs/sasl +testcases/files/logs/postfix-sasl testcases/files/logs/sogo-auth testcases/files/logs/sshd testcases/files/logs/sshd-ddos @@ -162,7 +162,7 @@ config/filter.d/pure-ftpd.conf config/filter.d/qmail.conf config/filter.d/pam-generic.conf config/filter.d/php-url-fopen.conf -config/filter.d/sasl.conf +config/filter.d/postfix-sasl.conf config/filter.d/sieve.conf config/filter.d/sshd.conf config/filter.d/sshd-ddos.conf From 7d23c2c24cd61af67604de14373fb80045126a84 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 23 Oct 2013 21:43:03 +1100 Subject: [PATCH 006/165] DOC: simpler diff for MANIFEST examination --- DEVELOP | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/DEVELOP b/DEVELOP index 6e5e0b4c..51314078 100644 --- a/DEVELOP +++ b/DEVELOP @@ -703,9 +703,7 @@ Which indicates that testcases/files/logs/mysqld.log has been moved or is a dire # clean up current direcory - find . -name \*.pyc -exec rm {} \; - - diff -rul . /tmp/fail2ban-0.8.10.dev/ + diff -rul --exclude \*.pyc . /tmp/fail2ban-0.8.10.dev/ # Only differences should be files that you don't want distributed. From 2782edce7435a6c37cbc2e80831e0c9317ef2401 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 23 Oct 2013 21:43:17 +1100 Subject: [PATCH 007/165] PKG: missing actions --- MANIFEST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MANIFEST b/MANIFEST index f5bdcab3..8db7d09f 100644 --- a/MANIFEST +++ b/MANIFEST @@ -181,6 +181,8 @@ config/filter.d/mysqld-auth.conf config/filter.d/sogo-auth.conf config/action.d/bsd-ipfw.conf config/action.d/dummy.conf +config/action.d/firewall-cmd-direct-new.conf +config/action.d/iptables-ipset-proto6-allports.conf config/action.d/iptables-blocktype.conf config/action.d/iptables-ipset-proto4.conf config/action.d/iptables-ipset-proto6.conf From d451c2a231df3d2ae8fd6a1f3c4315e95db4271a Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 26 Oct 2013 09:51:25 +1100 Subject: [PATCH 008/165] FIX: vsftp improvements from Rich Mellor on mailing list --- ChangeLog | 2 ++ config/filter.d/vsftpd.conf | 2 +- testcases/files/logs/vsftpd | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bbad4e89..e98bcaa6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -47,6 +47,8 @@ ver. 0.8.11 (2013/XX/XXX) - loves-unittests * files/redhat-initd - rewritten to use stock init.d functions thus avoiding problems with getpid. Also $network and iptables moved to Should- rc init fields + Rick Mellor + * filter.d/vsftp - fix capture with tty=ftp - New Features: Edgar Hoch diff --git a/config/filter.d/vsftpd.conf b/config/filter.d/vsftpd.conf index 661fbb61..e72b89eb 100644 --- a/config/filter.d/vsftpd.conf +++ b/config/filter.d/vsftpd.conf @@ -20,7 +20,7 @@ _daemon = vsftpd # (?:::f{4,6}:)?(?P[\w\-.^_]+) # Values: TEXT # -failregex = ^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty= ruser=\S* rhost=(?:\s+user=.*)?\s*$ +failregex = ^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=(ftp)? ruser=\S* rhost=(?:\s+user=.*)?\s*$ ^ \[pid \d+\] \[.+\] FAIL LOGIN: Client ""\s*$ # Option: ignoreregex diff --git a/testcases/files/logs/vsftpd b/testcases/files/logs/vsftpd index 4be6a8f8..bcd7f611 100644 --- a/testcases/files/logs/vsftpd +++ b/testcases/files/logs/vsftpd @@ -10,3 +10,5 @@ Feb 6 12:02:29 server vsftpd(pam_unix)[15522]: authentication failure; logname= # failJSON: { "time": "2007-01-19T12:20:33", "match": true , "host": "64.106.46.98" } Fri Jan 19 12:20:33 2007 [pid 27202] [anonymous] FAIL LOGIN: Client "64.106.46.98" +# failJSON: { "time": "2004-10-23T21:15:42", "match": true , "host": "58.254.172.161" } +Oct 23 21:15:42 vps vsftpd: pam_unix(vsftpd:auth): authentication failure; logname= uid=0 euid=0 tty=ftp ruser=test rhost=58.254.172.161 From 0c1470720113873b39a31860f6b7fc7c2f62be9c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 26 Oct 2013 10:01:04 +1100 Subject: [PATCH 009/165] ENH: add dovecot jail --- config/jail.conf | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/config/jail.conf b/config/jail.conf index 594dfc3b..c30b50e8 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -472,5 +472,9 @@ filter = webmin-auth action = iptables-multiport[name=webmin,port="10000"] logpath = /var/log/auth.log - +[dovecot] +enabled = false +filter = dovecot +action = iptables-multiport[name=dovecot, port="pop3,pop3s,imap,imaps", protocol=tcp] +logpath = /var/log/secure From cde389cadc8473c14b17b927bdaa3a85704d2d84 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 29 Oct 2013 10:15:54 +1100 Subject: [PATCH 010/165] ENH: additional tweek to dovecot regex based on http://chrisgilligan.com/portfolio/fail2ban-regex/ --- config/filter.d/dovecot.conf | 2 +- testcases/files/logs/dovecot | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/config/filter.d/dovecot.conf b/config/filter.d/dovecot.conf index 51c28af4..dd0e7678 100644 --- a/config/filter.d/dovecot.conf +++ b/config/filter.d/dovecot.conf @@ -9,7 +9,7 @@ before = common.conf [Definition] -_daemon = (dovecot(-auth)?|auth-worker) +_daemon = (auth|dovecot(-auth)?|auth-worker) # Option: failregex # Notes.: regex to match the password failures messages in the logfile. # first regex is essentially a copy of pam-generic.conf diff --git a/testcases/files/logs/dovecot b/testcases/files/logs/dovecot index 733552df..80313b75 100644 --- a/testcases/files/logs/dovecot +++ b/testcases/files/logs/dovecot @@ -35,3 +35,7 @@ Jul 02 13:49:32 hostname dovecot[442]: dovecot: auth(default): pam(account@MYSER # failJSON: { "time": "2013-08-11T03:56:40", "match": true , "host": "1.2.3.4" } 2013-08-11 03:56:40 auth-worker(default): Info: pam(username,1.2.3.4): pam_authenticate() failed: Authentication failure (password mismatch?) + +# failJSON: { "time": "2005-05-19T05:22:20", "match": true , "host": "80.255.3.104" } +Apr 19 05:22:20 vm5 auth: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=informix rhost=80.255.3.104 + From 8412303131235aafb2405824323b1534deb5f85c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 29 Oct 2013 10:17:45 +1100 Subject: [PATCH 011/165] ENH: dovecot jail examples --- config/jail.conf | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/config/jail.conf b/config/jail.conf index c30b50e8..60bb23c6 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -472,9 +472,16 @@ filter = webmin-auth action = iptables-multiport[name=webmin,port="10000"] logpath = /var/log/auth.log +# dovecot defaults to logging to the mail syslog facility +# but can be set by syslog_facility in the dovecot configuration. [dovecot] enabled = false filter = dovecot action = iptables-multiport[name=dovecot, port="pop3,pop3s,imap,imaps", protocol=tcp] -logpath = /var/log/secure +logpath = /var/log/mail.log +[dovecot-auth] +enabled = false +filter = dovecot +action = iptables-multiport[name=dovecot-auth, port="pop3,pop3s,imap,imaps", protocol=tcp] +logpath = /var/log/secure From a991adb83f7197e537a5d1b9242470a5c2729416 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 29 Oct 2013 14:33:45 +1100 Subject: [PATCH 012/165] ENH: add submission, smtps and sieve to blocked ports since this also typically rely on dovecot auth --- config/jail.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/jail.conf b/config/jail.conf index 60bb23c6..1154cb52 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -477,11 +477,11 @@ logpath = /var/log/auth.log [dovecot] enabled = false filter = dovecot -action = iptables-multiport[name=dovecot, port="pop3,pop3s,imap,imaps", protocol=tcp] +action = iptables-multiport[name=dovecot, port="pop3,pop3s,imap,imaps,submission,smtps,sieve", protocol=tcp] logpath = /var/log/mail.log [dovecot-auth] enabled = false filter = dovecot -action = iptables-multiport[name=dovecot-auth, port="pop3,pop3s,imap,imaps", protocol=tcp] +action = iptables-multiport[name=dovecot-auth, port="pop3,pop3s,imap,imaps,submission,smtps,sieve", protocol=tcp] logpath = /var/log/secure From 7596b96d4f3e04e1d1b07d16eaaeb2e5fa009862 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 30 Oct 2013 09:05:09 +1100 Subject: [PATCH 013/165] TST: fix date in test comparison for dovecot --- testcases/files/logs/dovecot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcases/files/logs/dovecot b/testcases/files/logs/dovecot index 80313b75..d2aa59ca 100644 --- a/testcases/files/logs/dovecot +++ b/testcases/files/logs/dovecot @@ -36,6 +36,6 @@ Jul 02 13:49:32 hostname dovecot[442]: dovecot: auth(default): pam(account@MYSER # failJSON: { "time": "2013-08-11T03:56:40", "match": true , "host": "1.2.3.4" } 2013-08-11 03:56:40 auth-worker(default): Info: pam(username,1.2.3.4): pam_authenticate() failed: Authentication failure (password mismatch?) -# failJSON: { "time": "2005-05-19T05:22:20", "match": true , "host": "80.255.3.104" } +# failJSON: { "time": "2005-04-19T05:22:20", "match": true , "host": "80.255.3.104" } Apr 19 05:22:20 vm5 auth: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=informix rhost=80.255.3.104 From e3150044fd17f2cd96094ba3e4587e91cf7235f9 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 30 Oct 2013 20:05:49 +1100 Subject: [PATCH 014/165] BF: fix selinux TST: ignore *common.conf files in test cases as these are included BF: Remove USER_LOGIN from selinux-ssh as its a duplicate message ENH: add sample jail.conf --- ChangeLog | 2 +- config/filter.d/selinux-common.conf | 21 +++++++++++++++++++++ config/filter.d/selinux-ssh.conf | 7 +++++-- config/filter.d/selinux.conf | 18 ------------------ config/jail.conf | 6 ++++++ testcases/files/logs/selinux-ssh | 16 +++++++++++----- testcases/samplestestcase.py | 8 ++------ 7 files changed, 46 insertions(+), 32 deletions(-) create mode 100644 config/filter.d/selinux-common.conf delete mode 100644 config/filter.d/selinux.conf diff --git a/ChangeLog b/ChangeLog index 4d75213f..1979096b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -65,7 +65,7 @@ ver. 0.8.11 (2013/XX/XXX) - loves-unittests Mark McKinstry * action.d/apf.conf - add action for Advanced Policy Firewall (apf) Steven Hiscocks and Daniel Black - * filter.d/selinux{,-ssh} -- add SELinux date and filter + * filter.d/selinux-{common,ssh} -- add SELinux date and ssh filter - Enhancements: François Boulogne and Frédéric diff --git a/config/filter.d/selinux-common.conf b/config/filter.d/selinux-common.conf new file mode 100644 index 00000000..333b43f2 --- /dev/null +++ b/config/filter.d/selinux-common.conf @@ -0,0 +1,21 @@ +# Fail2Ban configuration file for generic SELinux audit messages +# +# Author: Daniel Black +# +# This file is not intended to be used directly, and should be included into a +# filter file which would define following variables. See selinux-ssh.conf as +# and example. +# +# _type +# _uid +# _auid +# _subj +# _msg +# +# Also one of these variables must include . +# +[Definition] + +failregex = ^type=%(_type)s msg=audit\(:\d+\): (user )?pid=\d+ uid=%(_uid)s auid=%(_auid)s ses=\d+ subj=%(_subj)s msg='%(_msg)s'$ + +ignoreregex = diff --git a/config/filter.d/selinux-ssh.conf b/config/filter.d/selinux-ssh.conf index 34bf65ab..6e563a13 100644 --- a/config/filter.d/selinux-ssh.conf +++ b/config/filter.d/selinux-ssh.conf @@ -3,13 +3,16 @@ # Author: Daniel Black # # +# Note: USER_LOGIN is ignored as this is the duplicate messsage +# ssh logs after 3 USER_AUTH failures. +# [INCLUDES] -after = selinux.conf +after = selinux-common.conf [Definition] -_type = USER_(LOGIN|ERR|AUTH) +_type = USER_(ERR|AUTH) _uid = 0 _auid = \d+ _subj = (?:unconfined_u|system_u):system_r:sshd_t:s0-s0:c0\.c1023 diff --git a/config/filter.d/selinux.conf b/config/filter.d/selinux.conf deleted file mode 100644 index 143be189..00000000 --- a/config/filter.d/selinux.conf +++ /dev/null @@ -1,18 +0,0 @@ -# Fail2Ban configuration file for generic SELinux audit messages -# -# Author: Daniel Black -# -# -[Definition] - -# Things you must set before including this file. See selinux-ssh as an example. -# One of these must include a . -# -# _type -# _uid -# _auid -# _subj -# _msg - -failregex = ^type=%(_type)s msg=audit\(:\d+\): user pid=\d+ uid=%(_uid)s auid=%(_auid)s ses=\d+ subj=%(_subj)s msg='%(_msg)s'$ - diff --git a/config/jail.conf b/config/jail.conf index 4878122f..325229cb 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -433,3 +433,9 @@ enabled = false filter = sshd action = osx-afctl[bantime=600] logpath = /var/log/secure.log + +[selinux-ssh] +enabled = false +filter = selinux-ssh +action = iptables[name=SELINUX-SSH, port=ssh, protocol=tcp] +logpath = /var/log/audit/audit.log diff --git a/testcases/files/logs/selinux-ssh b/testcases/files/logs/selinux-ssh index c6cdfe15..ed43c411 100644 --- a/testcases/files/logs/selinux-ssh +++ b/testcases/files/logs/selinux-ssh @@ -1,23 +1,29 @@ -# failJSON: { "time": "2013-07-09T02:45:16", "match": true , "host": "173.242.116.187" } +# failJSON: { "time": "2013-07-09T02:45:16", "match": false , "host": "173.242.116.187" } type=USER_LOGIN msg=audit(1373330716.415:4063): user pid=11998 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=login acct="root" exe="/usr/sbin/sshd" hostname=? addr=173.242.116.187 terminal=ssh res=failed' -# failJSON: { "time": "2013-07-09T02:45:17", "match": true , "host": "173.242.116.187" } +# failJSON: { "time": "2013-07-09T02:45:17", "match": false , "host": "173.242.116.187" } type=USER_LOGIN msg=audit(1373330717.441:4068): user pid=12000 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=login acct=28756E6B6E6F776E207573657229 exe="/usr/sbin/sshd" hostname=? addr=173.242.116.187 terminal=ssh res=failed' # failJSON: { "time": "2013-07-09T02:45:17", "match": true , "host": "173.242.116.187" } type=USER_ERR msg=audit(1373330717.575:4070): user pid=12000 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=PAM:bad_ident acct="?" exe="/usr/sbin/sshd" hostname=173.242.116.187 addr=173.242.116.187 terminal=ssh res=failed' -# failJSON: { "time": "2013-07-09T02:45:17", "match": true , "host": "173.242.116.187" } +# failJSON: { "time": "2013-07-09T02:45:17", "match": false , "host": "173.242.116.187" } type=USER_LOGIN msg=audit(1373330717.576:4073): user pid=12000 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=login acct=28696E76616C6964207573657229 exe="/usr/sbin/sshd" hostname=? addr=173.242.116.187 terminal=ssh res=failed' -# failJSON: { "time": "2013-06-30T01:02:08", "match": true , "host": "113.240.248.18" } +# failJSON: { "time": "2013-06-30T01:02:08", "match": false , "host": "113.240.248.18" } type=USER_LOGIN msg=audit(1372546928.726:52008): user pid=21569 uid=0 auid=0 ses=76 subj=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=login acct="sshd" exe="/usr/sbin/sshd" hostname=? addr=113.240.248.18 terminal=ssh res=failed' # failJSON: { "time": "2013-06-30T03:58:20", "match": true , "host": "113.240.248.18" } type=USER_ERR msg=audit(1372557500.401:61747): user pid=23684 uid=0 auid=0 ses=76 subj=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=PAM:bad_ident acct="?" exe="/usr/sbin/sshd" hostname=113.240.248.18 addr=113.240.248.18 terminal=ssh res=failed' -# failJSON: { "time": "2013-06-30T03:58:20", "match": true , "host": "113.240.248.18" } +# failJSON: { "time": "2013-06-30T03:58:20", "match": false , "host": "113.240.248.18" } type=USER_LOGIN msg=audit(1372557500.402:61750): user pid=23684 uid=0 auid=0 ses=76 subj=unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=login acct=28696E76616C6964207573657229 exe="/usr/sbin/sshd" hostname=? addr=113.240.248.18 terminal=ssh res=failed' # failJSON: { "time": "2013-07-06T18:48:00", "match": true , "host": "194.228.20.113" } type=USER_AUTH msg=audit(1373129280.772:9): user pid=1277 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=pubkey acct="root" exe="/usr/sbin/sshd" hostname=? addr=194.228.20.113 terminal=ssh res=failed' + +# failJSON: { "time": "2013-10-30T07:57:43", "match": true , "host": "192.168.3.100" } +type=USER_AUTH msg=audit(1383116263.930:603): pid=12887 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=password acct="dan" exe="/usr/sbin/sshd" hostname=? addr=192.168.3.100 terminal=ssh res=failed' + +# failJSON: { "time": "2013-10-30T07:54:08", "match": false , "host": "192.168.3.100" } +type=USER_LOGIN msg=audit(1383116048.450:595): pid=12354 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:sshd_t:s0-s0:c0.c1023 msg='op=login acct="dan" exe="/usr/sbin/sshd" hostname=? addr=192.168.3.100 terminal=ssh res=failed' diff --git a/testcases/samplestestcase.py b/testcases/samplestestcase.py index 35abb813..15f9ee0f 100644 --- a/testcases/samplestestcase.py +++ b/testcases/samplestestcase.py @@ -61,11 +61,7 @@ def testSampleRegexsFactory(name): # Check filter exists filterConf = FilterReader(name, "jail", basedir=CONFIG_DIR) filterConf.read() - try: - filterConf.getOptions({}) - except InterpolationMissingOptionError: - # some filters like selinux aren't complete - return + filterConf.getOptions({}) for opt in filterConf.convert(): if opt[2] == "addfailregex": @@ -136,7 +132,7 @@ def testSampleRegexsFactory(name): return testFilter -for filter_ in os.listdir(os.path.join(CONFIG_DIR, "filter.d")): +for filter_ in filter(lambda x: not x.endswith('common.conf'), os.listdir(os.path.join(CONFIG_DIR, "filter.d"))): filterName = filter_.rpartition(".")[0] setattr( FilterSamplesRegex, From c7b6d789ca87a07fcda3c97141e9a601300e5631 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 30 Oct 2013 20:16:22 +1100 Subject: [PATCH 015/165] DOC: add ChangeLog for #392 --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index e98bcaa6..bd668a71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -76,6 +76,8 @@ ver. 0.8.11 (2013/XX/XXX) - loves-unittests François Boulogne and Frédéric * filter.d/lighttpd - auth regexs for lighttpd-1.4.31 Daniel Black + * reorder parsing of jail.conf, jail.d/*.conf, jail.local, jail.d/*.local + and likewise for fail2ban.{conf|local|d/*.conf|d/*.local}. Closes gh-392 * jail.conf now has asterisk jail - no need for asterisk-tcp and asterisk-udp. Users should replace existing jails with asterisk to reduce duplicate parsing of the asterisk log file. From 7ab909d0565adf85a7af9782cf8f8f82964e13a9 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 30 Oct 2013 20:34:06 +1100 Subject: [PATCH 016/165] DOC: space out jail.conf consistantly --- config/jail.conf | 120 +++++++++++++++++++++++++++++++---------------- 1 file changed, 80 insertions(+), 40 deletions(-) diff --git a/config/jail.conf b/config/jail.conf index 670922cc..89c1ce73 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -87,8 +87,8 @@ action = iptables[name=ProFTPD, port=ftp, protocol=tcp] logpath = /var/log/proftpd/proftpd.log maxretry = 6 -# This jail forces the backend to "polling". +# This jail forces the backend to "polling". [sasl-iptables] enabled = false @@ -98,16 +98,18 @@ 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 -filter = assp -action = iptables-multiport[name=assp,port="25,465,587"] -logpath = /root/path/to/assp/logs/maillog.txt + +enabled = false +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 # used to avoid banning the user "myuser". - [ssh-tcpwrapper] enabled = false @@ -117,17 +119,18 @@ action = hostsdeny[daemon_list=sshd] ignoreregex = for myuser from logpath = /var/log/sshd.log + # Here we use blackhole routes for not requiring any additional kernel support # to store large volumes of banned IPs - [ssh-route] -enabled = false -filter = sshd -action = route -logpath = /var/log/sshd.log +enabled = false +filter = sshd +action = route +logpath = /var/log/sshd.log maxretry = 5 + # Here we use a combination of Netfilter/Iptables and IPsets # for storing large volumes of banned IPs # @@ -141,13 +144,16 @@ action = iptables-ipset-proto4[name=SSH, port=ssh, protocol=tcp] logpath = /var/log/sshd.log maxretry = 5 + [ssh-iptables-ipset6] + enabled = false filter = sshd action = iptables-ipset-proto6[name=SSH, port=ssh, protocol=tcp, bantime=600] logpath = /var/log/sshd.log maxretry = 5 + # bsd-ipfw is ipfw used by BSD. It uses ipfw tables. # table number must be unique. # @@ -155,15 +161,16 @@ maxretry = 5 # for the table doesn't ready exist. # [ssh-bsd-ipfw] + enabled = false filter = sshd action = bsd-ipfw[port=ssh,table=1] logpath = /var/log/auth.log maxretry = 5 + # This jail demonstrates the use of wildcards in "logpath". # Moreover, it is possible to give other files on a new line. - [apache-tcpwrapper] enabled = false @@ -173,9 +180,9 @@ logpath = /var/log/apache*/*error.log /home/www/myhomepage/error.log maxretry = 6 + # The hosts.deny path can be defined with the "file" argument if it is # not in /etc. - [postfix-tcpwrapper] enabled = false @@ -185,9 +192,9 @@ action = hostsdeny[file=/not/a/standard/path/hosts.deny] logpath = /var/log/postfix.log bantime = 300 + # Do not ban anybody. Just report information about the remote host. # A notification is sent at most every 600 seconds (bantime). - [vsftpd-notification] enabled = false @@ -197,8 +204,8 @@ logpath = /var/log/vsftpd.log maxretry = 5 bantime = 1800 -# Same as above but with banning the IP address. +# Same as above but with banning the IP address. [vsftpd-iptables] enabled = false @@ -209,9 +216,9 @@ logpath = /var/log/vsftpd.log maxretry = 5 bantime = 1800 + # Ban hosts which agent identifies spammer robots crawling the web # for email addresses. The mail outputs are buffered. - [apache-badbots] enabled = false @@ -222,8 +229,8 @@ logpath = /var/www/*/logs/access_log bantime = 172800 maxretry = 1 -# Use shorewall instead of iptables. +# Use shorewall instead of iptables. [apache-shorewall] enabled = false @@ -232,8 +239,8 @@ action = shorewall sendmail[name=Postfix, dest=you@example.com] logpath = /var/log/apache2/error_log -# Monitor roundcube server +# Monitor roundcube server [roundcube-iptables] enabled = false @@ -243,7 +250,6 @@ logpath = /var/log/roundcube/userlogins # Monitor SOGo groupware server - [sogo-iptables] enabled = false @@ -253,41 +259,43 @@ filter = sogo-auth action = iptables-multiport[name=SOGo, port="http,https"] logpath = /var/log/sogo/sogo.log + # Ban attackers that try to use PHP's URL-fopen() functionality # through GET/POST variables. - Experimental, with more than a year # of usage in production environments. - [php-url-fopen] -enabled = false -action = iptables-multiport[name=php-url-open, port="http,https"] -filter = php-url-fopen -logpath = /var/www/*/logs/access_log +enabled = false +action = iptables-multiport[name=php-url-open, port="http,https"] +filter = php-url-fopen +logpath = /var/www/*/logs/access_log maxretry = 1 + [suhosin] -enabled = false -filter = suhosin -action = iptables-multiport[name=suhosin, port="http,https"] +enabled = false +filter = suhosin +action = iptables-multiport[name=suhosin, port="http,https"] # adapt the following two items as needed -logpath = /var/log/lighttpd/error.log +logpath = /var/log/lighttpd/error.log maxretry = 2 + [lighttpd-auth] -enabled = false -filter = lighttpd-auth -action = iptables-multiport[name=lighttpd-auth, port="http,https"] +enabled = false +filter = lighttpd-auth +action = iptables-multiport[name=lighttpd-auth, port="http,https"] # adapt the following two items as needed -logpath = /var/log/lighttpd/error.log +logpath = /var/log/lighttpd/error.log maxretry = 2 + # This jail uses ipfw, the standard firewall on FreeBSD. The "ignoreip" # option is overridden in this jail. Moreover, the action "mail-whois" defines # the variable "name" which contains a comma using "". The characters '' are # valid too. - [ssh-ipfw] enabled = false @@ -297,6 +305,7 @@ action = ipfw[localhost=192.168.0.1] logpath = /var/log/auth.log ignoreip = 168.192.0.1 + # These jails block attacks against named (bind9). By default, logging is off # with bind9 installation. You will need something like this: # @@ -332,7 +341,6 @@ ignoreip = 168.192.0.1 # ignoreip = 168.192.0.1 # This jail blocks TCP traffic for DNS requests. - [named-refused-tcp] enabled = false @@ -342,6 +350,7 @@ action = iptables-multiport[name=Named, port="domain,953", protocol=tcp] logpath = /var/log/named/security.log ignoreip = 168.192.0.1 + [asterisk] enabled = false @@ -353,6 +362,7 @@ logpath = /var/log/asterisk/messages maxretry = 10 # Historical support (before https://github.com/fail2ban/fail2ban/issues/37 was fixed ) +# use [asterisk] for new jails [asterisk-tcp] enabled = false @@ -362,6 +372,9 @@ action = iptables-multiport[name=asterisk-tcp, port="5060,5061", protocol=tcp] logpath = /var/log/asterisk/messages maxretry = 10 + +# Historical support (before https://github.com/fail2ban/fail2ban/issues/37 was fixed ) +# use [asterisk] for new jails [asterisk-udp] enabled = false @@ -371,6 +384,7 @@ action = iptables-multiport[name=asterisk-udp, port="5060,5061", protocol=udp] logpath = /var/log/asterisk/messages maxretry = 10 + # To log wrong MySQL access attempts add to /etc/my.cnf: # log-error=/var/log/mysqld.log # log-warning = 2 @@ -383,6 +397,7 @@ action = iptables[name=mysql, port=3306, protocol=tcp] logpath = /var/log/mysqld.log maxretry = 5 + # If using mysql syslog [mysql_safe] has syslog in /etc/my.cnf [mysqld-syslog-iptables] @@ -392,6 +407,7 @@ action = iptables[name=mysql, port=3306, protocol=tcp] logpath = /var/log/daemon.log maxretry = 5 + # Jail for more extended banning of persistent abusers # !!! WARNING !!! # Make sure that your loglevel specified in fail2ban.conf/.local @@ -408,14 +424,16 @@ bantime = 604800 ; 1 week findtime = 86400 ; 1 day maxretry = 5 + # PF is a BSD based firewall [ssh-pf] -enabled=false -filter = sshd -action = pf +enabled = false +filter = sshd +action = pf logpath = /var/log/sshd.log -maxretry=5 +maxretry = 5 + [3proxy] @@ -424,70 +442,92 @@ filter = 3proxy action = iptables[name=3proxy, port=3128, protocol=tcp] logpath = /var/log/3proxy.log + [exim] + enabled = false -filter = exim -action = iptables-multiport[name=exim,port="25,465,587"] +filter = exim +action = iptables-multiport[name=exim,port="25,465,587"] logpath = /var/log/exim/mainlog + [exim-spam] + enabled = false filter = exim-spam action = iptables-multiport[name=exim-spam,port="25,465,587"] logpath = /var/log/exim/mainlog + [perdition] + enabled = false filter = perdition action = iptables-multiport[name=perdition,port="110,143,993,995"] logpath = /var/log/maillog + [uwimap-auth] + enabled = false filter = uwimap-auth action = iptables-multiport[name=uwimap-auth,port="110,143,993,995"] logpath = /var/log/maillog + [osx-ssh-ipfw] + enabled = false filter = sshd action = osx-ipfw logpath = /var/log/secure.log + [ssh-apf] + enabled = false filter = sshd action = apf[name=SSH] logpath = /var/log/secure + [osx-ssh-afctl] + enabled = false filter = sshd action = osx-afctl[bantime=600] logpath = /var/log/secure.log + [webmin-auth] + enabled = false filter = webmin-auth action = iptables-multiport[name=webmin,port="10000"] logpath = /var/log/auth.log + # dovecot defaults to logging to the mail syslog facility # but can be set by syslog_facility in the dovecot configuration. [dovecot] + enabled = false filter = dovecot action = iptables-multiport[name=dovecot, port="pop3,pop3s,imap,imaps,submission,smtps,sieve", protocol=tcp] logpath = /var/log/mail.log + [dovecot-auth] + enabled = false filter = dovecot action = iptables-multiport[name=dovecot-auth, port="pop3,pop3s,imap,imaps,submission,smtps,sieve", protocol=tcp] logpath = /var/log/secure + [selinux-ssh] enabled = false filter = selinux-ssh action = iptables[name=SELINUX-SSH, port=ssh, protocol=tcp] logpath = /var/log/audit/audit.log + From de9977441aeaa11ea1badee3ab5ae7f5b391be95 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 30 Oct 2013 21:12:16 +1100 Subject: [PATCH 017/165] DOC: move named and mysql instructions into the filters from jail.conf --- config/filter.d/mysqld-auth.conf | 5 +++++ config/filter.d/named-refused.conf | 16 ++++++++++++++++ config/jail.conf | 24 +++--------------------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/config/filter.d/mysqld-auth.conf b/config/filter.d/mysqld-auth.conf index 64dd16ed..82c941ff 100644 --- a/config/filter.d/mysqld-auth.conf +++ b/config/filter.d/mysqld-auth.conf @@ -3,6 +3,11 @@ # Authors: Artur Penttinen # Yaroslav O. Halchenko # +# To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld]: +# log-error=/var/log/mysqld.log +# log-warning = 2 +# +# If using mysql syslog [mysql_safe] has syslog in /etc/my.cnf [INCLUDES] diff --git a/config/filter.d/named-refused.conf b/config/filter.d/named-refused.conf index 1b6f4d4d..c53aa3e1 100644 --- a/config/filter.d/named-refused.conf +++ b/config/filter.d/named-refused.conf @@ -4,7 +4,23 @@ # # Author: Yaroslav Halchenko # +# This filter blocks attacks against named (bind9). # +# By default, logging is off +# with bind9 installation. You will need something like this: +# +# logging { +# channel security_file { +# file "/var/log/named/security.log" versions 3 size 30m; +# severity dynamic; +# print-time yes; +# }; +# category security { +# security_file; +# }; +# }; +# +# in your named.conf to provide proper logging. [Definition] diff --git a/config/jail.conf b/config/jail.conf index 89c1ce73..c6d3384f 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -306,23 +306,6 @@ logpath = /var/log/auth.log ignoreip = 168.192.0.1 -# These jails block attacks against named (bind9). By default, logging is off -# with bind9 installation. You will need something like this: -# -# logging { -# channel security_file { -# file "/var/log/named/security.log" versions 3 size 30m; -# severity dynamic; -# print-time yes; -# }; -# category security { -# security_file; -# }; -# }; -# -# in your named.conf to provide proper logging. -# This jail blocks UDP traffic for DNS requests. - # !!! WARNING !!! # Since UDP is connection-less protocol, spoofing of IP and imitation # of illegal actions is way too simple. Thus enabling of this filter @@ -331,6 +314,8 @@ ignoreip = 168.192.0.1 # http://nion.modprobe.de/blog/archives/690-fail2ban-+-dns-fail.html # Please DO NOT USE this jail unless you know what you are doing. # +# IMPORTANT: see filter.d/named-refused for instructions to enable logging +# This jail blocks UDP traffic for DNS requests. # [named-refused-udp] # # enabled = false @@ -340,6 +325,7 @@ ignoreip = 168.192.0.1 # logpath = /var/log/named/security.log # ignoreip = 168.192.0.1 +# IMPORTANT: see filter.d/named-refused for instructions to enable logging # This jail blocks TCP traffic for DNS requests. [named-refused-tcp] @@ -385,9 +371,6 @@ logpath = /var/log/asterisk/messages maxretry = 10 -# To log wrong MySQL access attempts add to /etc/my.cnf: -# log-error=/var/log/mysqld.log -# log-warning = 2 [mysqld-iptables] enabled = false @@ -398,7 +381,6 @@ logpath = /var/log/mysqld.log maxretry = 5 -# If using mysql syslog [mysql_safe] has syslog in /etc/my.cnf [mysqld-syslog-iptables] enabled = false From 89fd792dfbd09f331858d04bbe4f2d290d63b969 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 00:02:59 +1100 Subject: [PATCH 018/165] DOC: in filters, put user relevant doc at top, and developer info at bottom, and remove all the repetative blindly copied stuff that appears in the jail man page --- config/filter.d/3proxy.conf | 20 +++++------ config/filter.d/apache-auth.conf | 48 +++++++++++++-------------- config/filter.d/apache-badbots.conf | 26 ++++++--------- config/filter.d/apache-common.conf | 13 ++++---- config/filter.d/apache-nohome.conf | 26 +++++---------- config/filter.d/apache-noscript.conf | 21 +++--------- config/filter.d/apache-overflows.conf | 18 +++------- config/filter.d/assp.conf | 27 +++++---------- config/filter.d/asterisk.conf | 24 +++----------- config/filter.d/common.conf | 5 +-- config/filter.d/courierlogin.conf | 21 +++--------- config/filter.d/couriersmtp.conf | 18 ++-------- config/filter.d/cyrus-imap.conf | 17 ++-------- config/filter.d/dovecot.conf | 21 +++++------- config/filter.d/exim-common.conf | 11 +++--- config/filter.d/exim-spam.conf | 21 ++++-------- config/filter.d/exim.conf | 22 +++++------- config/filter.d/gssftpd.conf | 8 ++--- config/filter.d/lighttpd-auth.conf | 14 ++------ config/filter.d/mysqld-auth.conf | 27 ++++++--------- config/filter.d/named-refused.conf | 31 ++++++++--------- config/filter.d/pam-generic.conf | 26 ++++++--------- config/filter.d/perdition.conf | 8 +++-- config/filter.d/php-url-fopen.conf | 31 ++++++++--------- config/filter.d/postfix-sasl.conf | 6 ++-- config/filter.d/postfix.conf | 18 ++-------- config/filter.d/proftpd.conf | 8 ++--- config/filter.d/pure-ftpd.conf | 21 ++---------- config/filter.d/qmail.conf | 21 ++++++++---- config/filter.d/recidive.conf | 9 ++--- config/filter.d/roundcube-auth.conf | 14 ++------ config/filter.d/selinux-common.conf | 6 ++-- config/filter.d/selinux-ssh.conf | 13 ++++---- config/filter.d/sieve.conf | 18 ++-------- config/filter.d/sogo-auth.conf | 23 ++++++------- config/filter.d/sshd-ddos.conf | 17 ++-------- config/filter.d/sshd.conf | 20 ++--------- config/filter.d/suhosin.conf | 19 +++++------ config/filter.d/uwimap-auth.conf | 7 ++-- config/filter.d/vsftpd.conf | 18 ++-------- config/filter.d/webmin-auth.conf | 16 ++++----- config/filter.d/wuftpd.conf | 12 ++----- config/filter.d/xinetd-fail.conf | 29 +++++----------- 43 files changed, 281 insertions(+), 518 deletions(-) diff --git a/config/filter.d/3proxy.conf b/config/filter.d/3proxy.conf index b22b4588..299c3a29 100644 --- a/config/filter.d/3proxy.conf +++ b/config/filter.d/3proxy.conf @@ -1,18 +1,18 @@ -# Fail2Ban configuration file +# Fail2Ban filter for 3proxy # -# Author: Daniel Black -# -# Requested by ykimon in https://github.com/fail2ban/fail2ban/issues/246 # [Definition] -# Option: failregex -# Notes.: http://www.3proxy.ru/howtoe.asp#ERRORS indicates that 01-09 are -# all authentication problems (%E field) -# Log format is: "L%d-%m-%Y %H:%M:%S %z %N.%p %E %U %C:%c %R:%r %O %I %h %T" -# Values: TEXT -# + failregex = ^\s[+-]\d{4} \S+ \d{3}0[1-9] \S+ :\d+ [\d.]+:\d+ \d+ \d+ \d+\s ignoreregex = + +# DEV Notes: +# http://www.3proxy.ru/howtoe.asp#ERRORS indicates that 01-09 are +# all authentication problems (%E field) +# Log format is: "L%d-%m-%Y %H:%M:%S %z %N.%p %E %U %C:%c %R:%r %O %I %h %T" +# +# Requested by ykimon in https://github.com/fail2ban/fail2ban/issues/246 +# Author: Daniel Black diff --git a/config/filter.d/apache-auth.conf b/config/filter.d/apache-auth.conf index b4061778..3df91c15 100644 --- a/config/filter.d/apache-auth.conf +++ b/config/filter.d/apache-auth.conf @@ -1,17 +1,33 @@ -# Fail2Ban configuration file -# -# Author: Cyril Jaquier -# +# Fail2Ban apache-auth filter # [INCLUDES] # Read common prefixes. If any customizations available -- read them from -# common.local +# apache-common.local before = apache-common.conf [Definition] + +failregex = ^%(_apache_error_client)s (AH01797: )?client denied by server configuration: (uri )?\S*\s*$ + ^%(_apache_error_client)s (AH01617: )?user .* authentication failure for "\S*": Password Mismatch$ + ^%(_apache_error_client)s (AH01618: )?user .* not found(: )?\S*\s*$ + ^%(_apache_error_client)s (AH01614: )?client used wrong authentication scheme: \S*\s*$ + ^%(_apache_error_client)s (AH\d+: )?Authorization of user \S+ to access \S* failed, reason: .*$ + ^%(_apache_error_client)s (AH0179[24]: )?(Digest: )?user .*: password mismatch: \S*\s*$ + ^%(_apache_error_client)s (AH0179[01]: |Digest: )user `.*' in realm `.+' (not found|denied by provider): \S*\s*$ + ^%(_apache_error_client)s (AH01631: )?user .*: authorization failure for "\S*":\s*$ + ^%(_apache_error_client)s (AH01775: )?(Digest: )?invalid nonce .* received - length is not \S+\s*$ + ^%(_apache_error_client)s (AH01788: )?(Digest: )?realm mismatch - got `.*' but expected `.+'\s*$ + ^%(_apache_error_client)s (AH01789: )?(Digest: )?unknown algorithm `.*' received: \S*\s*$ + ^%(_apache_error_client)s (AH01793: )?invalid qop `.*' received: \S*\s*$ + ^%(_apache_error_client)s (AH01777: )?(Digest: )?invalid nonce .* received - user attempted time travel\s*$ + +ignoreregex = + +# DEV Notes: +# # This filter matches the authorization failures of Apache. It takes the log messages # from the modules in aaa that return HTTP_UNAUTHORIZED, HTTP_METHOD_NOT_ALLOWED or # HTTP_FORBIDDEN and not AUTH_GENERAL_ERROR or HTTP_INTERNAL_SERVER_ERROR. @@ -34,23 +50,5 @@ before = apache-common.conf # ^%(_apache_error_client)s (AH01779: )?user .*: one-time-nonce mismatch - sending new nonce\s*$ # ^%(_apache_error_client)s (AH02486: )?realm mismatch - got `.*' but no realm specified\s*$ # -failregex = ^%(_apache_error_client)s (AH01797: )?client denied by server configuration: (uri )?\S*\s*$ - ^%(_apache_error_client)s (AH01617: )?user .* authentication failure for "\S*": Password Mismatch$ - ^%(_apache_error_client)s (AH01618: )?user .* not found(: )?\S*\s*$ - ^%(_apache_error_client)s (AH01614: )?client used wrong authentication scheme: \S*\s*$ - ^%(_apache_error_client)s (AH\d+: )?Authorization of user \S+ to access \S* failed, reason: .*$ - ^%(_apache_error_client)s (AH0179[24]: )?(Digest: )?user .*: password mismatch: \S*\s*$ - ^%(_apache_error_client)s (AH0179[01]: |Digest: )user `.*' in realm `.+' (not found|denied by provider): \S*\s*$ - ^%(_apache_error_client)s (AH01631: )?user .*: authorization failure for "\S*":\s*$ - ^%(_apache_error_client)s (AH01775: )?(Digest: )?invalid nonce .* received - length is not \S+\s*$ - ^%(_apache_error_client)s (AH01788: )?(Digest: )?realm mismatch - got `.*' but expected `.+'\s*$ - ^%(_apache_error_client)s (AH01789: )?(Digest: )?unknown algorithm `.*' received: \S*\s*$ - ^%(_apache_error_client)s (AH01793: )?invalid qop `.*' received: \S*\s*$ - ^%(_apache_error_client)s (AH01777: )?(Digest: )?invalid nonce .* received - user attempted time travel\s*$ - - -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# -ignoreregex = +# Author: Cyril Jaquier +# Major edits by Daniel Black diff --git a/config/filter.d/apache-badbots.conf b/config/filter.d/apache-badbots.conf index f9c79472..9ee44c69 100644 --- a/config/filter.d/apache-badbots.conf +++ b/config/filter.d/apache-badbots.conf @@ -1,27 +1,21 @@ # Fail2Ban configuration file # -# List of bad bots fetched from http://www.user-agents.org -# Generated on Sun Feb 11 01:09:15 EST 2007 by ./badbots.sh -# -# Author: Yaroslav Halchenko -# -# +# Regexp to catch known spambots and software alike. Please verify +# that it is your intent to block IPs which were driven by +# above mentioned bots. + [Definition] badbotscustom = EmailCollector|WebEMailExtrac|TrackBack/1\.02|sogou music spider badbots = atSpider/1\.0|autoemailspider|China Local Browse 2\.6|ContentSmartz|DataCha0s/2\.0|DBrowse 1\.4b|DBrowse 1\.4d|Demo Bot DOT 16b|Demo Bot Z 16b|DSurf15a 01|DSurf15a 71|DSurf15a 81|DSurf15a VA|EBrowse 1\.4b|Educate Search VxB|EmailSiphon|EmailWolf 1\.00|ESurf15a 15|ExtractorPro|Franklin Locator 1\.8|FSurf15a 01|Full Web Bot 0416B|Full Web Bot 0516B|Full Web Bot 2816B|Industry Program 1\.0\.x|ISC Systems iRc Search 2\.1|IUPUI Research Bot v 1\.9a|LARBIN-EXPERIMENTAL \(efp@gmx\.net\)|LetsCrawl\.com/1\.0 +http\://letscrawl\.com/|Lincoln State Web Browser|LWP\:\:Simple/5\.803|Mac Finder 1\.0\.xx|MFC Foundation Class Library 4\.0|Microsoft URL Control - 6\.00\.8xxx|Missauga Locate 1\.0\.0|Missigua Locator 1\.9|Missouri College Browse|Mizzu Labs 2\.2|Mo College 1\.9|Mozilla/2\.0 \(compatible; NEWT ActiveX; Win32\)|Mozilla/3\.0 \(compatible; Indy Library\)|Mozilla/4\.0 \(compatible; Advanced Email Extractor v2\.xx\)|Mozilla/4\.0 \(compatible; Iplexx Spider/1\.0 http\://www\.iplexx\.at\)|Mozilla/4\.0 \(compatible; MSIE 5\.0; Windows NT; DigExt; DTS Agent|Mozilla/4\.0 efp@gmx\.net|Mozilla/5\.0 \(Version\: xxxx Type\:xx\)|MVAClient|NASA Search 1\.0|Nsauditor/1\.x|PBrowse 1\.4b|PEval 1\.4b|Poirot|Port Huron Labs|Production Bot 0116B|Production Bot 2016B|Production Bot DOT 3016B|Program Shareware 1\.0\.2|PSurf15a 11|PSurf15a 51|PSurf15a VA|psycheclone|RSurf15a 41|RSurf15a 51|RSurf15a 81|searchbot admin@google\.com|sogou spider|sohu agent|SSurf15a 11 |TSurf15a 11|Under the Rainbow 2\.2|User-Agent\: Mozilla/4\.0 \(compatible; MSIE 6\.0; Windows NT 5\.1\)|WebVulnCrawl\.blogspot\.com/1\.0 libwww-perl/5\.803|Wells Search II|WEP Search 00 -# Option: failregex -# Notes.: Regexp to catch known spambots and software alike. Please verify -# that it is your intent to block IPs which were driven by -# above mentioned bots. -# Values: TEXT -# failregex = ^ -.*"(GET|POST).*HTTP.*"(?:%(badbots)s|%(badbotscustom)s)"$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# DEV Notes: +# List of bad bots fetched from http://www.user-agents.org +# Generated on Sun Feb 11 01:09:15 EST 2007 by ./badbots.sh +# +# Author: Yaroslav Halchenko diff --git a/config/filter.d/apache-common.conf b/config/filter.d/apache-common.conf index 134fad29..ca8f2417 100644 --- a/config/filter.d/apache-common.conf +++ b/config/filter.d/apache-common.conf @@ -1,21 +1,20 @@ # Generic configuration items (to be used as interpolations) in other -# apache filters -# -# Author: Yaroslav Halchenko -# -# +# apache filters. [INCLUDES] # Load customizations if any available after = apache-common.local - [DEFAULT] +_apache_error_client = \[[^]]*\] \[(error|\S+:\S+)\]( \[pid \d+:\S+ \d+\])? \[client (:\d{1,5})?\] + # Common prefix for [error] apache messages which also would include # Depending on the version it could be # 2.2: [Sat Jun 01 11:23:08 2013] [error] [client 1.2.3.4] # 2.4: [Thu Jun 27 11:55:44.569531 2013] [core:info] [pid 4101:tid 2992634688] [client 1.2.3.4:46652] +# # Reference: https://github.com/fail2ban/fail2ban/issues/268 -_apache_error_client = \[[^]]*\] \[(error|\S+:\S+)\]( \[pid \d+:\S+ \d+\])? \[client (:\d{1,5})?\] +# +# Author: Yaroslav Halchenko diff --git a/config/filter.d/apache-nohome.conf b/config/filter.d/apache-nohome.conf index 0eede317..358d6d32 100644 --- a/config/filter.d/apache-nohome.conf +++ b/config/filter.d/apache-nohome.conf @@ -1,28 +1,20 @@ -# Fail2Ban configuration file -# -# Author: Yaroslav O. Halchenko -# +# Fail2Ban filter to web requests for home directories on Apache servers # +# Regex to match failures to find a home directory on a server, which +# became popular last days. Most often attacker just uses IP instead of +# domain name -- so expect to see them in generic error.log if you have +# per-domain log files. [INCLUDES] -# Read common prefixes. If any customizations available -- read them from -# common.local +# overwrite with apache-common.local if _apache_error_client is incorrect. before = apache-common.conf [Definition] -# Option: failregex -# Notes.: regex to match failures to find a home directory on a server, which -# became popular last days. Most often attacker just uses IP instead of -# domain name -- so expect to see them in generic error.log if you have -# per-domain log files. -# Values: TEXT -# + failregex = ^%(_apache_error_client)s (AH00128: )?File does not exist: .*/~.* -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# Author: Yaroslav O. Halchenko diff --git a/config/filter.d/apache-noscript.conf b/config/filter.d/apache-noscript.conf index 295e1b9f..4ecf349a 100644 --- a/config/filter.d/apache-noscript.conf +++ b/config/filter.d/apache-noscript.conf @@ -1,29 +1,18 @@ -# Fail2Ban configuration file -# -# Author: Cyril Jaquier +# Fail2Ban filter to block web requests for scripts (on non scripted websites) # # [INCLUDES] -# Read common prefixes. If any customizations available -- read them from -# common.local +# overwrite with apache-common.local if _apache_error_client is incorrect. before = apache-common.conf [Definition] -# Option: failregex -# Notes.: regex to match the password 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[\w\-.^_]+) -# Values: TEXT -# failregex = ^%(_apache_error_client)s (File does not exist|script not found or unable to stat): /\S*(\.php|\.asp|\.exe|\.pl)\s*$ ^%(_apache_error_client)s script '/\S*(\.php|\.asp|\.exe|\.pl)\S*' not found or unable to stat\s*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + + +# Author: Cyril Jaquier diff --git a/config/filter.d/apache-overflows.conf b/config/filter.d/apache-overflows.conf index 1cf08db7..de1c770d 100644 --- a/config/filter.d/apache-overflows.conf +++ b/config/filter.d/apache-overflows.conf @@ -1,25 +1,15 @@ -# Fail2Ban configuration file -# -# Author: Tim Connors -# +# Fail2Ban filter to block web requests on a long or suspicious nature # [INCLUDES] -# Read common prefixes. If any customizations available -- read them from -# common.local +# overwrite with apache-common.local if _apache_error_client is incorrect. before = apache-common.conf [Definition] -# Option: failregex -# Notes.: Regexp to catch Apache overflow attempts. -# Values: TEXT -# failregex = ^%(_apache_error_client)s (Invalid (method|URI) in request|request failed: URI too long|erroneous characters after protocol string) -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# Author: Tim Connors diff --git a/config/filter.d/assp.conf b/config/filter.d/assp.conf index 2854d898..2aa8958c 100644 --- a/config/filter.d/assp.conf +++ b/config/filter.d/assp.conf @@ -1,33 +1,24 @@ -# Fail2Ban configuration file -# for Anti-Spam SMTP Proxy Server also known as ASSP +# Fail2Ban filter 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 = ^(:? \[SSL-out\])? max sender authentication errors \(\d{,3}\) exceeded -- %(__assp_actions)s connection - after reply: \d{3} \d{1}\.\d{1}.\d{1} Error: authentication failed: \w+;$ ^(?: \[SSL-out\])? SSL negotiation with client failed: SSL accept attempt failed with unknown error.*:unknown protocol;$ ^ Blocking - too much AUTH errors \(\d{,3}\);$ - -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = +# DEV Notes: +# +# 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 +# +# Author: Enrico Labedzki (enrico.labedzki@deiwos.de) diff --git a/config/filter.d/asterisk.conf b/config/filter.d/asterisk.conf index fef43693..35906d11 100644 --- a/config/filter.d/asterisk.conf +++ b/config/filter.d/asterisk.conf @@ -1,22 +1,11 @@ -# Fail2Ban configuration file +# Fail2Ban filter for asterisk authentication failures # -# Author: Xavier Devlamynck -# -# - - -[INCLUDES] - -# Read common prefixes. If any customizations available -- read them from -# common.local -before = common.conf [Definition] -# Option: failregex -# Notes.: regex to match the password failures messages in the logfile. -# Values: TEXT -# +__pid_re = (?:\[\d+\]) + +# All Asterisk log messages begin like this: log_prefix= \[\]\s*(?:NOTICE|SECURITY)%(__pid_re)s:?(?:\[\S+\d*\])? \S+:\d* failregex = ^%(log_prefix)s Registration from '[^']*' failed for '(:\d+)?' - Wrong password$ @@ -34,10 +23,7 @@ failregex = ^%(log_prefix)s Registration from '[^']*' failed for '(:\d+)?' ^%(log_prefix)s (?:handle_request_subscribe: )?Sending fake auth rejection for (device|user) \d*>;tag=\w+\S*$ ^%(log_prefix)s SecurityEvent="(FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)",EventTV="[\d-]+",Severity="[\w]+",Service="[\w]+",EventVersion="\d+",AccountID="\d+",SessionID="0x[\da-f]+",LocalAddress="IPV[46]/(UD|TC)P/[\da-fA-F:.]+/\d+",RemoteAddress="IPV[46]/(UD|TC)P//\d+"(,Challenge="\w+",ReceivedChallenge="\w+")?(,ReceivedHash="[\da-f]+")?$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = +# Author: Xavier Devlamynck diff --git a/config/filter.d/common.conf b/config/filter.d/common.conf index a74d223e..b992e4b8 100644 --- a/config/filter.d/common.conf +++ b/config/filter.d/common.conf @@ -1,9 +1,6 @@ # Generic configuration items (to be used as interpolations) in other # filters or actions configurations # -# Author: Yaroslav Halchenko -# -# [INCLUDES] @@ -49,7 +46,6 @@ __md5hex = (?:[\da-f]{2}:){15}[\da-f]{2} # appearing before the host as per testcases/files/logs/bsd/*. __bsd_syslog_verbose = (<[^.]+\.[^.]+>) -# # Common line prefixes (beginnings) which could be used in filters # # [bsdverbose]? [hostname] [vserver tag] daemon_id spaces @@ -57,3 +53,4 @@ __bsd_syslog_verbose = (<[^.]+\.[^.]+>) # This can be optional (for instance if we match named native log files) __prefix_line = \s*%(__bsd_syslog_verbose)s?\s*(?:%(__hostname)s )?(?:%(__kernel_prefix)s )?(?:@vserver_\S+ )?%(__daemon_combs_re)s?\s%(__daemon_extra_re)s?\s* +# Author: Yaroslav Halchenko diff --git a/config/filter.d/courierlogin.conf b/config/filter.d/courierlogin.conf index f096325e..1170a63a 100644 --- a/config/filter.d/courierlogin.conf +++ b/config/filter.d/courierlogin.conf @@ -1,8 +1,4 @@ -# Fail2Ban configuration file -# -# Author: Christoph Haas -# Modified by: Cyril Jaquier -# +# Fail2Ban filter for courier authentication failures # [INCLUDES] @@ -11,22 +7,13 @@ # common.local before = common.conf - [Definition] _daemon = (?:courier)?(?:imapd?|pop3d?)(?:login)?(?:-ssl)? -# Option: failregex -# Notes.: regex to match the password failures 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[\w\-.^_]+) -# Values: TEXT -# failregex = ^%(__prefix_line)sLOGIN FAILED, user=.*, ip=\[\]$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# Author: Christoph Haas +# Modified by: Cyril Jaquier diff --git a/config/filter.d/couriersmtp.conf b/config/filter.d/couriersmtp.conf index 65ffa5d7..2b9a13f2 100644 --- a/config/filter.d/couriersmtp.conf +++ b/config/filter.d/couriersmtp.conf @@ -1,6 +1,4 @@ -# Fail2Ban configuration file -# -# Author: Cyril Jaquier +# Fail2Ban filter to block relay attempts though a Courier smtp server # # @@ -10,22 +8,12 @@ # common.local before = common.conf - [Definition] _daemon = courieresmtpd -# Option: failregex -# Notes.: regex to match the password failures 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[\w\-.^_]+) -# Values: TEXT -# failregex = ^%(__prefix_line)serror,relay=,.*: 550 User unknown\.$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# Author: Cyril Jaquier diff --git a/config/filter.d/cyrus-imap.conf b/config/filter.d/cyrus-imap.conf index 0ace92c1..3560234e 100644 --- a/config/filter.d/cyrus-imap.conf +++ b/config/filter.d/cyrus-imap.conf @@ -1,6 +1,5 @@ -# Fail2Ban configuration file +# Fail2Ban filter for authentication failures on Cyrus imap server # -# Author: Jan Wagner # # @@ -10,22 +9,12 @@ # common.local before = common.conf - [Definition] _daemon = (?:cyrus/)?(?:imapd?|pop3d?) -# Option: failregex -# Notes.: regex to match the password failures 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[\w\-.^_]+) -# Values: TEXT -# failregex = ^%(__prefix_line)sbadlogin: \S+ ?\[\] \S+ .*?\[?SASL\(-13\): authentication failure: .*\]?$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# Author: Jan Wagner diff --git a/config/filter.d/dovecot.conf b/config/filter.d/dovecot.conf index dd0e7678..2caa04b3 100644 --- a/config/filter.d/dovecot.conf +++ b/config/filter.d/dovecot.conf @@ -1,7 +1,5 @@ -# Fail2Ban configuration file for dovecot +# Fail2Ban filter Dovecot authentication and pop3/imap server # -# Author: Martin Waschbuesch -# Daniel Black (rewrote with begin and end anchors) [INCLUDES] @@ -10,17 +8,16 @@ before = common.conf [Definition] _daemon = (auth|dovecot(-auth)?|auth-worker) -# Option: failregex -# Notes.: regex to match the password failures messages in the logfile. -# first regex is essentially a copy of pam-generic.conf -# Values: TEXT -# + failregex = ^%(__prefix_line)s(pam_unix(\(dovecot:auth\))?:)?\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=dovecot ruser=\S* rhost=(\s+user=\S*)?\s*$ ^%(__prefix_line)s(pop3|imap)-login: (Info: )?(Aborted login|Disconnected)(: Inactivity)? \(((no auth attempts|auth failed, \d+ attempts)( in \d+ secs)?|tried to use disabled \S+ auth)\):( user=<\S*>,)?( method=\S+,)? rip=, lip=(\d{1,3}\.){3}\d{1,3}(, session=<\w+>)?(, TLS( handshaking)?(: Disconnected)?)?\s*$ ^%(__prefix_line)s(Info|dovecot: auth\(default\)): pam\(\S+,\): pam_authenticate\(\) failed: (User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \(password mismatch\?\))\s*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# DEV Notes: +# * the first regex is essentially a copy of pam-generic.conf +# * Probably doesn't do dovecot sql/ldap backends properly +# +# Author: Martin Waschbuesch +# Daniel Black (rewrote with begin and end anchors) diff --git a/config/filter.d/exim-common.conf b/config/filter.d/exim-common.conf index 79d6ffbb..1c0a0a20 100644 --- a/config/filter.d/exim-common.conf +++ b/config/filter.d/exim-common.conf @@ -1,17 +1,18 @@ -# Fail2Ban configuration file for exim -# -# Author: Daniel Black +# Fail2Ban filter file for common exim expressions # +# This is to be used by other exim filters [INCLUDES] # Load customizations if any available -# after = exim-common.local [Definition] -# From exim source code: ./src/receive.c:add_host_info_for_log host_info = H=([\w.-]+ )?(\(\S+\) )?\[\](:\d+)? (I=\[\S+\]:\d+ )?(U=\S+ )?(P=e?smtp )? pid = ( \[\d+\])? +# DEV Notes: +# From exim source code: ./src/receive.c:add_host_info_for_log +# +# Author: Daniel Black diff --git a/config/filter.d/exim-spam.conf b/config/filter.d/exim-spam.conf index 55a6f5dd..15737b2f 100644 --- a/config/filter.d/exim-spam.conf +++ b/config/filter.d/exim-spam.conf @@ -1,9 +1,5 @@ -# Fail2Ban configuration file +# Fail2Ban filter for exim the spam rejection messages # -# Author: Cyril Jaquier -# Daniel Black (rewrote with strong regexs) -# - [INCLUDES] @@ -11,19 +7,16 @@ # exim-common.local before = exim-common.conf - [Definition] -# Option: failregex -# Notes.: This includes the spam rejection messages of exim. -# Note the %(host_info) defination contains a match - failregex = ^%(pid)s \S+ F=(<>|\S+@\S+) %(host_info)srejected by local_scan\(\): .{0,256}$ ^%(pid)s %(host_info)sF=(<>|[^@]+@\S+) rejected RCPT [^@]+@\S+: .*dnsbl.*\s*$ ^%(pid)s \S+ %(host_info)sF=(<>|[^@]+@\S+) rejected after DATA: This message contains a virus \(\S+\)\.\s*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# DEV Notes: +# The %(host_info) defination contains a match +# +# Author: Cyril Jaquier +# Daniel Black (rewrote with strong regexs) diff --git a/config/filter.d/exim.conf b/config/filter.d/exim.conf index a30c9503..5f786594 100644 --- a/config/filter.d/exim.conf +++ b/config/filter.d/exim.conf @@ -1,7 +1,7 @@ -# Fail2Ban configuration file +# Fail2Ban filter for exim # -# Author: Cyril Jaquier -# Daniel Black (rewrote with strong regexs) +# This includes the rejection messages of exim. For spam and filter +# related bans use the exim-spam.conf # @@ -11,22 +11,18 @@ # exim-common.local before = exim-common.conf - [Definition] -# Option: failregex -# Notes.: This includes the rejection messages of exim. For spam and filter -# related bans use the exim-spam.conf -# Note the %(host_info) defination contains a match - failregex = ^%(pid)s %(host_info)ssender verify fail for <\S+>: (?:Unknown user|Unrouteable address|all relevant MX records point to non-existent hosts)\s*$ ^%(pid)s (plain|login) authenticator failed for (\S+ )?\(\S+\) \[\]: 535 Incorrect authentication data( \(set_id=.*\)|: \d+ Time\(s\))?\s*$ ^%(pid)s %(host_info)sF=(<>|[^@]+@\S+) rejected RCPT [^@]+@\S+: (relay not permitted|Sender verify failed|Unknown user)\s*$ ^%(pid)s SMTP protocol synchronization error \(.*\): rejected (connection from|"\S+") %(host_info)s(next )?input=".*"\s*$ ^%(pid)s SMTP call from \S+ \[\](:\d+)? (I=\[\S+\]:\d+ )?dropped: too many nonmail commands \(last was "\S+"\)\s*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# DEV Notes: +# The %(host_info) defination contains a match +# +# Author: Cyril Jaquier +# Daniel Black (rewrote with strong regexs) diff --git a/config/filter.d/gssftpd.conf b/config/filter.d/gssftpd.conf index 5bce817b..5f9fb6a7 100644 --- a/config/filter.d/gssftpd.conf +++ b/config/filter.d/gssftpd.conf @@ -1,7 +1,4 @@ -# Fail2Ban configuration file for gssftp -# -# Author: Kevin Zembower -# Edited: Daniel Black - syslog based daemon +# Fail2Ban filter file for gssftp # # Note: gssftp is part of the krb5-appl-servers in Fedora # @@ -16,3 +13,6 @@ _daemon = ftpd failregex = ^%(__prefix_line)srepeated login failures from \(\S+\)$ ignoreregex = + +# Author: Kevin Zembower +# Edited: Daniel Black - syslog based daemon diff --git a/config/filter.d/lighttpd-auth.conf b/config/filter.d/lighttpd-auth.conf index b59a98a2..3bd01f29 100644 --- a/config/filter.d/lighttpd-auth.conf +++ b/config/filter.d/lighttpd-auth.conf @@ -1,18 +1,10 @@ -# Fail2Ban configuration file -# -# Author: Francois Boulogne +# Fail2Ban filter to match wrong passwords as notified by lighttpd's auth Module # [Definition] -# Option: failregex -# Notes.: regex to match wrong passwords as notified by lighttpd's auth Module -# Values: TEXT -# failregex = ^: \(http_auth\.c\.\d+\) (password doesn\'t match .* username: .*|digest: auth failed for .*: wrong password|get_password failed), IP: \s*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# Author: Francois Boulogne diff --git a/config/filter.d/mysqld-auth.conf b/config/filter.d/mysqld-auth.conf index 82c941ff..92dc9a99 100644 --- a/config/filter.d/mysqld-auth.conf +++ b/config/filter.d/mysqld-auth.conf @@ -1,7 +1,5 @@ -# Fail2Ban configuration file for unsuccesfull MySQL authentication attempts +# Fail2Ban filter for unsuccesfull MySQL authentication attempts # -# Authors: Artur Penttinen -# Yaroslav O. Halchenko # # To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld]: # log-error=/var/log/mysqld.log @@ -15,23 +13,20 @@ # common.local before = common.conf - [Definition] _daemon = mysqld -# Option: failregex -# Notes.: regex to match the password failures 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[\w\-.^_]+) -# Values: TEXT -# 130322 11:26:54 [Warning] Access denied for user 'root'@'127.0.0.1' (using password: YES) -# failregex = ^%(__prefix_line)s(\d{6} \s?\d{1,2}:\d{2}:\d{2} )?\[Warning\] Access denied for user '\w+'@'' (to database '[^']*'|\(using password: (YES|NO)\))*\s*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# DEV Notes: +# +# Technically __prefix_line can equate to an empty string hence it can support +# syslog and non-syslog at once. +# Example: +# 130322 11:26:54 [Warning] Access denied for user 'root'@'127.0.0.1' (using password: YES) +# +# Authors: Artur Penttinen +# Yaroslav O. Halchenko diff --git a/config/filter.d/named-refused.conf b/config/filter.d/named-refused.conf index c53aa3e1..be997bd4 100644 --- a/config/filter.d/named-refused.conf +++ b/config/filter.d/named-refused.conf @@ -1,13 +1,12 @@ -# Fail2Ban configuration file for named (bind9). Trying to generalize the -# structure which is general to capture general patterns in log -# lines to cover different configurations/distributions +# Fail2Ban filter file for named (bind9). # -# Author: Yaroslav Halchenko + +# This filter blocks attacks against named (bind9) however it requires special +# configuration on bind. # -# This filter blocks attacks against named (bind9). +# By default, logging is off with bind9 installation. # -# By default, logging is off -# with bind9 installation. You will need something like this: +# You will need something like this in your named.conf to provide proper logging. # # logging { # channel security_file { @@ -19,29 +18,31 @@ # security_file; # }; # }; -# -# in your named.conf to provide proper logging. [Definition] -# # Daemon name _daemon=named -# # Shortcuts for easier comprehension of the failregex + __pid_re=(?:\[\d+\]) __daemon_re=\(?%(_daemon)s(?:\(\S+\))?\)?:? __daemon_combs_re=(?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_re)s?:) + # hostname daemon_id spaces # this can be optional (for instance if we match named native log files) __line_prefix=(?:\s\S+ %(__daemon_combs_re)s\s+)? - -# note - (\.\d+)? is a really ugly catch of the microseconds not captured in -# in the date detector -# failregex = ^%(__line_prefix)s(\.\d+)?( error:)?\s*client #\S+( \([\S.]+\))?: (view (internal|external): )?query(?: \(cache\))? '.*' denied\s*$ ^%(__line_prefix)s(\.\d+)?( error:)?\s*client #\S+( \([\S.]+\))?: zone transfer '\S+/AXFR/\w+' denied\s*$ ^%(__line_prefix)s(\.\d+)?( error:)?\s*client #\S+( \([\S.]+\))?: bad zone transfer request: '\S+/IN': non-authoritative zone \(NOTAUTH\)\s*$ +# DEV Notes: +# Trying to generalize the +# structure which is general to capture general patterns in log +# lines to cover different configurations/distributions +# +# (\.\d+)? is a really ugly catch of the microseconds not captured in the date detector +# +# Author: Yaroslav Halchenko diff --git a/config/filter.d/pam-generic.conf b/config/filter.d/pam-generic.conf index 15aadf3e..aea47529 100644 --- a/config/filter.d/pam-generic.conf +++ b/config/filter.d/pam-generic.conf @@ -1,35 +1,29 @@ # Fail2Ban configuration file for generic PAM authentication errors # -# Author: Yaroslav Halchenko -# -# + [INCLUDES] before = common.conf [Definition] -# if you want to catch only login erros from specific daemons, use smth like +# if you want to catch only login errors from specific daemons, use something like #_ttys_re=(?:ssh|pure-ftpd|ftp) -# To catch all failed logins +# +# Default: catch all failed logins _ttys_re=\S* __pam_re=\(?pam_unix(?:\(\S+\))?\)?:? _daemon = \S+ -# Option: failregex -# Notes.: regex to match the password failures messages in the logfile. -# Values: TEXT -# failregex = ^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=%(_ttys_re)s ruser=\S* rhost=(?:\s+user=.*)?\s*$ -# for linux-pam before 0.99.2.0 (late 2005) +ignoreregex = + +# DEV Notes: +# +# for linux-pam before 0.99.2.0 (late 2005) (removed before 0.8.11 release) # _daemon = \S*\(?pam_unix\)? # failregex = ^%(__prefix_line)sauthentication 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 = +# Author: Yaroslav Halchenko diff --git a/config/filter.d/perdition.conf b/config/filter.d/perdition.conf index 7fdca14b..c47dcac4 100644 --- a/config/filter.d/perdition.conf +++ b/config/filter.d/perdition.conf @@ -1,6 +1,4 @@ -# Fail2Ban configuration file -# -# Author: Christophe Carles and Daniel Black +# Fail2Ban filter for perdition # # @@ -14,3 +12,7 @@ _daemon=perdition.\S+ failregex = ^%(__prefix_line)sAuth: :\d+->(\d{1,3}\.){3}\d{1,3}:\d+ client-secure=\S+ authorisation_id=NONE authentication_id=".+" server="\S+" protocol=\S+ server-secure=\S+ status="failed: (local authentication failure|Re-Authentication Failure)"$ ^%(__prefix_line)sFatal Error reading authentication information from client :\d+->(\d{1,3}\.){3}\d{1,3}:\d+: Exiting child$ + +ignoreregex = + +# Author: Christophe Carles and Daniel Black diff --git a/config/filter.d/php-url-fopen.conf b/config/filter.d/php-url-fopen.conf index 68927e06..87bd04c8 100644 --- a/config/filter.d/php-url-fopen.conf +++ b/config/filter.d/php-url-fopen.conf @@ -1,23 +1,20 @@ -# Fail2Ban configuration file +# Fail2Ban filter for URLs with a URL as a script parameters +# which can be an indication of a fopen url php injection +# +# Example of web requests in Apache access log: +# 66.185.212.172 - - [26/Mar/2009:08:44:20 -0500] "GET /index.php?n=http://eatmyfood.hostinginfive.com/pizza.htm? HTTP/1.1" 200 114 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" + +[Definition] + +failregex = ^ -.*"(GET|POST).*\?.*\=http\:\/\/.* HTTP\/.*$ + +ignoreregex = + +# DEV Notes: # -# Author: Arturo 'Buanzo' Busleiman # Version 2 # fixes the failregex so REFERERS that contain =http:// don't get blocked # (mentioned by "fasuto" (no real email provided... blog comment) in this entry: # http://blogs.buanzo.com.ar/2009/04/fail2ban-filter-for-php-injection-attacks.html#comment-1489 # - -[Definition] - -# Option: failregex -# Notes.: regex to match this kind of request: -# -# 66.185.212.172 - - [26/Mar/2009:08:44:20 -0500] "GET /index.php?n=http://eatmyfood.hostinginfive.com/pizza.htm? HTTP/1.1" 200 114 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" -# -failregex = ^ -.*"(GET|POST).*\?.*\=http\:\/\/.* HTTP\/.*$ - -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# -ignoreregex = +# Author: Arturo 'Buanzo' Busleiman diff --git a/config/filter.d/postfix-sasl.conf b/config/filter.d/postfix-sasl.conf index c720abc1..d232f86e 100644 --- a/config/filter.d/postfix-sasl.conf +++ b/config/filter.d/postfix-sasl.conf @@ -1,7 +1,4 @@ -# Fail2Ban configuration file -# -# Author: Yaroslav Halchenko -# +# Fail2Ban filter for postfix authentication failures # [INCLUDES] @@ -14,3 +11,4 @@ _daemon = postfix/smtpd failregex = ^%(__prefix_line)swarning: [-._\w]+\[\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?\s*$ +# Author: Yaroslav Halchenko diff --git a/config/filter.d/postfix.conf b/config/filter.d/postfix.conf index da981733..fd8519c9 100644 --- a/config/filter.d/postfix.conf +++ b/config/filter.d/postfix.conf @@ -1,6 +1,4 @@ -# Fail2Ban configuration file -# -# Author: Cyril Jaquier +# Fail2Ban filter for selected Postfix SMTP rejections # # @@ -10,24 +8,14 @@ # common.local before = common.conf - [Definition] _daemon = postfix/smtpd -# Option: failregex -# Notes.: regex to match the password failures 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[\w\-.^_]+) -# Values: TEXT -# failregex = ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[\]: 554 5\.7\.1 .*$ ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[\]: 450 4\.7\.1 : Helo command rejected: Host not found; from=<> to=<> proto=ESMTP helo= *$ ^%(__prefix_line)sNOQUEUE: reject: VRFY from \S+\[\]: 550 5\.1\.1 .*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# Author: Cyril Jaquier diff --git a/config/filter.d/proftpd.conf b/config/filter.d/proftpd.conf index 66e4b6e7..bf8f9b5f 100644 --- a/config/filter.d/proftpd.conf +++ b/config/filter.d/proftpd.conf @@ -1,7 +1,4 @@ -# Fail2Ban configuration file -# -# Author: Yaroslav Halchenko -# Daniel Black - hardening of regex +# Fail2Ban fitler for the Proftpd FTP daemon # [INCLUDES] @@ -20,3 +17,6 @@ failregex = ^%(__prefix_line)s%(__hostname)s \(\S+\[\]\)[: -]+ USER .*: no ^%(__prefix_line)s%(__hostname)s \(\S+\[\]\)[: -]+ Maximum login attempts \(\d+\) exceeded *$ ignoreregex = + +# Author: Yaroslav Halchenko +# Daniel Black - hardening of regex diff --git a/config/filter.d/pure-ftpd.conf b/config/filter.d/pure-ftpd.conf index 2f910b8a..1698c9ec 100644 --- a/config/filter.d/pure-ftpd.conf +++ b/config/filter.d/pure-ftpd.conf @@ -1,7 +1,5 @@ -# Fail2Ban configuration file +# Fail2Ban filter for pureftp # -# Author: Cyril Jaquier -# Modified: Yaroslav Halchenko for pure-ftpd # # [INCLUDES] @@ -13,22 +11,9 @@ before = common.conf # Error message specified in multiple languages __errmsg = (?:Authentication failed for user|Erreur d'authentification pour l'utilisateur) -# -# Option: failregex -# Notes.: regex to match the password failures 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[\w\-.^_]+) -# Values: TEXT -# -# -_daemon = pure-ftpd - failregex = ^%(__prefix_line)s\(.+?@\) \[WARNING\] %(__errmsg)s \[.+\]\s*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = +# Author: Cyril Jaquier +# Modified: Yaroslav Halchenko for pure-ftpd diff --git a/config/filter.d/qmail.conf b/config/filter.d/qmail.conf index f1f47e01..62d499ce 100644 --- a/config/filter.d/qmail.conf +++ b/config/filter.d/qmail.conf @@ -1,8 +1,11 @@ -# Fail2Ban configuration file +# Fail2Ban filters for qmail RBL patches/fake proxies # -# Author: Daniel Black +# the default djb RBL implementation doesn't log any rejections +# so is useless with this filter. # +# One patch is here: # +# http://www.tjsi.com/rblsmtpd/faq/ patch to rblsmtpd [INCLUDES] @@ -12,11 +15,17 @@ before = common.conf _daemon = (?:qmail|rblsmtpd) -# -# These seem to be for two or 3 different patches to qmail or rblsmtpd -# so you'll probably only ever see one of these. - failregex = ^%(__prefix_line)s\d+\.\d+ rblsmtpd: pid \d+ \S+ 4\d\d \S+\s*$ ^%(__prefix_line)s\d+\.\d+ qmail-smtpd: 4\d\d badiprbl: ip rbl: \S+\s*$ ^%(__prefix_line)s\S+ blocked \S+ -\s*$ +ignoreregex = + +# DEV Notes: +# +# These seem to be for two or 3 different patches to qmail or rblsmtpd +# so you'll probably only ever see one of these regex's that match. +# +# ref: https://github.com/fail2ban/fail2ban/pull/386 +# +# Author: Daniel Black diff --git a/config/filter.d/recidive.conf b/config/filter.d/recidive.conf index 617e008a..b29acaf3 100644 --- a/config/filter.d/recidive.conf +++ b/config/filter.d/recidive.conf @@ -1,9 +1,8 @@ -# Fail2Ban configuration file +# Fail2Ban filter for repeat bans # -# Author: Tom Hendrikx, modifications by Amir Caspi -# # This filter monitors the fail2ban log file, and enables you to add long # time bans for ip addresses that get banned by fail2ban multiple times. +# # Reasons to use this: block very persistent attackers for a longer time, # stop receiving email notifications about the same attacker over and # over again. @@ -13,8 +12,6 @@ # drawbacks, namely in that it works only with iptables, or if you use a # different blocking mechanism for this jail versus others (e.g. hostsdeny # for most jails, and shorewall for this one). -# - [INCLUDES] @@ -26,10 +23,10 @@ before = common.conf _daemon = fail2ban\.actions - # The name of the jail that this filter is used for. In jail.conf, name the # jail using this filter 'recidive', or change this line! _jailname = recidive failregex = ^(%(__prefix_line)s|,\d{3} fail2ban.actions:\s+)WARNING\s+\[(?!%(_jailname)s\])(?:.*)\]\s+Ban\s+\s*$ +# Author: Tom Hendrikx, modifications by Amir Caspi diff --git a/config/filter.d/roundcube-auth.conf b/config/filter.d/roundcube-auth.conf index d36f5fef..279c5edd 100644 --- a/config/filter.d/roundcube-auth.conf +++ b/config/filter.d/roundcube-auth.conf @@ -1,6 +1,5 @@ # Fail2Ban configuration file for roundcube web server # -# Author: Teodor Micu & Yaroslav Halchenko & terence namusonge # # @@ -10,17 +9,8 @@ before = common.conf [Definition] -# Option: failregex -# Notes.: regex to match the password 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[\w\-.^_]+) -# Values: TEXT -# failregex = ^\s*(\[(\s[+-][0-9]{4})?\])?(%(__hostname)s roundcube: IMAP Error)?: (FAILED login|Login failed) for .*? from (\. AUTHENTICATE .*)?\s*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# Author: Teodor Micu & Yaroslav Halchenko & terence namusonge diff --git a/config/filter.d/selinux-common.conf b/config/filter.d/selinux-common.conf index 333b43f2..7269e8f7 100644 --- a/config/filter.d/selinux-common.conf +++ b/config/filter.d/selinux-common.conf @@ -1,7 +1,5 @@ # Fail2Ban configuration file for generic SELinux audit messages # -# Author: Daniel Black -# # This file is not intended to be used directly, and should be included into a # filter file which would define following variables. See selinux-ssh.conf as # and example. @@ -13,9 +11,11 @@ # _msg # # Also one of these variables must include . -# + [Definition] failregex = ^type=%(_type)s msg=audit\(:\d+\): (user )?pid=\d+ uid=%(_uid)s auid=%(_auid)s ses=\d+ subj=%(_subj)s msg='%(_msg)s'$ ignoreregex = + +# Author: Daniel Black diff --git a/config/filter.d/selinux-ssh.conf b/config/filter.d/selinux-ssh.conf index 6e563a13..6955094f 100644 --- a/config/filter.d/selinux-ssh.conf +++ b/config/filter.d/selinux-ssh.conf @@ -1,11 +1,6 @@ # Fail2Ban configuration file for SELinux ssh authentication errors # -# Author: Daniel Black -# -# -# Note: USER_LOGIN is ignored as this is the duplicate messsage -# ssh logs after 3 USER_AUTH failures. -# + [INCLUDES] after = selinux-common.conf @@ -22,3 +17,9 @@ _terminal = ssh _msg = op=\S+ acct=(?P<_quote_acct>"?)\S+(?P=_quote_acct) exe="%(_exe)s" hostname=(\?|(\d+\.){3}\d+) addr= terminal=%(_terminal)s res=failed +# DEV Notes: +# +# Note: USER_LOGIN is ignored as this is the duplicate messsage +# ssh logs after 3 USER_AUTH failures. +# +# Author: Daniel Black diff --git a/config/filter.d/sieve.conf b/config/filter.d/sieve.conf index b2af6774..999b68a4 100644 --- a/config/filter.d/sieve.conf +++ b/config/filter.d/sieve.conf @@ -1,7 +1,4 @@ -# Fail2Ban configuration file -# -# Author: Jan Wagner -# +# Fail2Ban filter for sieve authentication failures # [INCLUDES] @@ -10,21 +7,12 @@ # common.local before = common.conf - [Definition] _deamon = (?:cyrus/)?(?:tim)?sieved? -# Option: failregex -# Notes.: regex to match the password failures messages in the logfile. The -# host must be matched by a group named "host". The tag "" can -# be used for standard IP/hostname matching. -# Values: TEXT -# failregex = ^%(__prefix_line)sbadlogin: \S+ ?\[\] \S+ authentication failure$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# Author: Jan Wagner diff --git a/config/filter.d/sogo-auth.conf b/config/filter.d/sogo-auth.conf index 41e5bf46..d56c94f7 100644 --- a/config/filter.d/sogo-auth.conf +++ b/config/filter.d/sogo-auth.conf @@ -1,20 +1,17 @@ -# /etc/fail2ban/filter.d/sogo-auth.conf -# -# Fail2Ban configuration file -# By Arnd Brandes -# SOGo +# Fail2ban filter for SOGo authentcation # +# Log file usually in /var/log/sogo/sogo.log [Definition] -# Option: failregex -# Filter Ban in /var/log/sogo/sogo.log -# Note: the error log may contain multiple hosts, whereas the first one -# is the client and all others are poxys. We match the first one, only failregex = ^ sogod \[\d+\]: SOGoRootPage Login from '' for user '.*' might not have worked( - password policy: \d* grace: -?\d* expire: -?\d* bound: -?\d*)?\s*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# +# DEV Notes: +# +# The error log may contain multiple hosts, whereas the first one +# is the client and all others are poxys. We match the first one, only +# +# Author: Arnd Brandes diff --git a/config/filter.d/sshd-ddos.conf b/config/filter.d/sshd-ddos.conf index 58698ced..1fa87238 100644 --- a/config/filter.d/sshd-ddos.conf +++ b/config/filter.d/sshd-ddos.conf @@ -1,6 +1,4 @@ -# Fail2Ban configuration file -# -# Author: Yaroslav Halchenko +# Fail2Ban ssh filter for at attempted exploit # # The regex here also relates to a exploit: # @@ -20,17 +18,8 @@ before = common.conf _daemon = sshd -# Option: failregex -# Notes.: regex to match the password failures 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[\w\-.^_]+) -# Values: TEXT -# failregex = ^%(__prefix_line)sDid not receive identification string from \s*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# Author: Yaroslav Halchenko diff --git a/config/filter.d/sshd.conf b/config/filter.d/sshd.conf index c4deb03a..08456177 100644 --- a/config/filter.d/sshd.conf +++ b/config/filter.d/sshd.conf @@ -1,7 +1,4 @@ -# Fail2Ban configuration file -# -# Author: Cyril Jaquier -# +# Fail2Ban filter for openssh # [INCLUDES] @@ -15,15 +12,6 @@ before = common.conf _daemon = sshd -# Option: failregex -# Notes.: regex to match the password failures 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[\w\-.^_]+) -# Values: TEXT -# -# - failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from ( via \S+)?\s*$ ^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from \s*$ ^%(__prefix_line)sFailed \S+ for .* from (?: port \d*)?(?: ssh\d*)?(: (ruser .{0,100}|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".{0,100}", client host ".{0,100}")?))?\s*$ @@ -36,8 +24,6 @@ failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|erro ^%(__prefix_line)sUser .+ from not allowed because a group is listed in DenyGroups\s*$ ^%(__prefix_line)sUser .+ from not allowed because none of user's groups are listed in AllowGroups\s*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# Author: Cyril Jaquier, Yaroslav Halchenko, Petr Voralek, Daniel Black diff --git a/config/filter.d/suhosin.conf b/config/filter.d/suhosin.conf index f0bcea77..f125eadc 100644 --- a/config/filter.d/suhosin.conf +++ b/config/filter.d/suhosin.conf @@ -1,6 +1,6 @@ -# Fail2Ban configuration file +# Fail2Ban filter for suhosian PHP hardening # -# Author: Arturo 'Buanzo' Busleiman +# This occurs with lighttpd or directly from the plugin # [INCLUDES] @@ -14,18 +14,15 @@ before = common.conf _daemon = (?:lighttpd|suhosin) -# Option: failregex -# Notes.: regex to match ALERTS as notified by lighttpd's FastCGI Module -# Values: TEXT -# -# https://github.com/stefanesser/suhosin/blob/1fba865ab73cc98a3109f88d85eb82c1bfc29b37/log.c#L161 _lighttpd_prefix = (?:\(mod_fastcgi\.c\.\d+\) FastCGI-stderr:\s) failregex = ^%(__prefix_line)s%(_lighttpd_prefix)s?ALERT - .* \(attacker '', file '.*'(?:, line \d+)?\)$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# DEV Notes: +# +# https://github.com/stefanesser/suhosin/blob/1fba865ab73cc98a3109f88d85eb82c1bfc29b37/log.c#L161 +# +# Author: Arturo 'Buanzo' Busleiman diff --git a/config/filter.d/uwimap-auth.conf b/config/filter.d/uwimap-auth.conf index b166f3fc..f734eb7f 100644 --- a/config/filter.d/uwimap-auth.conf +++ b/config/filter.d/uwimap-auth.conf @@ -1,7 +1,6 @@ -# Fail2Ban configuration file -# -# Author: Amir Caspi +# Fail2Ban filter for uwimap # + [INCLUDES] before = common.conf @@ -14,3 +13,5 @@ failregex = ^%(__prefix_line)sLogin (?:failed|excessive login failures|disabled| ^%(__prefix_line)sFailed .* override of user=.* host=.*\[\]\s*$ ignoreregex = + +# Author: Amir Caspi diff --git a/config/filter.d/vsftpd.conf b/config/filter.d/vsftpd.conf index e72b89eb..59ce49a3 100644 --- a/config/filter.d/vsftpd.conf +++ b/config/filter.d/vsftpd.conf @@ -1,7 +1,4 @@ -# Fail2Ban configuration file -# -# Author: Cyril Jaquier -# +# Fail2Ban filter for vsftp # [INCLUDES] @@ -13,18 +10,9 @@ before = common.conf __pam_re=\(?pam_unix(?:\(\S+\))?\)?:? _daemon = vsftpd -# Option: failregex -# Notes.: regex to match the password failures 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[\w\-.^_]+) -# Values: TEXT -# failregex = ^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=(ftp)? ruser=\S* rhost=(?:\s+user=.*)?\s*$ ^ \[pid \d+\] \[.+\] FAIL LOGIN: Client ""\s*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# Author: Cyril Jaquier diff --git a/config/filter.d/webmin-auth.conf b/config/filter.d/webmin-auth.conf index b98075b5..18bf6361 100644 --- a/config/filter.d/webmin-auth.conf +++ b/config/filter.d/webmin-auth.conf @@ -1,8 +1,4 @@ -# Fail2Ban configuration file -# -# Author: Cyril Jaquier -# Rule by : Delvit Guillaume -# +# Fail2Ban filter for webmin # [INCLUDES] @@ -15,10 +11,14 @@ _daemon = webmin [Definition] -# patern : webmin[15673]: Non-existent login as toto from 86.0.6.217 -# webmin[29544]: Invalid login as root from 86.0.6.217 -# failregex = ^%(__prefix_line)sNon-existent login as .+ from \s*$ ^%(__prefix_line)sInvalid login as .+ from \s*$ ignoreregex = + +# DEV Notes: +# +# pattern : webmin[15673]: Non-existent login as toto from 86.0.6.217 +# webmin[29544]: Invalid login as root from 86.0.6.217 +# +# Rule Author: Delvit Guillaume diff --git a/config/filter.d/wuftpd.conf b/config/filter.d/wuftpd.conf index de98d02d..942de82a 100644 --- a/config/filter.d/wuftpd.conf +++ b/config/filter.d/wuftpd.conf @@ -1,7 +1,5 @@ # Fail2Ban configuration file for wuftpd # -# Author: Yaroslav Halchenko -# # [INCLUDES] @@ -14,14 +12,8 @@ before = common.conf _daemon = wu-ftpd -# Option: failregex -# Notes.: regex to match the password failures messages in the logfile. -# Values: TEXT -# failregex = ^%(__prefix_line)sfailed login from \S+ \[\]\s*$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# Author: Yaroslav Halchenko diff --git a/config/filter.d/xinetd-fail.conf b/config/filter.d/xinetd-fail.conf index 253ce15d..d75e3d66 100644 --- a/config/filter.d/xinetd-fail.conf +++ b/config/filter.d/xinetd-fail.conf @@ -1,6 +1,6 @@ -# Fail2Ban configuration file +# Fail2Ban filter for xinetd failures # -# Author: Guido Bozzetto +# Cfr.: /var/log/(daemon\.|sys)log # # @@ -10,29 +10,18 @@ # common.local before = common.conf - [Definition] _daemon = xinetd -# Option: failregex -# Notes.: regex to match the password failures 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[\w\-.^_]+) -# Values: TEXT -# -# Cfr.: /var/log/(daemon\.|sys)log -# libwrap => tcp wrappers: hosts.(allow|deny) -# address => xinetd: deny_from|only_from -# load => xinetd: max_load (temporary problem) -# - failregex = ^%(__prefix_line)sFAIL: \S+ address from=$ ^%(__prefix_line)sFAIL: \S+ libwrap from=$ -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# DEV Notes: +# +# libwrap => tcp wrappers: hosts.(allow|deny) +# address => xinetd: deny_from|only_from +# +# Author: Guido Bozzetto From c3f9c9aa6033acab4c5ab06161ff2845aba6e49e Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 00:21:30 +1100 Subject: [PATCH 019/165] BF: filter.d/dropbear Add PAM failures which is in dropbear-2013.60 in srv-authpam.c Patch http://www.unchartedbackwaters.co.uk/files/dropbear/dropbear-0.52.patch obviously has exit with lower case e so adjust regex for both. svr-authpasswd.c in 2013.60 (at bottom) for second regex ends after the IP so the regex was altered. .*\s* can be compressed to .* --- ChangeLog | 3 ++ config/filter.d/dropbear.conf | 59 ++++++++++++++--------------------- 2 files changed, 27 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index f77d9491..a29caddd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -37,6 +37,8 @@ ver. 0.8.11 (2013/XX/XXX) - loves-unittests * filter.d/roundcube-auth - timezone offset can be positive or negative * action.d/bsd-ipfw - action option unsed. Fixed to blocktype for consistency. default to port unreach instead of deny + * filter.d/dropbear - fix regexs to match standard dropbear and the patched + http://www.unchartedbackwaters.co.uk/files/dropbear/dropbear-0.52.patch Rolf Fokkens * action.d/dshield.conf and complain.conf -- reorder mailx arguments. https://bugzilla.redhat.com/show_bug.cgi?id=998020 @@ -104,6 +106,7 @@ ver. 0.8.11 (2013/XX/XXX) - loves-unittests * filter.d/webmin - anchored regex at start * filter.d/qmail - rewrote regex to anchor at start. Added regex for another "in the wild" patch to rblsmtp. + * filter.d/dropbear - add PAM is in dropbear-2013.60 Daniel Black & Georgiy Mernov & ftoppi & Мернов Георгий * filter.d/exim.conf -- regex hardening and extra failure examples in sample logs diff --git a/config/filter.d/dropbear.conf b/config/filter.d/dropbear.conf index 350747c6..54d8166b 100644 --- a/config/filter.d/dropbear.conf +++ b/config/filter.d/dropbear.conf @@ -1,8 +1,15 @@ -# Fail2Ban configuration file +# Fail2Ban filter for dropbear # -# Author: Francis Russell -# Zak B. Elep +# NOTE: The regex below is ONLY intended to work with a patched +# version of Dropbear as described here: +# http://www.unchartedbackwaters.co.uk/pyblosxom/static/patches +# ^%(__prefix_line)sexit before auth from .*\s*$ # +# The standard Dropbear output doesn't provide enough information to +# ban all types of attack. The Dropbear patch adds IP address +# information to the 'exit before auth' message which is always +# produced for any form of non-successful login. It is that message +# which this file matches. # # More information: http://bugs.debian.org/546913 @@ -12,41 +19,23 @@ # common.local before = common.conf - [Definition] _daemon = dropbear -# Option: failregex -# Notes.: regex to match the password failures 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 +failregex = ^%(__prefix_line)s[Ll]ogin attempt for nonexistent user ('.*' )?from :.*$ + ^%(__prefix_line)s[Bb]ad (PAM )?password attempt for .+ from .*$ + ^%(__prefix_line)s[Ee]xit before auth \(user '.+', \d+ fails\): Max auth tries reached - user '.+' from :\d+\s*$ -# These match the unmodified dropbear messages. It isn't possible to -# match the source of the 'exit before auth' messages from dropbear. -# -failregex = ^%(__prefix_line)s(L|l)ogin attempt for nonexistent user ('.*' )?from :.*\s*$ - ^%(__prefix_line)s(B|b)ad password attempt for .+ from :.*\s*$ - ^%(__prefix_line)sExit before auth \(user '.+', \d+ fails\): Max auth tries reached - user '.+' from :\d+\s*$ - -# The only line we need to match with the modified dropbear. - -# NOTE: The failregex below is ONLY intended to work with a patched -# version of Dropbear as described here: -# http://www.unchartedbackwaters.co.uk/pyblosxom/static/patches -# -# The standard Dropbear output doesn't provide enough information to -# ban all types of attack. The Dropbear patch adds IP address -# information to the 'exit before auth' message which is always -# produced for any form of non-successful login. It is that message -# which this file matches. - -# failregex = ^%(__prefix_line)sexit before auth from .*\s*$ - -# Option: ignoreregex -# Notes.: regex to ignore. If this regex matches, the line is ignored. -# Values: TEXT -# ignoreregex = + +# DEV Notes: +# +# The first two regexs here match the unmodified dropbear messages. It isn't +# possible to match the source of the 'exit before auth' messages from dropbear +# as they don't include the "from " bit. +# +# The second last failregex line we need to match with the modified dropbear. +# +# Author: Francis Russell +# Zak B. Elep From 8441539988bcec009bfd067ff2f0e6cd8bb23cdd Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 00:43:02 +1100 Subject: [PATCH 020/165] DOC: reorder bits of changelog The enhancements list was too long an maybe not always appropriate. Reclassified changes to filters to catch new versions as bug fixes since the new version of the application is effectively broken. Moved large enhancements to New Features. --- ChangeLog | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index f77d9491..0a4fd144 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,13 +30,27 @@ ver. 0.8.11 (2013/XX/XXX) - loves-unittests mode has failed (e.g. due to incorrect syntax). Closes gh-353 Daniel Black & Мернов Георгий * filter.d/dovecot.conf -- Fix when no TLS enabled - line doesn't end in , + Daniel Black & Georgiy Mernov & ftoppi & Мернов Георгий + * filter.d/exim.conf -- regex hardening and extra failure examples in + sample logs + * filter.d/named-refused.conf - BIND 9.9.3 regex changes + Daniel Black & Sebastian Arcus + * filter.d/asterisk -- more regexes Daniel Black * action.d/hostsdeny -- NOTE: new dependancy 'ed'. Switched to use 'ed' across all platforms to ensure permissions are the same before and after a ban - closes gh-266. hostsdeny supports daemon_list now too. + * action.d/bsd-ipfw - action option unsed. Change blocktype to port unreach + instead of deny for consistancy. * filter.d/roundcube-auth - timezone offset can be positive or negative - * action.d/bsd-ipfw - action option unsed. Fixed to blocktype for - consistency. default to port unreach instead of deny + * filter.d/{asterisk,assp,dovecot,proftpd}.conf -- regex hardening + and extra failure examples in sample logs + * filter.d/apache-auth - added expressions for mod_authz, mod_auth and + mod_auth_digest failures. + * filter.d/recidive -- support f2b syslog target and anchor regex at start + * filter.d/mysqld-auth.conf - mysql can use syslog + * filter.d/sshd - regex enhancements to support openssh-6.3. Closes Debian + bug #722970 Rolf Fokkens * action.d/dshield.conf and complain.conf -- reorder mailx arguments. https://bugzilla.redhat.com/show_bug.cgi?id=998020 @@ -61,6 +75,8 @@ ver. 0.8.11 (2013/XX/XXX) - loves-unittests * action.d/osx-afctl - an action based on afctl for osx Daniel Black & ykimon * filter.d/3proxy.conf -- filter added + * fail2ban-regex - now generates http://www.debuggex.com urls for debugging + regular expressions with the -D parameter. Daniel Black * filter.d/exim-spam.conf -- a splitout of exim's spam regexes with additions for greater control over filtering spam. @@ -83,33 +99,15 @@ ver. 0.8.11 (2013/XX/XXX) - loves-unittests * jail.conf now has asterisk jail - no need for asterisk-tcp and asterisk-udp. Users should replace existing jails with asterisk to reduce duplicate parsing of the asterisk log file. - * filter.d/suhosin - regex anchor at start - * filter.d/{asterisk,assp,dovecot,proftpd}.conf -- regex hardening - and extra failure examples in sample logs - * filter.d/apache-auth - added expressions for mod_authz, mod_auth and - mod_auth_digest failures. - * filter.d/recidive -- support f2b syslog target and anchor regex at start + * filter.d/{suhosin,pam-generic,gssftpd,sogo-auth,webmin}- regex anchor at + start * filter.d/vsftpd - anchored regex at start. disable old pam format regex * filter.d/pam-generic - added syslog prefix. Disabled support for linux-pam before version 0.99.2.0 (2005) - * filter.d/gssftpd - anchored regex at start - * filter.d/sogo-auth - anchor regex at start - * filter.d/mysqld-auth.conf - mysql can use syslog * filter.d/postfix-sasl - renamed from sasl, anchor at start and base on syslog - * fail2ban-regex - now generates http://www.debuggex.com urls for debugging - regular expressions with the -D parameter. - * filter.d/sshd - regex enhancements to support openssh-6.3. Closes Debian - bug #722970 - * filter.d/webmin - anchored regex at start * filter.d/qmail - rewrote regex to anchor at start. Added regex for another "in the wild" patch to rblsmtp. - Daniel Black & Georgiy Mernov & ftoppi & Мернов Георгий - * filter.d/exim.conf -- regex hardening and extra failure examples in - sample logs - * filter.d/named-refused.conf - BIND 9.9.3 regex changes - Daniel Black & Sebastian Arcus - * filter.d/asterisk -- more regexes Yaroslav Halchenko * fail2ban-regex -- refactored to provide more details (missing and ignored lines, control over logging, etc) while maintaining look&feel From 93de46ac72e0e7e76f409d2992e36c2fdc80d547 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 00:52:47 +1100 Subject: [PATCH 021/165] BF: maxretry=5 for ssh as per DEVELOP. align = in jail.conf --- config/jail.conf | 53 +++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/config/jail.conf b/config/jail.conf index c6d3384f..23e30c83 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -436,33 +436,34 @@ logpath = /var/log/exim/mainlog [exim-spam] enabled = false -filter = exim-spam -action = iptables-multiport[name=exim-spam,port="25,465,587"] +filter = exim-spam +action = iptables-multiport[name=exim-spam,port="25,465,587"] logpath = /var/log/exim/mainlog [perdition] enabled = false -filter = perdition -action = iptables-multiport[name=perdition,port="110,143,993,995"] +filter = perdition +action = iptables-multiport[name=perdition,port="110,143,993,995"] logpath = /var/log/maillog [uwimap-auth] enabled = false -filter = uwimap-auth -action = iptables-multiport[name=uwimap-auth,port="110,143,993,995"] +filter = uwimap-auth +action = iptables-multiport[name=uwimap-auth,port="110,143,993,995"] logpath = /var/log/maillog [osx-ssh-ipfw] -enabled = false -filter = sshd -action = osx-ipfw -logpath = /var/log/secure.log +enabled = false +filter = sshd +action = osx-ipfw +logpath = /var/log/secure.log +maxretry = 5 [ssh-apf] @@ -471,22 +472,24 @@ enabled = false filter = sshd action = apf[name=SSH] logpath = /var/log/secure +maxretry = 5 [osx-ssh-afctl] -enabled = false -filter = sshd -action = osx-afctl[bantime=600] -logpath = /var/log/secure.log +enabled = false +filter = sshd +action = osx-afctl[bantime=600] +logpath = /var/log/secure.log +maxretry = 5 [webmin-auth] enabled = false -filter = webmin-auth -action = iptables-multiport[name=webmin,port="10000"] -logpath = /var/log/auth.log +filter = webmin-auth +action = iptables-multiport[name=webmin,port="10000"] +logpath = /var/log/auth.log # dovecot defaults to logging to the mail syslog facility @@ -494,22 +497,22 @@ logpath = /var/log/auth.log [dovecot] enabled = false -filter = dovecot -action = iptables-multiport[name=dovecot, port="pop3,pop3s,imap,imaps,submission,smtps,sieve", protocol=tcp] +filter = dovecot +action = iptables-multiport[name=dovecot, port="pop3,pop3s,imap,imaps,submission,smtps,sieve", protocol=tcp] logpath = /var/log/mail.log [dovecot-auth] enabled = false -filter = dovecot -action = iptables-multiport[name=dovecot-auth, port="pop3,pop3s,imap,imaps,submission,smtps,sieve", protocol=tcp] +filter = dovecot +action = iptables-multiport[name=dovecot-auth, port="pop3,pop3s,imap,imaps,submission,smtps,sieve", protocol=tcp] logpath = /var/log/secure [selinux-ssh] enabled = false -filter = selinux-ssh -action = iptables[name=SELINUX-SSH, port=ssh, protocol=tcp] -logpath = /var/log/audit/audit.log - +filter = selinux-ssh +action = iptables[name=SELINUX-SSH, port=ssh, protocol=tcp] +logpath = /var/log/audit/audit.log +maxretry = 5 From c19a685ee3d37c53d3df31fd7921fab4d4b6bd51 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 00:58:48 +1100 Subject: [PATCH 022/165] DOC: version 0.8.11.pre --- ChangeLog | 4 ++-- common/version.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index f77d9491..2e1480be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,10 +4,10 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ================================================================================ -Fail2Ban (version 0.8.10) 2013/06/12 +Fail2Ban (version 0.8.11.pre) 2013/10/30 ================================================================================ -ver. 0.8.11 (2013/XX/XXX) - loves-unittests +ver. 0.8.11 (2013/11/XXX) - loves-unittests and tight DoS free filter regexes ----------- - Fixes: diff --git a/common/version.py b/common/version.py index 87cb5020..a0cb94ea 100644 --- a/common/version.py +++ b/common/version.py @@ -24,4 +24,4 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko" __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko" __license__ = "GPL" -version = "0.8.10.dev" +version = "0.8.11.pre1" From 363d53e8d796fe42d33ecb57030aa6f425978289 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 01:00:38 +1100 Subject: [PATCH 023/165] update man pages for release --- man/fail2ban-client.1 | 6 ++-- man/fail2ban-regex.1 | 75 +++++++++++++++++++++++++------------------ man/fail2ban-server.1 | 6 ++-- 3 files changed, 49 insertions(+), 38 deletions(-) diff --git a/man/fail2ban-client.1 b/man/fail2ban-client.1 index a6eb461e..057f3410 100644 --- a/man/fail2ban-client.1 +++ b/man/fail2ban-client.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.2. -.TH FAIL2BAN-CLIENT "1" "June 2013" "fail2ban-client v0.8.10" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.12. +.TH FAIL2BAN-CLIENT "1" "October 2013" "fail2ban-client v0.8.11.pre1" "User Commands" .SH NAME fail2ban-client \- configure and control the server .SH SYNOPSIS .B fail2ban-client [\fIOPTIONS\fR] \fI\fR .SH DESCRIPTION -Fail2Ban v0.8.10 reads log file that contains password failure report +Fail2Ban v0.8.11.pre1 reads log file that contains password failure report and bans the corresponding IP addresses using firewall rules. .SH OPTIONS .TP diff --git a/man/fail2ban-regex.1 b/man/fail2ban-regex.1 index 379cd761..46d260a6 100644 --- a/man/fail2ban-regex.1 +++ b/man/fail2ban-regex.1 @@ -1,56 +1,67 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.2. -.TH FAIL2BAN-REGEX "1" "June 2013" "fail2ban-regex v0.8.10" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.12. +.TH FAIL2BAN-REGEX "1" "October 2013" "fail2ban-regex 0.8.11.pre1" "User Commands" .SH NAME fail2ban-regex \- test Fail2ban "failregex" option .SH SYNOPSIS .B fail2ban-regex [\fIOPTIONS\fR] \fI \fR[\fIIGNOREREGEX\fR] .SH DESCRIPTION -Fail2Ban v0.8.10 reads log file that contains password failure report +Fail2Ban reads log file that contains password failure report and bans the corresponding IP addresses using firewall rules. .PP This tools can test regular expressions for "fail2ban". .SH OPTIONS .TP -\fB\-h\fR, \fB\-\-help\fR -display this help message +\fB\-\-version\fR +show program's version number and exit .TP -\fB\-V\fR, \fB\-\-version\fR -print the version +\fB\-h\fR, \fB\-\-help\fR +show this help message and exit +.TP +\fB\-l\fR LOG_LEVEL, \fB\-\-log\-level\fR=\fILOG_LEVEL\fR +Log level for the Fail2Ban logger to use .TP \fB\-v\fR, \fB\-\-verbose\fR -verbose output -.SH LOG +Be verbose in output .TP -\fBstring\fR -a string representing a log line +\fB\-D\fR, \fB\-\-debuggex\fR +Produce debuggex.com urls for debugging there .TP -\fBfilename\fR -path to a log file (\fI/var/log/auth.log\fP) -.SH REGEX +\fB\-\-print\-all\-missed\fR +Either to print all missed lines .TP -\fBstring\fR -a string representing a 'failregex' +\fB\-\-print\-all\-ignored\fR +Either to print all ignored lines .TP -\fBfilename\fR -path to a filter file (filter.d/sshd.conf) -.SS "IgnoreRegex:" +\fB\-t\fR, \fB\-\-log\-traceback\fR +Enrich log\-messages with compressed tracebacks .TP -\fBstring\fR -a string representing an 'ignoreregex' -.TP -\fBfilename\fR -path to a filter file (filter.d/sshd.conf) -.SH AUTHOR -Written by Cyril Jaquier . -Many contributions by Yaroslav O. Halchenko . +\fB\-\-full\-traceback\fR +Either to make the tracebacks full, not compressed (as +by default) .SH "REPORTING BUGS" Report bugs to https://github.com/fail2ban/fail2ban/issues -.SH COPYRIGHT -Copyright \(co 2004\-2008 Cyril Jaquier -.br -Copyright of modifications held by their respective authors. -Licensed under the GNU General Public License v2 (GPL). +.SS "LOG:" +.TP +string +a string representing a log line +.TP +filename +path to a log file (/var/log/auth.log) +.SS "REGEX:" +.TP +string +a string representing a 'failregex' +.TP +filename +path to a filter file (filter.d/sshd.conf) +.SS "IGNOREREGEX:" +.TP +string +a string representing an 'ignoreregex' +.TP +filename +path to a filter file (filter.d/sshd.conf) .SH "SEE ALSO" .br fail2ban-client(1) diff --git a/man/fail2ban-server.1 b/man/fail2ban-server.1 index 3851db91..7e09b49e 100644 --- a/man/fail2ban-server.1 +++ b/man/fail2ban-server.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.2. -.TH FAIL2BAN-SERVER "1" "June 2013" "fail2ban-server v0.8.10" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.12. +.TH FAIL2BAN-SERVER "1" "October 2013" "fail2ban-server v0.8.11.pre1" "User Commands" .SH NAME fail2ban-server \- start the server .SH SYNOPSIS .B fail2ban-server [\fIOPTIONS\fR] .SH DESCRIPTION -Fail2Ban v0.8.10 reads log file that contains password failure report +Fail2Ban v0.8.11.pre1 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 From 3a4ba2dba62b2812d8979d03cb362f4569868b47 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 01:11:42 +1100 Subject: [PATCH 024/165] DOC: ChangeLog - TODO top summary before final release --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2e1480be..e9c1f317 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,8 @@ Fail2Ban (version 0.8.11.pre) 2013/10/30 ver. 0.8.11 (2013/11/XXX) - loves-unittests and tight DoS free filter regexes ----------- +TODO write summary here + - Fixes: Daniel Black & Marcel Dopita * filter.d/apache-auth -- fixed and apache auth samples provide. closes #286 From a5ac0a49e7aac0c7d7fa53ea3fe5747b6b428530 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 01:12:04 +1100 Subject: [PATCH 025/165] DOC: Version number changes in DEVELOP --- DEVELOP | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DEVELOP b/DEVELOP index 51314078..edaee92a 100644 --- a/DEVELOP +++ b/DEVELOP @@ -686,7 +686,7 @@ Releasing # Wait for feedback from distributors -# Ensure the version is correct in ./common/version.py +# Ensure the version is correct in ./common/version.py and at the top of ChangeLog # Ensure the MANIFEST is complete @@ -699,21 +699,21 @@ Look for errors like: Which indicates that testcases/files/logs/mysqld.log has been moved or is a directory - tar -C /tmp -jxf dist/fail2ban-0.8.10.dev.tar.bz2 + tar -C /tmp -jxf dist/fail2ban-0.8.11.dev.tar.bz2 # clean up current direcory - diff -rul --exclude \*.pyc . /tmp/fail2ban-0.8.10.dev/ + diff -rul --exclude \*.pyc . /tmp/fail2ban-0.8.11.dev/ # Only differences should be files that you don't want distributed. - cd /tmp/fail2ban-0.8.10.dev/ && ./fail2ban-testcases-all + cd /tmp/fail2ban-0.8.11.dev/ && ./fail2ban-testcases-all # Add/finalize the corresponding entry in the ChangeLog To generate a list of committers use e.g. - git shortlog -sn 0.8.10.. | sed -e 's,^[ 0-9\t]*,,g' | tr '\n' '\|' | sed -e 's:|:, :g' + git shortlog -sn 0.8.11.. | sed -e 's,^[ 0-9\t]*,,g' | tr '\n' '\|' | sed -e 's:|:, :g' Ensure the top of the ChangeLog has the right version and current date. From 8ac6081555dd95574692e93c0c985a28582c6595 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 01:23:00 +1100 Subject: [PATCH 026/165] ENH: fix to use upstream --remove-rules https://fedorahosted.org/firewalld/ticket/10 --- config/action.d/firewall-cmd-direct-new.conf | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/config/action.d/firewall-cmd-direct-new.conf b/config/action.d/firewall-cmd-direct-new.conf index ac06aa57..0f7388a2 100644 --- a/config/action.d/firewall-cmd-direct-new.conf +++ b/config/action.d/firewall-cmd-direct-new.conf @@ -15,15 +15,8 @@ actionstart = firewall-cmd --direct --add-chain ipv4 filter fail2ban- firewall-cmd --direct --add-rule ipv4 filter fail2ban- 1000 -j RETURN firewall-cmd --direct --add-rule ipv4 filter 0 -m state --state NEW -p --dport -j fail2ban- -# The following rule does not work, because firewalld keeps its own database of firewall rules. -# firewall-cmd --direct --passthrough ipv4 -F fail2ban- -# The better rule would be the following, but firewall-cmd has not implemented this command with firewalld-0.3.3-2.fc19 . -# firewall-cmd --direct --flush-chain ipv4 filter fail2ban- -# The following is a workaround using a loop to implement the --flush-chain command. -# https://fedorahosted.org/firewalld/ticket/10 - actionstop = firewall-cmd --direct --remove-rule ipv4 filter 0 -m state --state NEW -p --dport -j fail2ban- - ( IFS='|' ; for r in $( firewall-cmd --direct --get-rules ipv4 filter fail2ban- | tr '\n' '|' ) ; do eval firewall-cmd --direct --remove-rule ipv4 filter fail2ban- $r ; done ) + firewall-cmd --direct --remove-rules ipv4 filter fail2ban- firewall-cmd --direct --remove-chain ipv4 filter fail2ban- actioncheck = firewall-cmd --direct --get-chains ipv4 filter | grep -q 'fail2ban-[ \t]' From 5eddd5d12dbb7a4d82d74598df2c9efb548f2e12 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 09:10:59 +1100 Subject: [PATCH 027/165] DOC: document required firewalld version as > 0.3.7.1 --- config/action.d/firewall-cmd-direct-new.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/action.d/firewall-cmd-direct-new.conf b/config/action.d/firewall-cmd-direct-new.conf index 0f7388a2..3fd4e52b 100644 --- a/config/action.d/firewall-cmd-direct-new.conf +++ b/config/action.d/firewall-cmd-direct-new.conf @@ -3,7 +3,8 @@ # Author: Edgar Hoch # Copied from iptables-new.conf and modified for use with firewalld by Edgar Hoch. # It uses "firewall-cmd" instead of "iptables". -# firewall-cmd is based on the command of version firewalld-0.3.4-1.fc19. +# +# Because of the --remove-rules in stop it requires a version AFTER (but not including) 0.3.7.1 [INCLUDES] From fff996c8df077f996035e1caf3038ae863c1689c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 10:26:49 +1100 Subject: [PATCH 028/165] ENH: fix fail2ban-regex output to generate a man page with copyright notices --- fail2ban-regex | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fail2ban-regex b/fail2ban-regex index 7c525157..18e2a5df 100755 --- a/fail2ban-regex +++ b/fail2ban-regex @@ -23,7 +23,6 @@ and bans the corresponding IP addresses using firewall rules. This tools can test regular expressions for "fail2ban". -Report bugs to https://github.com/fail2ban/fail2ban/issues """ __author__ = "Cyril Jaquier, Yaroslav Halchenko" @@ -73,6 +72,7 @@ def pprint_list(l, header=None): s = '' print s + "| " + "\n| ".join(l) + '\n`-' + def get_opt_parser(): # use module docstring for help output p = OptionParser( @@ -89,6 +89,15 @@ REGEX: IGNOREREGEX: string a string representing an 'ignoreregex' filename path to a filter file (filter.d/sshd.conf) + +Copyright (c) 2004-2008 Cyril Jaquier, 2008- Fail2Ban Contributors +Copyright of modifications held by their respective authors. +Licensed under the GNU General Public License v2 (GPL). + +Written by Cyril Jaquier . +Many contributions by Yaroslav O. Halchenko and Steven Hiscocks. + +Report bugs to https://github.com/fail2ban/fail2ban/issues """, version="%prog " + version) @@ -110,7 +119,6 @@ IGNOREREGEX: help="Enrich log-messages with compressed tracebacks"), Option("--full-traceback", action='store_true', help="Either to make the tracebacks full, not compressed (as by default)"), - ]) return p From f860307b579ec3022f75dc3dff60d4c5de6fca06 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 10:27:30 +1100 Subject: [PATCH 029/165] DOC: update man pages. Add references to jail.conf from fail2ban-client man page --- man/fail2ban-client.1 | 1 + man/fail2ban-client.h2m | 1 + man/fail2ban-regex.1 | 50 ++++++++++++++++++++++++----------------- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/man/fail2ban-client.1 b/man/fail2ban-client.1 index 057f3410..aab2dde4 100644 --- a/man/fail2ban-client.1 +++ b/man/fail2ban-client.1 @@ -274,3 +274,4 @@ Licensed under the GNU General Public License v2 (GPL). .SH "SEE ALSO" .br fail2ban-server(1) +jail.conf(5) diff --git a/man/fail2ban-client.h2m b/man/fail2ban-client.h2m index 9ae9c3f2..b5300463 100644 --- a/man/fail2ban-client.h2m +++ b/man/fail2ban-client.h2m @@ -10,3 +10,4 @@ fail2ban-client \- configure and control the server [see also] .br fail2ban-server(1) +jail.conf(5) diff --git a/man/fail2ban-regex.1 b/man/fail2ban-regex.1 index 46d260a6..4a0e272b 100644 --- a/man/fail2ban-regex.1 +++ b/man/fail2ban-regex.1 @@ -10,6 +10,27 @@ Fail2Ban reads log file that contains password failure report and bans the corresponding IP addresses using firewall rules. .PP This tools can test regular expressions for "fail2ban". +.SS "LOG:" +.TP +string +a string representing a log line +.TP +filename +path to a log file (/var/log/auth.log) +.SS "REGEX:" +.TP +string +a string representing a 'failregex' +.TP +filename +path to a filter file (filter.d/sshd.conf) +.SS "IGNOREREGEX:" +.TP +string +a string representing an 'ignoreregex' +.TP +filename +path to a filter file (filter.d/sshd.conf) .SH OPTIONS .TP \fB\-\-version\fR @@ -39,29 +60,16 @@ Enrich log\-messages with compressed tracebacks \fB\-\-full\-traceback\fR Either to make the tracebacks full, not compressed (as by default) +.SH AUTHOR +Written by Cyril Jaquier . +Many contributions by Yaroslav O. Halchenko and Steven Hiscocks. .SH "REPORTING BUGS" Report bugs to https://github.com/fail2ban/fail2ban/issues -.SS "LOG:" -.TP -string -a string representing a log line -.TP -filename -path to a log file (/var/log/auth.log) -.SS "REGEX:" -.TP -string -a string representing a 'failregex' -.TP -filename -path to a filter file (filter.d/sshd.conf) -.SS "IGNOREREGEX:" -.TP -string -a string representing an 'ignoreregex' -.TP -filename -path to a filter file (filter.d/sshd.conf) +.SH COPYRIGHT +Copyright \(co 2004\-2008 Cyril Jaquier, 2008\- Fail2Ban Contributors +.br +Copyright of modifications held by their respective authors. +Licensed under the GNU General Public License v2 (GPL). .SH "SEE ALSO" .br fail2ban-client(1) From 4ec0e3f0874224af0a5a1127ecb80d1758751d1a Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 10:51:37 +1100 Subject: [PATCH 030/165] DOC: version 0.8.11.pre1 --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2cd0d78b..ac97ebd5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,7 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ================================================================================ -Fail2Ban (version 0.8.11.pre) 2013/10/30 +Fail2Ban (version 0.8.11.pre1) 2013/10/30 ================================================================================ ver. 0.8.11 (2013/11/XXX) - loves-unittests and tight, DoS free, filter regexes From 6db9e64934387037c95301e28f8064a9541ce7ca Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 10:56:45 +1100 Subject: [PATCH 031/165] DOC: final updates to release doco --- DEVELOP | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DEVELOP b/DEVELOP index edaee92a..9eabf440 100644 --- a/DEVELOP +++ b/DEVELOP @@ -735,6 +735,10 @@ Which indicates that testcases/files/logs/mysqld.log has been moved or is a dire python setup.py bdist_rpm python setup.py upload +# Prepare a release notice https://github.com/fail2ban/fail2ban/releases/new + + Update the binaries and tag the release + # Run the following and update the wiki with output: python -c 'import common.protocol; common.protocol.printWiki()' From 5cefb8aff96e2aa0ce49cba77463e4a0fa44fbb6 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 11:30:07 +1100 Subject: [PATCH 032/165] BF/DOC: fix hopefully final MANIFEST and release instructions --- DEVELOP | 5 ++--- MANIFEST | 26 ++++++++++++++------------ 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/DEVELOP b/DEVELOP index 9eabf440..bd31eb0f 100644 --- a/DEVELOP +++ b/DEVELOP @@ -728,16 +728,15 @@ Which indicates that testcases/files/logs/mysqld.log has been moved or is a dire ./fail2ban-testcases-all -# Prepare/upload source and rpm binary distributions +# Prepare source and rpm binary distributions - python setup.py check python setup.py sdist python setup.py bdist_rpm python setup.py upload # Prepare a release notice https://github.com/fail2ban/fail2ban/releases/new - Update the binaries and tag the release + Upload the source/binaries from the dist directory and tag the release # Run the following and update the wiki with output: diff --git a/MANIFEST b/MANIFEST index 8db7d09f..43927a7a 100644 --- a/MANIFEST +++ b/MANIFEST @@ -46,17 +46,6 @@ server/banmanager.py server/datetemplate.py server/mytime.py server/failregex.py -config/action.d/apf.conf -config/action.d/osx-afctl.conf -config/action.d/osx-ipfw.conf -config/action.d/sendmail-common.conf -config/filter.d/3proxy.conf -config/filter.d/apache-common.conf -config/filter.d/apache-common.conf.orig -config/filter.d/exim-common.conf -config/filter.d/exim-spam.conf -config/filter.d/perdition.conf -config/filter.d/uwimap-auth.conf testcases/actionstestcase.py testcases/dummyjail.py testcases/files/testcase-usedns.log @@ -101,6 +90,7 @@ testcases/files/logs/php-url-fopen testcases/files/logs/qmail testcases/files/logs/recidive testcases/files/logs/sieve +testcases/files/logs/selinux-ssh testcases/files/logs/suhosin testcases/files/logs/uwimap-auth testcases/files/logs/wuftpd @@ -177,8 +167,20 @@ config/filter.d/lighttpd-auth.conf config/filter.d/recidive.conf config/filter.d/roundcube-auth.conf config/filter.d/assp.conf -config/filter.d/mysqld-auth.conf config/filter.d/sogo-auth.conf +config/filter.d/mysqld-auth.conf +config/filter.d/selinux-common.conf +config/filter.d/selinux-ssh.conf +config/filter.d/3proxy.conf +config/filter.d/apache-common.conf +config/filter.d/exim-common.conf +config/filter.d/exim-spam.conf +config/filter.d/perdition.conf +config/filter.d/uwimap-auth.conf +config/action.d/apf.conf +config/action.d/osx-afctl.conf +config/action.d/osx-ipfw.conf +config/action.d/sendmail-common.conf config/action.d/bsd-ipfw.conf config/action.d/dummy.conf config/action.d/firewall-cmd-direct-new.conf From a9fe3d5df90dffa600324eba0e3a1915ad28666e Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 31 Oct 2013 14:44:14 +1100 Subject: [PATCH 033/165] DOC: alter release notes a bit more and versions in README.md --- DEVELOP | 121 ++++++++++++++++++++++++++++++++---------------------- README.md | 6 +-- 2 files changed, 74 insertions(+), 53 deletions(-) diff --git a/DEVELOP b/DEVELOP index bd31eb0f..a8f8899f 100644 --- a/DEVELOP +++ b/DEVELOP @@ -669,6 +669,61 @@ Releasing * https://bugzilla.redhat.com/buglist.cgi?query_format=advanced&bug_status=NEW&bug_status=ASSIGNED&component=fail2ban&classification=Red%20Hat&classification=Fedora * http://www.freebsd.org/cgi/query-pr-summary.cgi?text=fail2ban +# Make sure the tests pass + + ./fail2ban-testcases-all + +# Ensure the version is correct + + in: + * ./common/version.py + * top of ChangeLog + * README.md + +# Ensure the MANIFEST is complete + +Run: + + python setup.py sdist + +Look for errors like: + 'testcases/files/logs/mysqld.log' not a regular file -- skipping + +Which indicates that testcases/files/logs/mysqld.log has been moved or is a directory + + tar -C /tmp -jxf dist/fail2ban-0.8.11.tar.bz2 + +# clean up current direcory + + diff -rul --exclude \*.pyc . /tmp/fail2ban-0.8.11/ + + # Only differences should be files that you don't want distributed. + +# Ensure the tests work from the tarball + + cd /tmp/fail2ban-0.8.11/ && ./fail2ban-testcases-all + +# Add/finalize the corresponding entry in the ChangeLog + + To generate a list of committers use e.g. + + git shortlog -sn 0.8.10.. | sed -e 's,^[ 0-9\t]*,,g' | tr '\n' '\|' | sed -e 's:|:, :g' + + Ensure the top of the ChangeLog has the right version and current date. + + Ensure the top entry of the ChangeLog has the right version and current date. + +# Update man pages + + (cd man ; ./generate-man ) + git commit -m 'DOC/ENH: update man pages for release' man/* + +# Prepare source and rpm binary distributions + + python setup.py sdist + python setup.py bdist_rpm + python setup.py upload + # Provide a release sample to distributors * Debian: Yaroslav Halchenko @@ -683,65 +738,31 @@ Releasing https://build.opensuse.org/package/users?package=fail2ban&project=openSUSE%3AFactory * Mac Ports: @Malbrouck on github (gh-49) https://trac.macports.org/browser/trunk/dports/security/fail2ban/Portfile + An potentially to the fail2ban-users directory. # Wait for feedback from distributors -# Ensure the version is correct in ./common/version.py and at the top of ChangeLog - -# Ensure the MANIFEST is complete - -Run: - - python setup.py sdist - -Look for errors like: - 'testcases/files/logs/mysqld.log' not a regular file -- skipping - -Which indicates that testcases/files/logs/mysqld.log has been moved or is a directory - - tar -C /tmp -jxf dist/fail2ban-0.8.11.dev.tar.bz2 - -# clean up current direcory - - diff -rul --exclude \*.pyc . /tmp/fail2ban-0.8.11.dev/ - - # Only differences should be files that you don't want distributed. - - cd /tmp/fail2ban-0.8.11.dev/ && ./fail2ban-testcases-all - -# Add/finalize the corresponding entry in the ChangeLog - - To generate a list of committers use e.g. - - git shortlog -sn 0.8.11.. | sed -e 's,^[ 0-9\t]*,,g' | tr '\n' '\|' | sed -e 's:|:, :g' - - Ensure the top of the ChangeLog has the right version and current date. - - Ensure the top entry of the ChangeLog has the right version and current date. - -# Update man pages - - (cd man ; ./generate-man ) - git commit -m 'update man pages for release' man/* - -# Make sure the tests pass - - ./fail2ban-testcases-all - -# Prepare source and rpm binary distributions - - python setup.py sdist - python setup.py bdist_rpm - python setup.py upload - # Prepare a release notice https://github.com/fail2ban/fail2ban/releases/new - Upload the source/binaries from the dist directory and tag the release + Upload the source/binaries from the dist directory and tag the release using the URL + +# Upload source/binaries to sourceforge http://sourceforge.net/projects/fail2ban/ # Run the following and update the wiki with output: - python -c 'import common.protocol; common.protocol.printWiki()' + page: http://www.fail2ban.org/wiki/index.php/Commands + +* Update: + http://www.fail2ban.org/wiki/index.php/Downloads + http://www.fail2ban.org/wiki/index.php/ChangeLog + http://www.fail2ban.org/wiki/index.php/Requirements (Check requirement) + http://www.fail2ban.org/wiki/index.php/Main_Page (Add to News) + http://www.fail2ban.org/wiki/index.php/Features + +* See if any filters are upgraded: + http://www.fail2ban.org/wiki/index.php/Special:AllPages + # Email users and development list of release # notify distributors diff --git a/README.md b/README.md index 05e92fd6..7c00233f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ / _|__ _(_) |_ ) |__ __ _ _ _ | _/ _` | | |/ /| '_ \/ _` | ' \ |_| \__,_|_|_/___|_.__/\__,_|_||_| - v0.8.10 2013/06/12 + v0.8.11-pre1 2013/10/30 ## Fail2Ban: ban hosts that cause multiple authentication errors @@ -30,8 +30,8 @@ Optional: To install, just do: - tar xvfj fail2ban-0.8.10.tar.bz2 - cd fail2ban-0.8.10 + tar xvfj fail2ban-0.8.11.tar.bz2 + cd fail2ban-0.8.11 python setup.py install This will install Fail2Ban into /usr/share/fail2ban. The executable scripts are From ee1edfbf0c7ad641836f93ce46f252c92cd6515c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 4 Nov 2013 17:51:41 +1100 Subject: [PATCH 034/165] BF: remove duplication definition secion in webmin-auth --- config/filter.d/webmin-auth.conf | 2 -- 1 file changed, 2 deletions(-) diff --git a/config/filter.d/webmin-auth.conf b/config/filter.d/webmin-auth.conf index 18bf6361..a0f014cd 100644 --- a/config/filter.d/webmin-auth.conf +++ b/config/filter.d/webmin-auth.conf @@ -9,8 +9,6 @@ before = common.conf _daemon = webmin -[Definition] - failregex = ^%(__prefix_line)sNon-existent login as .+ from \s*$ ^%(__prefix_line)sInvalid login as .+ from \s*$ From 87f68d7564ff375eda6c423b28ca09e3f53123ae Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 6 Nov 2013 11:37:56 +1100 Subject: [PATCH 035/165] firewalld-0.3.8 release that support --remove-rules out so documenting this. --- ChangeLog | 1 + config/action.d/firewall-cmd-direct-new.conf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f77d9491..623d998e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -54,6 +54,7 @@ ver. 0.8.11 (2013/XX/XXX) - loves-unittests Edgar Hoch * action.d/firewall-cmd-direct-new.conf - action for firewalld from https://bugzilla.redhat.com/show_bug.cgi?id=979622 + NOTE: requires firewalld-0.3.8+ Andy Fragen and Daniel Black * filter.d/osx-ipfw.conf - ipfw action for OSX based on random rule numbers. diff --git a/config/action.d/firewall-cmd-direct-new.conf b/config/action.d/firewall-cmd-direct-new.conf index 3fd4e52b..55b6762d 100644 --- a/config/action.d/firewall-cmd-direct-new.conf +++ b/config/action.d/firewall-cmd-direct-new.conf @@ -4,7 +4,7 @@ # Copied from iptables-new.conf and modified for use with firewalld by Edgar Hoch. # It uses "firewall-cmd" instead of "iptables". # -# Because of the --remove-rules in stop it requires a version AFTER (but not including) 0.3.7.1 +# Because of the --remove-rules in stop this action requires firewalld-0.3.8+ [INCLUDES] From d22214da798a9175bf0fec11fef1253534561baa Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 6 Nov 2013 12:03:19 +1100 Subject: [PATCH 036/165] Add Fedora git repo of fail2ban package to DEVELOP --- DEVELOP | 1 + 1 file changed, 1 insertion(+) diff --git a/DEVELOP b/DEVELOP index a8f8899f..bf0bb863 100644 --- a/DEVELOP +++ b/DEVELOP @@ -732,6 +732,7 @@ Which indicates that testcases/files/logs/mysqld.log has been moved or is a dire http://svnweb.freebsd.org/ports/head/security/py-fail2ban/Makefile?view=markup * Fedora: Axel Thimm https://apps.fedoraproject.org/packages/fail2ban + http://pkgs.fedoraproject.org/cgit/fail2ban.git * Gentoo: netmon@gentoo.org http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/net-analyzer/fail2ban/metadata.xml?view=markup * openSUSE: Stephan Kulow From 8b54523316022d2f4e017f353ad1892f06b6bd8e Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 6 Nov 2013 12:13:37 +1100 Subject: [PATCH 037/165] BF: fix to filter.d/wuftp to support pam authentication - Debian bug #665925 --- ChangeLog | 2 ++ config/filter.d/wuftpd.conf | 3 +++ testcases/files/logs/wuftpd | 2 ++ 3 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6497a731..4fcc7cd0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -80,6 +80,8 @@ IMPORTANT incompatible changes: * filter.d/mysqld-auth.conf - mysql can use syslog * filter.d/sshd - regex enhancements to support openssh-6.3. Closes Debian bug #722970 + * filter.d/wuftpd - regex enhancements to support pam and wuftpd. Closes + Debian bug #665925 Rolf Fokkens * action.d/dshield.conf and complain.conf -- reorder mailx arguments. https://bugzilla.redhat.com/show_bug.cgi?id=998020 diff --git a/config/filter.d/wuftpd.conf b/config/filter.d/wuftpd.conf index 942de82a..45149f60 100644 --- a/config/filter.d/wuftpd.conf +++ b/config/filter.d/wuftpd.conf @@ -11,8 +11,11 @@ before = common.conf [Definition] _daemon = wu-ftpd +__pam_re=\(?pam_unix(?:\(wu-ftpd:auth\))?\)?:? failregex = ^%(__prefix_line)sfailed login from \S+ \[\]\s*$ + ^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=(ftp)? ruser=\S* rhost=(?:\s+user=.*)?\s*$ + ignoreregex = diff --git a/testcases/files/logs/wuftpd b/testcases/files/logs/wuftpd index bbb816cc..948e848f 100644 --- a/testcases/files/logs/wuftpd +++ b/testcases/files/logs/wuftpd @@ -3,3 +3,5 @@ Oct 6 09:59:26 myserver wu-ftpd[18760]: failed login from hj-145-173-a8.bta.net.cn [202.108.145.173] # failJSON: { "time": "2004-10-11T16:45:07", "match": true , "host": "198.51.100.71" } Oct 11 16:45:07 ubuntu wu-ftpd[2360]: failed login from example.com [198.51.100.71] +# failJSON: { "time": "2005-03-22T09:35:02", "match": true , "host": "198.51.100.71" } +Mar 22 09:35:02 SiD wu-ftpd[31278]: pam_unix(wu-ftpd:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost=198.51.100.71 user=root From e55b24c533d105cb284c414a2df34b7b48eb3680 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 6 Nov 2013 12:51:21 +1100 Subject: [PATCH 038/165] BF: fix dovecot filter for newer failure message. Closes Debian bug #709324 --- ChangeLog | 2 ++ config/filter.d/dovecot.conf | 2 +- testcases/files/logs/dovecot | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6497a731..9cacd141 100644 --- a/ChangeLog +++ b/ChangeLog @@ -66,6 +66,8 @@ IMPORTANT incompatible changes: closes gh-266. hostsdeny supports daemon_list now too. * action.d/bsd-ipfw - action option unsed. Change blocktype to port unreach instead of deny for consistancy. + * filter.d/dovecot - added to support different dovecot failure + "..disallowed plaintext auth". Closes Debian bug #709324 * filter.d/roundcube-auth - timezone offset can be positive or negative * action.d/bsd-ipfw - action option unsed. Fixed to blocktype for consistency. default to port unreach instead of deny diff --git a/config/filter.d/dovecot.conf b/config/filter.d/dovecot.conf index 2caa04b3..a51ce259 100644 --- a/config/filter.d/dovecot.conf +++ b/config/filter.d/dovecot.conf @@ -10,7 +10,7 @@ before = common.conf _daemon = (auth|dovecot(-auth)?|auth-worker) failregex = ^%(__prefix_line)s(pam_unix(\(dovecot:auth\))?:)?\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=dovecot ruser=\S* rhost=(\s+user=\S*)?\s*$ - ^%(__prefix_line)s(pop3|imap)-login: (Info: )?(Aborted login|Disconnected)(: Inactivity)? \(((no auth attempts|auth failed, \d+ attempts)( in \d+ secs)?|tried to use disabled \S+ auth)\):( user=<\S*>,)?( method=\S+,)? rip=, lip=(\d{1,3}\.){3}\d{1,3}(, session=<\w+>)?(, TLS( handshaking)?(: Disconnected)?)?\s*$ + ^%(__prefix_line)s(pop3|imap)-login: (Info: )?(Aborted login|Disconnected)(: Inactivity)? \(((no auth attempts|auth failed, \d+ attempts)( in \d+ secs)?|tried to use (disabled|disallowed) \S+ auth)\):( user=<\S*>,)?( method=\S+,)? rip=, lip=(\d{1,3}\.){3}\d{1,3}(, session=<\w+>)?(, TLS( handshaking)?(: Disconnected)?)?\s*$ ^%(__prefix_line)s(Info|dovecot: auth\(default\)): pam\(\S+,\): pam_authenticate\(\) failed: (User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \(password mismatch\?\))\s*$ ignoreregex = diff --git a/testcases/files/logs/dovecot b/testcases/files/logs/dovecot index d2aa59ca..aa79e65a 100644 --- a/testcases/files/logs/dovecot +++ b/testcases/files/logs/dovecot @@ -12,6 +12,9 @@ # failJSON: { "time": "2004-12-12T11:19:11", "match": true , "host": "190.210.136.21" } Dec 12 11:19:11 dunnart dovecot: pop3-login: Aborted login (tried to use disabled plaintext auth): rip=190.210.136.21, lip=113.212.99.193 +# failJSON: { "time": "2004-12-12T11:19:11", "match": true , "host": "190.210.136.21" } +Dec 12 11:19:11 dunnart dovecot: pop3-login: Aborted login (tried to use disallowed plaintext auth): rip=190.210.136.21, lip=113.212.99.193, session= + # failJSON: { "time": "2005-06-13T16:30:54", "match": true , "host": "49.176.98.87" } Jun 13 16:30:54 platypus dovecot: imap-login: Disconnected (auth failed, 2 attempts): user=, method=PLAIN, rip=49.176.98.87, lip=113.212.99.194, TLS # failJSON: { "time": "2005-06-14T00:48:21", "match": true , "host": "59.167.242.100" } From 5ebc38683355fbaf3137b8053b29fd74d513e22a Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 6 Nov 2013 13:35:04 +1100 Subject: [PATCH 039/165] DOC: few more links for DEVELOP --- DEVELOP | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/DEVELOP b/DEVELOP index bf0bb863..9a3be94b 100644 --- a/DEVELOP +++ b/DEVELOP @@ -730,15 +730,20 @@ Which indicates that testcases/files/logs/mysqld.log has been moved or is a dire http://packages.qa.debian.org/f/fail2ban.html * FreeBSD: Christoph Theis theis@gmx.at>, Nick Hilliard http://svnweb.freebsd.org/ports/head/security/py-fail2ban/Makefile?view=markup + http://www.freebsd.org/cgi/query-pr-summary.cgi?text=fail2ban * Fedora: Axel Thimm https://apps.fedoraproject.org/packages/fail2ban http://pkgs.fedoraproject.org/cgit/fail2ban.git + https://admin.fedoraproject.org/pkgdb/acls/bugs/fail2ban * Gentoo: netmon@gentoo.org http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/net-analyzer/fail2ban/metadata.xml?view=markup + https://bugs.gentoo.org/buglist.cgi?quicksearch=fail2ban * openSUSE: Stephan Kulow - https://build.opensuse.org/package/users?package=fail2ban&project=openSUSE%3AFactory + https://build.opensuse.org/package/show/openSUSE:Factory/fail2ban * Mac Ports: @Malbrouck on github (gh-49) https://trac.macports.org/browser/trunk/dports/security/fail2ban/Portfile + * Mageia: + https://bugs.mageia.org/buglist.cgi?quicksearch=fail2ban An potentially to the fail2ban-users directory. # Wait for feedback from distributors From f26fba9c19bdf319d8750f2c04e71b28edc29d79 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Wed, 6 Nov 2013 13:47:45 -0500 Subject: [PATCH 040/165] DOC: Untabifying and reindenting a bit ChangeLog --- ChangeLog | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4f69b4a1..87944c76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,7 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ================================================================================ -Fail2Ban (version 0.8.11.pre1) 2013/10/30 +Fail2Ban (version 0.8.11.pre1) 2013/10/30 ================================================================================ ver. 0.8.11 (2013/11/XXX) - loves-unittests and tight, DoS free, filter regexes @@ -27,12 +27,12 @@ possibility that we have inadvertently, despite our best intentions, incorrectly allowed a failure to continue. We will fix this as quickly as humanly possible. -IMPORTANT incompatible changes: - Filter name changes: - * 'lighttpd-fastcgi' filter has been renamed to 'suhosin' - * 'sasl' has been renamed to 'postfix-sasl' - These will require changing in jail.{conf,local} if using these filters. - Exim filter has been split into an spam and a relay/auth filter. +- IMPORTANT incompatible changes: + Filter name changes: + * 'lighttpd-fastcgi' filter has been renamed to 'suhosin' + * 'sasl' has been renamed to 'postfix-sasl' + These will require changing in jail.{conf,local} if using these filters. + Exim filter has been split into an spam and a relay/auth filter. - Fixes: Daniel Black & Marcel Dopita @@ -110,7 +110,7 @@ IMPORTANT incompatible changes: Daniel Black & ykimon * filter.d/3proxy.conf -- filter added * fail2ban-regex - now generates http://www.debuggex.com urls for debugging - regular expressions with the -D parameter. + regular expressions with the -D parameter. Daniel Black * filter.d/exim-spam.conf -- a splitout of exim's spam regexes with additions for greater control over filtering spam. @@ -131,8 +131,8 @@ IMPORTANT incompatible changes: * reorder parsing of jail.conf, jail.d/*.conf, jail.local, jail.d/*.local and likewise for fail2ban.{conf|local|d/*.conf|d/*.local}. Closes gh-392 * jail.conf now has asterisk jail - no need for asterisk-tcp and - asterisk-udp. Users should replace existing jails with asterisk to - reduce duplicate parsing of the asterisk log file. + asterisk-udp. Users should replace existing jails with asterisk to + reduce duplicate parsing of the asterisk log file. * filter.d/{suhosin,pam-generic,gssftpd,sogo-auth,webmin}- regex anchor at start * filter.d/vsftpd - anchored regex at start. disable old pam format regex From 28ee7ba12303faf1d6c81c60506d79a090099bae Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Wed, 6 Nov 2013 14:04:30 -0500 Subject: [PATCH 041/165] DOC: keeping Changelog release-phrases uniform, simplified intro, unified --- ChangeLog | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 87944c76..fc001187 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,36 +7,33 @@ Fail2Ban (version 0.8.11.pre1) 2013/10/30 ================================================================================ -ver. 0.8.11 (2013/11/XXX) - loves-unittests and tight, DoS free, filter regexes +ver. 0.8.11 (2013/11/XXX) - loves-unittests-and-tight-DoS-free-filter-regexes ----------- -In light of CVE-2013-2178 that triggered our last release we have put a -significant effort into tightening all of the regexs of our filters to avoid -another similar vulnerability. All filters have been updated and some to -include more failure regexs supporting previously unbanned failures and -support for newer application versions too. There are test cases for most log +In light of CVE-2013-2178 that triggered our last release we have put +a significant effort into tightening all of the regexs of our filters +to avoid another similar vulnerability. All filters have been updated +and some to catch more login/authentication failures and to support +for newer application versions. There are test cases for most log cases of failures now. -As usual if you have other examples that demonstrate that a filter is -insufficient please give us an example log line on the github issue tracker -http://github.com/fail2ban/fail2ban/issues and NOT on a random blog in some -obscure corner of the Internet. - -During the tightening of the regexs to avoid DoS vulnerabilities there is the -possibility that we have inadvertently, despite our best intentions, -incorrectly allowed a failure to continue. We will fix this as quickly as -humanly possible. +As usual, if you have other examples that demonstrate that a filter is +insufficient, or if we have inadvertently introduced a regression, +please provide us with example log lines on the github issue tracker +http://github.com/fail2ban/fail2ban/issues and NOT on a random blog in +some obscure corner of the Internet. - IMPORTANT incompatible changes: Filter name changes: * 'lighttpd-fastcgi' filter has been renamed to 'suhosin' * 'sasl' has been renamed to 'postfix-sasl' - These will require changing in jail.{conf,local} if using these filters. - Exim filter has been split into an spam and a relay/auth filter. + * 'exim' spam catching failregexes was split out into 'exim-spam' + These changes will require changing jail.{conf,local} if any of + those filters were used. - Fixes: Daniel Black & Marcel Dopita - * filter.d/apache-auth -- fixed and apache auth samples provide. closes #286 + * filter.d/apache-auth -- fixed and apache auth samples provide. Closes gh-286 Yaroslav Halchenko * filter.d/common.conf -- make colon after [daemon] optional. Closes gh-267 * filter.d/apache-common.conf -- support apache 2.4 more detailed error @@ -62,8 +59,8 @@ humanly possible. * filter.d/asterisk -- more regexes Daniel Black * action.d/hostsdeny -- NOTE: new dependancy 'ed'. Switched to use 'ed' across - all platforms to ensure permissions are the same before and after a ban - - closes gh-266. hostsdeny supports daemon_list now too. + all platforms to ensure permissions are the same before and after a ban. + Closes gh-266. hostsdeny supports daemon_list now too. * action.d/bsd-ipfw - action option unsed. Change blocktype to port unreach instead of deny for consistancy. * filter.d/dovecot - added to support different dovecot failure @@ -89,7 +86,7 @@ humanly possible. https://bugzilla.redhat.com/show_bug.cgi?id=998020 John Doe (ache) * action.d/bsd-ipfw.conf - invert actionstop logic to make exist status 0. - closes gh-343. + Closes gh-343. JP Espinosa (Reviewed by O.Poplawski) * files/redhat-initd - rewritten to use stock init.d functions thus avoiding problems with getpid. Also $network and iptables moved @@ -163,7 +160,7 @@ humanly possible. * filter.d/{courier{login,smtp},proftpd,sieve,wuftpd,xinetd} - General regex impovements Zurd - * filter.d/postfix - add filter for VRFY failures. closes gh-322. + * filter.d/postfix - add filter for VRFY failures. Closes gh-322. Orion Poplawski * fail2ban.d/ and jail.d/ directories are added to etc/fail2ban to facilitate their use From 6f321068f1c92a338aa08dfaa12db83a2ba475dd Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Thu, 7 Nov 2013 14:25:57 -0800 Subject: [PATCH 042/165] NF: gen_badbots script to (re)generate/update config/filter.d/apache-badbots.conf --- files/gen_badbots | 75 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100755 files/gen_badbots diff --git a/files/gen_badbots b/files/gen_badbots new file mode 100755 index 00000000..278058f7 --- /dev/null +++ b/files/gen_badbots @@ -0,0 +1,75 @@ +#!/bin/bash +#-------------------------- =+- Shell script -+= -------------------------- +# +# Yaroslav Halchenko CS@UNM, CS@NJIT +# web: http://www.onerussian.com & PSYCH@RUTGERS +# e-mail: yoh@onerussian.com ICQ#: 60653192 +# +# DESCRIPTION (NOTES): +# +# Script to fetch list of agent strings from http://www.user-agents.org +# which are known to be from mailicious bots, and create apache-badbots.conf +# filter for fail2ban +# +# COPYRIGHT: Yaroslav Halchenko 2007-2013 +# +# LICENSE: +# +# This program 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. +# +# This program 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 this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, +# MA 02110-1301, USA. +# +# On Debian system see /usr/share/common-licenses/GPL for the full license. +# +#-----------------\____________________________________/------------------ + +url=http://www.user-agents.org/index.shtml +badbots=$( +for f in "" "?g_m" "?moz" "?n_s" "?t_z"; do + wget -q -O- $url$f; +done \ +| grep -h -B4 'S '\ +| sed -e 's/ //g' \ +| awk '/^--/{getline; gsub(" ",""); print $0}' \ +| sed -e 's/\([.\:|()]\)/\\\1/g' \ +| uniq \ +| tr '\n' '|' \ +| sed -e 's/|$//g' +) + +echo $badbots >| /tmp/badbots.tmp + +cat >| config/filter.d/apache-badbots.conf < -.*"(GET|POST).*HTTP.*"(?:%(badbots)s|%(badbotscustom)s)"$ + +ignoreregex = + +# DEV Notes: +# List of bad bots fetched from http://www.user-agents.org +# Generated on `date` by $0. +# +# Author: Yaroslav Halchenko +EOF From 452230835411fcc86624aa0096fbb74c69be33d6 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Thu, 7 Nov 2013 14:26:18 -0800 Subject: [PATCH 043/165] ENH: regenerated config/filter.d/apache-badbots.conf --- config/filter.d/apache-badbots.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/filter.d/apache-badbots.conf b/config/filter.d/apache-badbots.conf index 9ee44c69..b2ac9626 100644 --- a/config/filter.d/apache-badbots.conf +++ b/config/filter.d/apache-badbots.conf @@ -3,12 +3,12 @@ # Regexp to catch known spambots and software alike. Please verify # that it is your intent to block IPs which were driven by # above mentioned bots. - + [Definition] badbotscustom = EmailCollector|WebEMailExtrac|TrackBack/1\.02|sogou music spider -badbots = atSpider/1\.0|autoemailspider|China Local Browse 2\.6|ContentSmartz|DataCha0s/2\.0|DBrowse 1\.4b|DBrowse 1\.4d|Demo Bot DOT 16b|Demo Bot Z 16b|DSurf15a 01|DSurf15a 71|DSurf15a 81|DSurf15a VA|EBrowse 1\.4b|Educate Search VxB|EmailSiphon|EmailWolf 1\.00|ESurf15a 15|ExtractorPro|Franklin Locator 1\.8|FSurf15a 01|Full Web Bot 0416B|Full Web Bot 0516B|Full Web Bot 2816B|Industry Program 1\.0\.x|ISC Systems iRc Search 2\.1|IUPUI Research Bot v 1\.9a|LARBIN-EXPERIMENTAL \(efp@gmx\.net\)|LetsCrawl\.com/1\.0 +http\://letscrawl\.com/|Lincoln State Web Browser|LWP\:\:Simple/5\.803|Mac Finder 1\.0\.xx|MFC Foundation Class Library 4\.0|Microsoft URL Control - 6\.00\.8xxx|Missauga Locate 1\.0\.0|Missigua Locator 1\.9|Missouri College Browse|Mizzu Labs 2\.2|Mo College 1\.9|Mozilla/2\.0 \(compatible; NEWT ActiveX; Win32\)|Mozilla/3\.0 \(compatible; Indy Library\)|Mozilla/4\.0 \(compatible; Advanced Email Extractor v2\.xx\)|Mozilla/4\.0 \(compatible; Iplexx Spider/1\.0 http\://www\.iplexx\.at\)|Mozilla/4\.0 \(compatible; MSIE 5\.0; Windows NT; DigExt; DTS Agent|Mozilla/4\.0 efp@gmx\.net|Mozilla/5\.0 \(Version\: xxxx Type\:xx\)|MVAClient|NASA Search 1\.0|Nsauditor/1\.x|PBrowse 1\.4b|PEval 1\.4b|Poirot|Port Huron Labs|Production Bot 0116B|Production Bot 2016B|Production Bot DOT 3016B|Program Shareware 1\.0\.2|PSurf15a 11|PSurf15a 51|PSurf15a VA|psycheclone|RSurf15a 41|RSurf15a 51|RSurf15a 81|searchbot admin@google\.com|sogou spider|sohu agent|SSurf15a 11 |TSurf15a 11|Under the Rainbow 2\.2|User-Agent\: Mozilla/4\.0 \(compatible; MSIE 6\.0; Windows NT 5\.1\)|WebVulnCrawl\.blogspot\.com/1\.0 libwww-perl/5\.803|Wells Search II|WEP Search 00 +badbots = Atomic_Email_Hunter/4\.0|atSpider/1\.0|autoemailspider|bwh3_user_agent|China Local Browse 2\.6|ContactBot/0\.2|ContentSmartz|DataCha0s/2\.0|DBrowse 1\.4b|DBrowse 1\.4d|Demo Bot DOT 16b|Demo Bot Z 16b|DSurf15a 01|DSurf15a 71|DSurf15a 81|DSurf15a VA|EBrowse 1\.4b|Educate Search VxB|EmailSiphon|EmailSpider|EmailWolf 1\.00|ESurf15a 15|ExtractorPro|Franklin Locator 1\.8|FSurf15a 01|Full Web Bot 0416B|Full Web Bot 0516B|Full Web Bot 2816B|Guestbook Auto Submitter|Industry Program 1\.0\.x|ISC Systems iRc Search 2\.1|IUPUI Research Bot v 1\.9a|LARBIN-EXPERIMENTAL \(efp@gmx\.net\)|LetsCrawl\.com/1\.0 +http\://letscrawl\.com/|Lincoln State Web Browser|LMQueueBot/0\.2|LWP\:\:Simple/5\.803|Mac Finder 1\.0\.xx|MFC Foundation Class Library 4\.0|Microsoft URL Control - 6\.00\.8xxx|Missauga Locate 1\.0\.0|Missigua Locator 1\.9|Missouri College Browse|Mizzu Labs 2\.2|Mo College 1\.9|MVAClient|Mozilla/2\.0 \(compatible; NEWT ActiveX; Win32\)|Mozilla/3\.0 \(compatible; Indy Library\)|Mozilla/3\.0 \(compatible; scan4mail \(advanced version\) http\://www\.peterspages\.net/?scan4mail\)|Mozilla/4\.0 \(compatible; Advanced Email Extractor v2\.xx\)|Mozilla/4\.0 \(compatible; Iplexx Spider/1\.0 http\://www\.iplexx\.at\)|Mozilla/4\.0 \(compatible; MSIE 5\.0; Windows NT; DigExt; DTS Agent|Mozilla/4\.0 efp@gmx\.net|Mozilla/5\.0 \(Version\: xxxx Type\:xx\)|NameOfAgent \(CMS Spider\)|NASA Search 1\.0|Nsauditor/1\.x|PBrowse 1\.4b|PEval 1\.4b|Poirot|Port Huron Labs|Production Bot 0116B|Production Bot 2016B|Production Bot DOT 3016B|Program Shareware 1\.0\.2|PSurf15a 11|PSurf15a 51|PSurf15a VA|psycheclone|RSurf15a 41|RSurf15a 51|RSurf15a 81|searchbot admin@google\.com|ShablastBot 1\.0|snap\.com beta crawler v0|Snapbot/1\.0|Snapbot/1\.0 \(Snap Shots, +http\://www\.snap\.com\)|sogou develop spider|Sogou Orion spider/3\.0\(+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sogou spider|Sogou web spider/3\.0\(+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sohu agent|SSurf15a 11 |TSurf15a 11|Under the Rainbow 2\.2|User-Agent\: Mozilla/4\.0 \(compatible; MSIE 6\.0; Windows NT 5\.1\)|VadixBot|WebVulnCrawl\.unknown/1\.0 libwww-perl/5\.803|Wells Search II|WEP Search 00 failregex = ^ -.*"(GET|POST).*HTTP.*"(?:%(badbots)s|%(badbotscustom)s)"$ @@ -16,6 +16,6 @@ ignoreregex = # DEV Notes: # List of bad bots fetched from http://www.user-agents.org -# Generated on Sun Feb 11 01:09:15 EST 2007 by ./badbots.sh +# Generated on Thu Nov 7 14:23:35 PST 2013 by files/gen_badbots. # # Author: Yaroslav Halchenko From a148d35d705b84fd97f3c2e00d28483f2eb4b92c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 8 Nov 2013 10:06:40 +1100 Subject: [PATCH 044/165] ENH: add filter.d/nginx-http-auth. Partially forfills #405 --- ChangeLog | 2 ++ THANKS | 1 + config/filter.d/nginx-http-auth.conf | 15 +++++++++++++++ config/jail.conf | 7 +++++++ testcases/files/logs/nginx-http-auth | 6 ++++++ 5 files changed, 31 insertions(+) create mode 100644 config/filter.d/nginx-http-auth.conf create mode 100644 testcases/files/logs/nginx-http-auth diff --git a/ChangeLog b/ChangeLog index fc001187..813213ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -112,6 +112,8 @@ some obscure corner of the Internet. * filter.d/exim-spam.conf -- a splitout of exim's spam regexes with additions for greater control over filtering spam. * add date expression for apache-2.4 - milliseconds + * filter.d/nginx-http-auth -- filter added for http basic authentication + failures in nginx. Partially forfills gh-405. Christophe Carles & Daniel Black * filter.d/perdition.conf -- filter added Mark McKinstry diff --git a/THANKS b/THANKS index e70ca9c9..5f6d1b2b 100644 --- a/THANKS +++ b/THANKS @@ -54,6 +54,7 @@ Michael Hanselmann Nick Munger Patrick Börjesson Raphaël Marichez +RealRancor René Berber Robert Edeker Rolf Fokkens diff --git a/config/filter.d/nginx-http-auth.conf b/config/filter.d/nginx-http-auth.conf new file mode 100644 index 00000000..00f152b7 --- /dev/null +++ b/config/filter.d/nginx-http-auth.conf @@ -0,0 +1,15 @@ +# fail2ban filter configuration for nginx + + +[Definition] + + +failregex = ^ \[error\] \d+#\d+: \*\d+ user "\S+":? (password mismatch|was not found in ".*"), client: , server: \S+, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+" + +ignoreregex = + +# DEV NOTES: +# Based on samples in https://github.com/fail2ban/fail2ban/pull/43/files +# Extensive search of all nginx auth failures not done yet. +# +# Author: Daniel Black diff --git a/config/jail.conf b/config/jail.conf index 23e30c83..4bda3c4a 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -181,6 +181,13 @@ logpath = /var/log/apache*/*error.log maxretry = 6 +[nginx-http-auth] + +enabled = false +filter = nginx-http-auth +logpath = /var/log/nginx/error.log + + # The hosts.deny path can be defined with the "file" argument if it is # not in /etc. [postfix-tcpwrapper] diff --git a/testcases/files/logs/nginx-http-auth b/testcases/files/logs/nginx-http-auth new file mode 100644 index 00000000..0fa7a7bd --- /dev/null +++ b/testcases/files/logs/nginx-http-auth @@ -0,0 +1,6 @@ + +# failJSON: { "time": "2012-04-09T11:53:29", "match": true , "host": "192.0.43.10" } +2012/04/09 11:53:29 [error] 2865#0: *66647 user "xyz" was not found in "/var/www/.htpasswd", client: 192.0.43.10, server: www.myhost.com, request: "GET / HTTP/1.1", host: "www.myhost.com" +# failJSON: { "time": "2012-04-09T11:53:36", "match": true , "host": "192.0.43.10" } +2012/04/09 11:53:36 [error] 2865#0: *66647 user "xyz": password mismatch, client: 192.0.43.10, server: www.myhost.com, request: "GET / HTTP/1.1", host: "www.myhost.com" + From ab9d921162038a22cbea48611c63b6e42f3a8b17 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 8 Nov 2013 10:09:19 +1100 Subject: [PATCH 045/165] BF: missed action in nginx-http-auth --- config/jail.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/config/jail.conf b/config/jail.conf index 4bda3c4a..486ea078 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -185,6 +185,7 @@ maxretry = 6 enabled = false filter = nginx-http-auth +action = iptables-multiport[name=nginx-http-auth,port="80,443"] logpath = /var/log/nginx/error.log From d7560d4041e90d99fd306ad5fb8d5d89424e45e0 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 8 Nov 2013 10:24:50 +1100 Subject: [PATCH 046/165] ENH: condense asterisk regexs for speed --- config/filter.d/asterisk.conf | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/config/filter.d/asterisk.conf b/config/filter.d/asterisk.conf index 35906d11..f77a1557 100644 --- a/config/filter.d/asterisk.conf +++ b/config/filter.d/asterisk.conf @@ -8,13 +8,7 @@ __pid_re = (?:\[\d+\]) # All Asterisk log messages begin like this: log_prefix= \[\]\s*(?:NOTICE|SECURITY)%(__pid_re)s:?(?:\[\S+\d*\])? \S+:\d* -failregex = ^%(log_prefix)s Registration from '[^']*' failed for '(:\d+)?' - Wrong password$ - ^%(log_prefix)s Registration from '[^']*' failed for '(:\d+)?' - No matching peer found$ - ^%(log_prefix)s Registration from '[^']*' failed for '(:\d+)?' - Username/auth name mismatch$ - ^%(log_prefix)s Registration from '[^']*' failed for '(:\d+)?' - Device does not match ACL$ - ^%(log_prefix)s Registration from '[^']*' failed for '(:\d+)?' - Peer is not supposed to register$ - ^%(log_prefix)s Registration from '[^']*' failed for '(:\d+)?' - ACL error \(permit/deny\)$ - ^%(log_prefix)s Registration from '[^']*' failed for '(:\d+)?' - Not a local domain$ +failregex = ^%(log_prefix)s Registration from '[^']*' failed for '(:\d+)?' - (Wrong password|No matching peer found|Username/auth name mismatch|Device does not match ACL|Peer is not supposed to register|ACL error \(permit/deny\)|Not a local domain)$ ^%(log_prefix)s Call from '[^']*' \(:\d+\) to extension '\d+' rejected because extension not found in context 'default'\.$ ^%(log_prefix)s Host failed to authenticate as '[^']*'$ ^%(log_prefix)s No registration for peer '[^']*' \(from \)$ From eace931c19d7da6ae8a81de9db6258d605a749f2 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Thu, 7 Nov 2013 15:47:25 -0800 Subject: [PATCH 047/165] Changelog for prior changes (gen_buildbots) --- ChangeLog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index fc001187..3d9d1a96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -149,6 +149,9 @@ some obscure corner of the Internet. * filter.d/roundcube-auth.conf -- anchored version * date matching - for standard asctime formats prefer more detailed first (thus use year if available) + * files/gen_badbots was added and filter.d/apache-badbots.conf was + regenerated to get updated (although now still an old) list of + "bad" bots Alexander Dietrich * action.d/sendmail-common.conf -- added common sendmail settings file and made the sender display name configurable From abb012ae5c90c4bfc2b83512bc168f1ecaa0d10e Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Fri, 8 Nov 2013 10:00:37 -0800 Subject: [PATCH 048/165] BF: fixing injection for OpenSSH 6.3 -- making .* before non-greedy --- config/filter.d/sshd.conf | 2 +- testcases/files/logs/sshd | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/config/filter.d/sshd.conf b/config/filter.d/sshd.conf index 08456177..be80b02f 100644 --- a/config/filter.d/sshd.conf +++ b/config/filter.d/sshd.conf @@ -14,7 +14,7 @@ _daemon = sshd failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from ( via \S+)?\s*$ ^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from \s*$ - ^%(__prefix_line)sFailed \S+ for .* from (?: port \d*)?(?: ssh\d*)?(: (ruser .{0,100}|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".{0,100}", client host ".{0,100}")?))?\s*$ + ^%(__prefix_line)sFailed \S+ for .*? from (?: port \d*)?(?: ssh\d*)?(: (ruser .{0,100}|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".{0,100}", client host ".{0,100}")?))?\s*$ ^%(__prefix_line)sROOT LOGIN REFUSED.* FROM \s*$ ^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from \s*$ ^%(__prefix_line)sUser .+ from not allowed because not listed in AllowUsers\s*$ diff --git a/testcases/files/logs/sshd b/testcases/files/logs/sshd index 96338220..def0ebb5 100644 --- a/testcases/files/logs/sshd +++ b/testcases/files/logs/sshd @@ -94,3 +94,7 @@ Sep 29 17:15:02 spaceman sshd[12946]: Failed hostbased for dan from 127.0.0.1 po # failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1" } Sep 29 17:15:02 spaceman sshd[12946]: Failed hostbased for dan from 127.0.0.1 port 45785 ssh2: DSA 01:c0:79:41:91:31:9a:7d:95:23:91:ac:b1:6d:59:81, client user "dan", client host "localhost.localdomain" + +# Injecting into rhost for the format of OpenSSH >=6.3 +# failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1" } +Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser from 1.2.3.4 From 750e0c1e3dbce856437c115142d57f18b6c1fac7 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Fri, 8 Nov 2013 10:06:24 -0800 Subject: [PATCH 049/165] BF: disallow exploiting of non-greedy .* in previous fix by providing too long rhost -- do not impose length limits for user-provided input since daemon might eventually change reported length and we would need to adjust anyways. So limiting in length does not provide additional security but allows for a possible injection vector --- ChangeLog | 2 +- config/filter.d/sshd.conf | 2 +- testcases/files/logs/sshd | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3d9d1a96..5120c139 100644 --- a/ChangeLog +++ b/ChangeLog @@ -78,7 +78,7 @@ some obscure corner of the Internet. * filter.d/recidive -- support f2b syslog target and anchor regex at start * filter.d/mysqld-auth.conf - mysql can use syslog * filter.d/sshd - regex enhancements to support openssh-6.3. Closes Debian - bug #722970 + bug #722970. Thanks Colin Watson for the regex analysis. * filter.d/wuftpd - regex enhancements to support pam and wuftpd. Closes Debian bug #665925 Rolf Fokkens diff --git a/config/filter.d/sshd.conf b/config/filter.d/sshd.conf index be80b02f..d97fd675 100644 --- a/config/filter.d/sshd.conf +++ b/config/filter.d/sshd.conf @@ -14,7 +14,7 @@ _daemon = sshd failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from ( via \S+)?\s*$ ^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from \s*$ - ^%(__prefix_line)sFailed \S+ for .*? from (?: port \d*)?(?: ssh\d*)?(: (ruser .{0,100}|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".{0,100}", client host ".{0,100}")?))?\s*$ + ^%(__prefix_line)sFailed \S+ for .*? from (?: port \d*)?(?: ssh\d*)?(: (ruser .*|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".*", client host ".*")?))?\s*$ ^%(__prefix_line)sROOT LOGIN REFUSED.* FROM \s*$ ^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from \s*$ ^%(__prefix_line)sUser .+ from not allowed because not listed in AllowUsers\s*$ diff --git a/testcases/files/logs/sshd b/testcases/files/logs/sshd index def0ebb5..4f862d89 100644 --- a/testcases/files/logs/sshd +++ b/testcases/files/logs/sshd @@ -95,6 +95,8 @@ Sep 29 17:15:02 spaceman sshd[12946]: Failed hostbased for dan from 127.0.0.1 po # failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1" } Sep 29 17:15:02 spaceman sshd[12946]: Failed hostbased for dan from 127.0.0.1 port 45785 ssh2: DSA 01:c0:79:41:91:31:9a:7d:95:23:91:ac:b1:6d:59:81, client user "dan", client host "localhost.localdomain" -# Injecting into rhost for the format of OpenSSH >=6.3 -# failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1" } +# failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1", "desc": "Injecting into rhost for the format of OpenSSH >=6.3" } Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser from 1.2.3.4 + +# failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1", "desc": "Injecting while exhausting initially present {0,100} match length limits set for ruser etc" } +Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX from 1.2.3.4 From bf245f9640e3a957f1deb751f9eb28742f957107 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Fri, 8 Nov 2013 14:34:31 -0800 Subject: [PATCH 050/165] DOC: adding DEV Notes for for non-greedy matchin within sshd.conf --- config/filter.d/sshd.conf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/filter.d/sshd.conf b/config/filter.d/sshd.conf index d97fd675..a36b050c 100644 --- a/config/filter.d/sshd.conf +++ b/config/filter.d/sshd.conf @@ -26,4 +26,11 @@ failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|erro ignoreregex = +# DEV Notes: +# +# "Failed \S+ for .*? from ..." failregex uses non-greedy catch-all because +# it is coming before use of which is not hard-anchored at the end as well, +# and later catch-all's could contain user-provided input, which need to be greedily +# matched away first. +# # Author: Cyril Jaquier, Yaroslav Halchenko, Petr Voralek, Daniel Black From 49024fe6ea1283c1bec69a2547237dd1e4adf117 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Fri, 8 Nov 2013 14:36:56 -0800 Subject: [PATCH 051/165] DOC: minor typos in ChangeLog --- ChangeLog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 648f1e1a..27e598ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -96,7 +96,7 @@ some obscure corner of the Internet. - New Features: Edgar Hoch - * action.d/firewall-cmd-direct-new.conf - action for firewalld + * action.d/firewall-cmd-direct-new.conf - action for firewalld from https://bugzilla.redhat.com/show_bug.cgi?id=979622 NOTE: requires firewalld-0.3.8+ Andy Fragen and Daniel Black @@ -113,7 +113,7 @@ some obscure corner of the Internet. with additions for greater control over filtering spam. * add date expression for apache-2.4 - milliseconds * filter.d/nginx-http-auth -- filter added for http basic authentication - failures in nginx. Partially forfills gh-405. + failures in nginx. Partially fulfills gh-405. Christophe Carles & Daniel Black * filter.d/perdition.conf -- filter added Mark McKinstry From ac061155f093464fb6cd2329d3d513b15c68e256 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Fri, 8 Nov 2013 14:40:52 -0800 Subject: [PATCH 052/165] BF: anchor introduced nginx-http-auth at the end needed since request probably could be not a correct HTTP statement but continue with all those to match till the end and then injected ", client: VICTIM, server..." thus allowing injection. We better anchor at the end then --- config/filter.d/nginx-http-auth.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/filter.d/nginx-http-auth.conf b/config/filter.d/nginx-http-auth.conf index 00f152b7..79dda30b 100644 --- a/config/filter.d/nginx-http-auth.conf +++ b/config/filter.d/nginx-http-auth.conf @@ -4,7 +4,7 @@ [Definition] -failregex = ^ \[error\] \d+#\d+: \*\d+ user "\S+":? (password mismatch|was not found in ".*"), client: , server: \S+, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+" +failregex = ^ \[error\] \d+#\d+: \*\d+ user "\S+":? (password mismatch|was not found in ".*"), client: , server: \S+, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"\s*$ ignoreregex = From 724c6bfd922638ecc1eddf9197df5369eeb7cd0b Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 9 Nov 2013 10:35:13 +1100 Subject: [PATCH 053/165] DOC: filter regex debugging --- DEVELOP | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/DEVELOP b/DEVELOP index 9a3be94b..0e37a0c3 100644 --- a/DEVELOP +++ b/DEVELOP @@ -289,15 +289,19 @@ TIP: Some applications log spaces at the end. If you are not sure add \s*$ as the end part of the regex. If your regex is not matching, http://www.debuggex.com/?flavor=python can help -to tune it: +to tune it. fail2ban-regex -D ... will present Debuggex URLs for the regexs +and sample log files that you pass into it. +In general use when using regex debuggers for generating fail2ban filters: * use regex from the ./fail2ban-regex output (to ensure all substitutions are -done) and replace with (?&.ipv4). Make sure that regex type set to -Python; -* for the test data put your log output with the time removed; -- when you have fixed the regex put it back into your filter file. +done) +* replace with (?&.ipv4) +* make sure that regex type set to Python +* for the test data put your log output with the date/time removed -Please spread the good word about debuggex - Serge Toarca is kindly continuing +When you have fixed the regex put it back into your filter file. + +Please spread the good word about Debuggex - Serge Toarca is kindly continuing its free availability to Open Source developers. Finishing up: From b8f40fef1bf362f5645b912b651797e4d2b83de2 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 11 Nov 2013 08:08:10 +1100 Subject: [PATCH 054/165] DOC: more on filter regexes - DEVELOP --- DEVELOP | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/DEVELOP b/DEVELOP index 0e37a0c3..d776d8f7 100644 --- a/DEVELOP +++ b/DEVELOP @@ -331,7 +331,7 @@ failregex, while matching inserted text to the part, they have the ability to deny any host they choose. So the part must be anchored on text generated by the application, and -not the user, to a extent sufficient to prevent user inserting the entire text +not the user, to an extent sufficient to prevent user inserting the entire text matching this or any other failregex. Ideally filter regex should anchor at the beginning and at the end of log line. @@ -381,7 +381,7 @@ Note if we'd just had the expression: Then provided the user put a space in their command they would have never been banned. -2. Filter regex can match other user injected data +2. Unanchored regex can match other user injected data From the Apache vulnerability CVE-2013-2178 ( original ref: https://vndh.net/note:fail2ban-089-denial-service ). @@ -402,7 +402,82 @@ Now the log line will be: As this log line doesn't match other expressions hence it matches the above regex and blocks 192.168.33.1 as a denial of service from the HTTP requester. -3. Application generates two identical log messages with different meanings +3. Over greedy pattern matching + +From: https://github.com/fail2ban/fail2ban/pull/426 + +An example ssh log (simplified) + + Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser remoteuser + +As we assume username can include anything including spaces its prudent to put +.* here. The remote user can also exist as anything so lets not make assumptions again. + + failregex = ^%(__prefix_line)sFailed \S+ for .* from ( port \d*)?( ssh\d+)?(: ruser .*)?$ + +So this works. The problem is if the .* after remote user is injected by the +user to be 'from 1.2.3.4'. The resultant log line is. + + Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser from 1.2.3.4 + +Testing with: + + fail2ban-regex -v 'Sep 29 17:15:02 Failed password for user from 127.0.0.1 port 20000 ssh1: ruser from 1.2.3.4' '^ Failed \S+ for .* from ( port \d*)?( ssh\d+)?(: ruser .*)?$' + +TIP: I've removed the bit that matches __prefix_line from the regex and log. + +Shows: + + 1) [1] ^ Failed \S+ for .* from ( port \d*)?( ssh\d+)?(: ruser .*)?$ + 1.2.3.4 Sun Sep 29 17:15:02 2013 + +It should of matched 127.0.0.1. So the first greedy part of the greedy regex +matched until the end of the string. The was no "from " so the regex +engine worked backwards from the end of the string until this was matched. + +The result was that 1.2.3.4 was matched, injected by the user, and the wrong IP +was banned. + +The solution here is to make the first .* non-greedy with .*?. Here it matches +as little as required and the fail2ban-regex tool shows the output: + + fail2ban-regex -v 'Sep 29 17:15:02 Failed password for user from 127.0.0.1 port 20000 ssh1: ruser from 1.2.3.4' '^ Failed \S+ for .*? from ( port \d*)?( ssh\d+)?(: ruser .*)?$' + + 1) [1] ^ Failed \S+ for .*? from ( port \d*)?( ssh\d+)?(: ruser .*)?$ + 127.0.0.1 Sun Sep 29 17:15:02 2013 + +So the general case here is a log line that contains: + + (fixed_data_1)(fixed_data_2)(user_injectable_data) + +Where the regex that matches fixed_data_1 is gready and matches the entire +string, before moving backwards and user_injectable_data can match the entire +string. + +Another case: + +ref: https://www.debuggex.com/r/CtAbeKMa2sDBEfA2/0 + +A webserver logs the following without URL escaping: + + [error] 2865#0: *66647 user "xyz" was not found in "/file", client: 1.2.3.1, server: www.host.com, request: "GET ", client: 3.2.1.1, server: fake.com, request: "GET exploited HTTP/3.3", host: "injected.host", host: "www.myhost.com" + +regex: + + failregex = ^ \[error\] \d+#\d+: \*\d+ user "\S+":? (?:password mismatch|was not found in ".*"), client: , server: \S+, request: "\S+ .+ HTTP/\d+\.\d+", host: "\S+" + +The .* matches to the end of the string. Finds that it can't continue to match +", client ... so it moves from the back and find that the user injected web URL: + + ", client: 3.2.1.1, server: fake.com, request: "GET exploited HTTP/3.3", host: "injected.host + +In this case there is a fixed host: "www.myhost.com" at the end so the solution +is to anchor the regex at the end with a $. + +If this wasn't the case then first .* needed to be made so it didn't capture +beyond . + +4. Application generates two identical log messages with different meanings If the application generates the following two messages under different circumstances: From d955714d26ba78f11999b4bd99a7c36ff8c55679 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 11 Nov 2013 08:11:32 +1100 Subject: [PATCH 055/165] TST: test case that shows injection --- testcases/files/logs/sshd | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testcases/files/logs/sshd b/testcases/files/logs/sshd index 4f862d89..ed4857bd 100644 --- a/testcases/files/logs/sshd +++ b/testcases/files/logs/sshd @@ -100,3 +100,6 @@ Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 po # failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1", "desc": "Injecting while exhausting initially present {0,100} match length limits set for ruser etc" } Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX from 1.2.3.4 + +# failJSON: { "time": "2004-11-11T08:04:51", "match": true , "host": "127.0.0.1", "desc": "Injecting on username ssh 'from 10.10.1.1'@localhost" +Nov 11 08:04:51 redbamboo sshd[2737]: Failed password for invalid user from 10.10.1.1 from 127.0.0.1 port 58946 ssh2 From 061a26c40815b8594e9ffce1e9056aeac7dff5cd Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 11 Nov 2013 08:28:09 +1100 Subject: [PATCH 056/165] TST: fix space in sshd sample log --- testcases/files/logs/sshd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcases/files/logs/sshd b/testcases/files/logs/sshd index ed4857bd..541afb19 100644 --- a/testcases/files/logs/sshd +++ b/testcases/files/logs/sshd @@ -101,5 +101,5 @@ Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 po # failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1", "desc": "Injecting while exhausting initially present {0,100} match length limits set for ruser etc" } Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX from 1.2.3.4 -# failJSON: { "time": "2004-11-11T08:04:51", "match": true , "host": "127.0.0.1", "desc": "Injecting on username ssh 'from 10.10.1.1'@localhost" +# failJSON: { "time": "2004-11-11T08:04:51", "match": true , "host": "127.0.0.1", "desc": "Injecting on username ssh 'from 10.10.1.1'@localhost" Nov 11 08:04:51 redbamboo sshd[2737]: Failed password for invalid user from 10.10.1.1 from 127.0.0.1 port 58946 ssh2 From d90130234dfba1fd389118941dcf4ec8db031c8b Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 11 Nov 2013 08:29:54 +1100 Subject: [PATCH 057/165] TST: end of json in sshd sample log --- testcases/files/logs/sshd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcases/files/logs/sshd b/testcases/files/logs/sshd index 541afb19..3c50dcfd 100644 --- a/testcases/files/logs/sshd +++ b/testcases/files/logs/sshd @@ -101,5 +101,5 @@ Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 po # failJSON: { "time": "2004-09-29T17:15:02", "match": true , "host": "127.0.0.1", "desc": "Injecting while exhausting initially present {0,100} match length limits set for ruser etc" } Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX from 1.2.3.4 -# failJSON: { "time": "2004-11-11T08:04:51", "match": true , "host": "127.0.0.1", "desc": "Injecting on username ssh 'from 10.10.1.1'@localhost" +# failJSON: { "time": "2004-11-11T08:04:51", "match": true , "host": "127.0.0.1", "desc": "Injecting on username ssh 'from 10.10.1.1'@localhost" } Nov 11 08:04:51 redbamboo sshd[2737]: Failed password for invalid user from 10.10.1.1 from 127.0.0.1 port 58946 ssh2 From 87516eb92b5792ce1202a5d67da481f6019ad52a Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 11 Nov 2013 09:46:40 +1100 Subject: [PATCH 058/165] ENH: apache-overflows - more detail on "request failed: URI too long (longer than %d)" with test case --- config/filter.d/apache-overflows.conf | 8 +++++++- testcases/files/logs/apache-overflows | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/config/filter.d/apache-overflows.conf b/config/filter.d/apache-overflows.conf index de1c770d..68669222 100644 --- a/config/filter.d/apache-overflows.conf +++ b/config/filter.d/apache-overflows.conf @@ -8,8 +8,14 @@ before = apache-common.conf [Definition] -failregex = ^%(_apache_error_client)s (Invalid (method|URI) in request|request failed: URI too long|erroneous characters after protocol string) +failregex = ^%(_apache_error_client)s (Invalid (method|URI) in request|request failed: URI too long \(longer than \d+\)|erroneous characters after protocol string) ignoreregex = +# DEV Noptes: +# +# fgrep -r 'URI too long' httpd-2.* +# httpd-2.2.25/server/protocol.c: "request failed: URI too long (longer than %d)", r->server->limit_req_line); +# httpd-2.4.4/server/protocol.c: "request failed: URI too long (longer than %d)", +# # Author: Tim Connors diff --git a/testcases/files/logs/apache-overflows b/testcases/files/logs/apache-overflows index d40c1c4f..69e5fd49 100644 --- a/testcases/files/logs/apache-overflows +++ b/testcases/files/logs/apache-overflows @@ -2,3 +2,6 @@ [Tue Mar 16 15:39:29 2010] [error] [client 58.179.109.179] Invalid URI in request \xf9h\xa9\xf3\x88\x8cXKj \xbf-l*4\x87n\xe4\xfe\xd4\x1d\x06\x8c\xf8m\\rS\xf6n\xeb\x8 # failJSON: { "time": "2010-03-15T15:44:47", "match": true , "host": "121.222.2.133" } [Mon Mar 15 15:44:47 2010] [error] [client 121.222.2.133] Invalid URI in request n\xed*\xbe*\xab\xefd\x80\xb5\xae\xf6\x01\x10M?\xf2\xce\x13\x9c\xd7\xa0N\xa7\xdb%0\xde\xe0\xfc\xd2\xa0\xfe\xe9w\xee\xc4`v\x9b[{\x0c:\xcb\x93\xc6\xa0\x93\x9c`l\\\x8d\xc9 +# http://forum.nconf.org/viewtopic.php?f=14&t=427&p=1488 +# failJSON: { "time": "2010-07-30T11:23:54", "match": true , "host": "10.85.6.69" } +[Fri Jul 30 11:23:54 2010] [error] [client 10.85.6.69] request failed: URI too long (longer than 8190) From a4718eb64402d2329bc3891c68024e7d1c61277f Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 11 Nov 2013 10:38:02 +1100 Subject: [PATCH 059/165] ENH: apache-overflow filter to have HTTP-2.4 message IDs and test samples --- config/filter.d/apache-overflows.conf | 19 +++++++++++++++++-- testcases/files/logs/apache-overflows | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/config/filter.d/apache-overflows.conf b/config/filter.d/apache-overflows.conf index 68669222..92551525 100644 --- a/config/filter.d/apache-overflows.conf +++ b/config/filter.d/apache-overflows.conf @@ -8,14 +8,29 @@ before = apache-common.conf [Definition] -failregex = ^%(_apache_error_client)s (Invalid (method|URI) in request|request failed: URI too long \(longer than \d+\)|erroneous characters after protocol string) +failregex = ^%(_apache_error_client)s ((AH0013[456]: )?Invalid (method|URI) in request .*( - possible attempt to establish SSL connection on non-SSL port)?|(AH00565: )?request failed: URI too long \(longer than \d+\)|request failed: erroneous characters after protocol string: .*|AH00566: request failed: invalid characters in URI)$ ignoreregex = -# DEV Noptes: +# DEV Notes: # # fgrep -r 'URI too long' httpd-2.* # httpd-2.2.25/server/protocol.c: "request failed: URI too long (longer than %d)", r->server->limit_req_line); # httpd-2.4.4/server/protocol.c: "request failed: URI too long (longer than %d)", # +# fgrep -r 'in request' ../httpd-2.* | fgrep Invalid +# httpd-2.2.25/server/core.c: "Invalid URI in request %s", r->the_request); +# httpd-2.2.25/server/core.c: "Invalid method in request %s", r->the_request); +# httpd-2.2.25/docs/manual/rewrite/flags.html.fr:avertissements 'Invalid URI in request'. +# httpd-2.4.4/server/core.c: "Invalid URI in request %s", r->the_request); +# httpd-2.4.4/server/core.c: "Invalid method in request %s - possible attempt to establish SSL connection on non-SSL port", r->the_request); +# httpd-2.4.4/server/core.c: "Invalid method in request %s", r->the_request); +# +# fgrep -r 'invalid characters in URI' httpd-2.* +# httpd-2.4.4/server/protocol.c: "request failed: invalid characters in URI"); +# +# http://svn.apache.org/viewvc/httpd/httpd/trunk/server/core.c?r1=739382&r2=739620&pathrev=739620 +# ...possible attempt to establish SSL connection on non-SSL port +# +# https://wiki.apache.org/httpd/ListOfErrors # Author: Tim Connors diff --git a/testcases/files/logs/apache-overflows b/testcases/files/logs/apache-overflows index 69e5fd49..01f54c7d 100644 --- a/testcases/files/logs/apache-overflows +++ b/testcases/files/logs/apache-overflows @@ -1,7 +1,25 @@ +# http://osdir.com/ml/debian-bugs-dist/2010-03/msg05840.html # failJSON: { "time": "2010-03-16T15:39:29", "match": true , "host": "58.179.109.179" } [Tue Mar 16 15:39:29 2010] [error] [client 58.179.109.179] Invalid URI in request \xf9h\xa9\xf3\x88\x8cXKj \xbf-l*4\x87n\xe4\xfe\xd4\x1d\x06\x8c\xf8m\\rS\xf6n\xeb\x8 # failJSON: { "time": "2010-03-15T15:44:47", "match": true , "host": "121.222.2.133" } [Mon Mar 15 15:44:47 2010] [error] [client 121.222.2.133] Invalid URI in request n\xed*\xbe*\xab\xefd\x80\xb5\xae\xf6\x01\x10M?\xf2\xce\x13\x9c\xd7\xa0N\xa7\xdb%0\xde\xe0\xfc\xd2\xa0\xfe\xe9w\xee\xc4`v\x9b[{\x0c:\xcb\x93\xc6\xa0\x93\x9c`l\\\x8d\xc9 + # http://forum.nconf.org/viewtopic.php?f=14&t=427&p=1488 # failJSON: { "time": "2010-07-30T11:23:54", "match": true , "host": "10.85.6.69" } [Fri Jul 30 11:23:54 2010] [error] [client 10.85.6.69] request failed: URI too long (longer than 8190) +# failJSON: { "time": "2010-10-27T23:16:37", "match": true , "host": "187.117.240.164" } +[Wed Oct 27 23:16:37 2010] [error] [client 187.117.240.164] Invalid URI in request x\xb2\xa1:SMl\xcc{\xfd"\xd1\x91\x84!d\x0e~\xf6:\xfbVu\xdf\xc3\xdb[\xa9\xfe\xd3lpz\x92\xbf\x9f5\xa3\xbbvF\xbc\xee\x1a\xb1\xb0\xf8K\xecE\xbc\xe8r\xacx=\xc7>\xb5\xbd\xa3\xda\xe9\xf09\x95"fd\x1c\x05\x1c\xd5\xf3#:\x91\xe6WE\xdb\xadN;k14;\xdcr\xad\x9e\xa8\xde\x95\xc3\xebw\xa0\xb1N\x8c~\xf1\xcfSY\xd5zX\xd7\x0f\vH\xe4\xb5(\xcf,3\xc98\x19\xefYq@\xd2I\x96\xfb\xc7\xa9\xae._{S\xd1\x9c\xad\x17\xdci\x9b\xca\x93\xafSM\xb8\x99\xd9|\xc2\xd8\xc9\xe7\xe9O\x99\xad\x19\xc3V]\xcc\xddR\xf7$\xaa\xb8\x18\xe0f\xb8\xff + + +# Could be apache-2.2 or earlier +# http://www.aota.net/forums/showthread.php?t=15796 +# failJSON: { "time": "2003-11-14T16:11:55", "match": true , "host": "1.2.3.4" } +[Fri Nov 14 16:11:55 2003] [error] [client 1.2.3.4] request failed: erroneous characters after protocol string: User-Agent: Mozilla/5.0 (Windows; U; Win98; en-US; m18) Gecko/20001108 Netscape6/6.0 + +# http://forum.directadmin.com/showthread.php?t=22412 +# failJSON: { "time": "2007-11-15T03:09:59", "match": true , "host": "89.189.71.87" } +[Thu Nov 15 03:09:59 2007] [error] [client 89.189.71.87] Invalid method in request NOOP + +# https://issues.apache.org/bugzilla/show_bug.cgi?id=46123 +# failJSON: { "time": "2008-10-29T11:55:14", "match": true , "host": "127.0.0.1" } +[Wed Oct 29 11:55:14 2008] [error] [client 127.0.0.1] Invalid method in request \x16\x03\x01 - possible attempt to establish SSL connection when the server isn't expecting it From c81ed538056c2a9ed163de2354fbd93de731b98c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 11 Nov 2013 10:40:12 +1100 Subject: [PATCH 060/165] TST: change source URL --- testcases/files/logs/apache-overflows | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcases/files/logs/apache-overflows b/testcases/files/logs/apache-overflows index 01f54c7d..376114c4 100644 --- a/testcases/files/logs/apache-overflows +++ b/testcases/files/logs/apache-overflows @@ -1,4 +1,4 @@ -# http://osdir.com/ml/debian-bugs-dist/2010-03/msg05840.html +# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=574182 # failJSON: { "time": "2010-03-16T15:39:29", "match": true , "host": "58.179.109.179" } [Tue Mar 16 15:39:29 2010] [error] [client 58.179.109.179] Invalid URI in request \xf9h\xa9\xf3\x88\x8cXKj \xbf-l*4\x87n\xe4\xfe\xd4\x1d\x06\x8c\xf8m\\rS\xf6n\xeb\x8 # failJSON: { "time": "2010-03-15T15:44:47", "match": true , "host": "121.222.2.133" } From 648d48c35516b5781b36dfa504a77764456dcbfe Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 11 Nov 2013 10:49:11 +1100 Subject: [PATCH 061/165] ENH: apache-2.4 message IDs for filter apache-noscript --- config/filter.d/apache-noscript.conf | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/config/filter.d/apache-noscript.conf b/config/filter.d/apache-noscript.conf index 4ecf349a..f3c6246a 100644 --- a/config/filter.d/apache-noscript.conf +++ b/config/filter.d/apache-noscript.conf @@ -9,10 +9,16 @@ before = apache-common.conf [Definition] -failregex = ^%(_apache_error_client)s (File does not exist|script not found or unable to stat): /\S*(\.php|\.asp|\.exe|\.pl)\s*$ +failregex = ^%(_apache_error_client)s ((AH001(28|30): )?File does not exist|(AH01264: )?script not found or unable to stat): /\S*(\.php|\.asp|\.exe|\.pl)\s*$ ^%(_apache_error_client)s script '/\S*(\.php|\.asp|\.exe|\.pl)\S*' not found or unable to stat\s*$ ignoreregex = +# DEV Notes: +# +# https://wiki.apache.org/httpd/ListOfErrors for apache error IDs +# +# Second regex, script '/\S*(\.php|\.asp|\.exe|\.pl)\S*' not found or unable to stat\s*$ is Before http-2.2 +# # Author: Cyril Jaquier From eb9663eb4fd8248c7a6ce82d04edabb3a701c798 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 12 Nov 2013 09:22:41 +1100 Subject: [PATCH 062/165] BF/ENH: asterisk connection ID is a hex not decimal number. Add "Rejecting unknown SIP connection from " regex thanks to Jonathan Lanning --- ChangeLog | 3 +++ THANKS | 1 + config/filter.d/asterisk.conf | 3 ++- testcases/files/logs/asterisk | 3 +++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 27e598ef..50b8bb8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,6 +32,9 @@ some obscure corner of the Internet. those filters were used. - Fixes: + Jonathan Lanning + * filter.d/asterisk -- identified another regex for blocking. Also channel + ID is hex not decimal as noted in sample logs provided. Daniel Black & Marcel Dopita * filter.d/apache-auth -- fixed and apache auth samples provide. Closes gh-286 Yaroslav Halchenko diff --git a/THANKS b/THANKS index 5f6d1b2b..13303c21 100644 --- a/THANKS +++ b/THANKS @@ -34,6 +34,7 @@ Guillaume Delvit Hanno 'Rince' Wagner Iain Lea Jonathan Kamens +Jonathan Lanning Jonathan Underwood Joël Bertrand JP Espinosa diff --git a/config/filter.d/asterisk.conf b/config/filter.d/asterisk.conf index f77a1557..3c1a97df 100644 --- a/config/filter.d/asterisk.conf +++ b/config/filter.d/asterisk.conf @@ -6,7 +6,7 @@ __pid_re = (?:\[\d+\]) # All Asterisk log messages begin like this: -log_prefix= \[\]\s*(?:NOTICE|SECURITY)%(__pid_re)s:?(?:\[\S+\d*\])? \S+:\d* +log_prefix= \[\]\s*(?:NOTICE|SECURITY)%(__pid_re)s:?(?:\[C-[\da-f]*\])? \S+:\d* failregex = ^%(log_prefix)s Registration from '[^']*' failed for '(:\d+)?' - (Wrong password|No matching peer found|Username/auth name mismatch|Device does not match ACL|Peer is not supposed to register|ACL error \(permit/deny\)|Not a local domain)$ ^%(log_prefix)s Call from '[^']*' \(:\d+\) to extension '\d+' rejected because extension not found in context 'default'\.$ @@ -16,6 +16,7 @@ failregex = ^%(log_prefix)s Registration from '[^']*' failed for '(:\d+)?' ^%(log_prefix)s Failed to authenticate (user|device) [^@]+@\S*$ ^%(log_prefix)s (?:handle_request_subscribe: )?Sending fake auth rejection for (device|user) \d*>;tag=\w+\S*$ ^%(log_prefix)s SecurityEvent="(FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)",EventTV="[\d-]+",Severity="[\w]+",Service="[\w]+",EventVersion="\d+",AccountID="\d+",SessionID="0x[\da-f]+",LocalAddress="IPV[46]/(UD|TC)P/[\da-fA-F:.]+/\d+",RemoteAddress="IPV[46]/(UD|TC)P//\d+"(,Challenge="\w+",ReceivedChallenge="\w+")?(,ReceivedHash="[\da-f]+")?$ + ^\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? Ext\. s: "Rejecting unknown SIP connection from "$ ignoreregex = diff --git a/testcases/files/logs/asterisk b/testcases/files/logs/asterisk index b2eb7738..60c89d5f 100644 --- a/testcases/files/logs/asterisk +++ b/testcases/files/logs/asterisk @@ -40,3 +40,6 @@ [2009-12-22 16:35:24] NOTICE[14916]: chan_sip.c:15644 handle_request_subscribe: Sending fake auth rejection for user ;tag=6pwd6erg54 # failJSON: { "time": "2013-07-06T09:09:25", "match": true , "host": "141.255.164.106" } [2013-07-06 09:09:25] SECURITY[3308] res_security_log.c: SecurityEvent="InvalidPassword",EventTV="1373098165-824497",Severity="Error",Service="SIP",EventVersion="2",AccountID="972592891005",SessionID="0x88aab6c",LocalAddress="IPV4/UDP/92.28.73.180/5060",RemoteAddress="IPV4/UDP/141.255.164.106/5084",Challenge="41d26de5",ReceivedChallenge="41d26de5",ReceivedHash="7a6a3a2e95a05260aee612896e1b4a39" + +# failJSON: { "time": "2013-11-11T14:33:38", "match": true , "host": "192.168.55.152" } +[2013-11-11 14:33:38] WARNING[6756][C-0000001d] Ext. s: "Rejecting unknown SIP connection from 192.168.55.152" From c272573fe3318b18cd76d0655481d4fe04b6d9e1 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 12 Nov 2013 18:06:16 +1100 Subject: [PATCH 063/165] ENH: DoS resistant dropbear filter --- config/filter.d/dropbear.conf | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/config/filter.d/dropbear.conf b/config/filter.d/dropbear.conf index 54d8166b..288b0882 100644 --- a/config/filter.d/dropbear.conf +++ b/config/filter.d/dropbear.conf @@ -23,8 +23,8 @@ before = common.conf _daemon = dropbear -failregex = ^%(__prefix_line)s[Ll]ogin attempt for nonexistent user ('.*' )?from :.*$ - ^%(__prefix_line)s[Bb]ad (PAM )?password attempt for .+ from .*$ +failregex = ^%(__prefix_line)s[Ll]ogin attempt for nonexistent user ('.*' )?from :\d+$ + ^%(__prefix_line)s[Bb]ad (PAM )?password attempt for .+ from (:\d+)?$ ^%(__prefix_line)s[Ee]xit before auth \(user '.+', \d+ fails\): Max auth tries reached - user '.+' from :\d+\s*$ ignoreregex = @@ -37,5 +37,12 @@ ignoreregex = # # The second last failregex line we need to match with the modified dropbear. # +# For the second regex the following apply: +# +# http://www.netmite.com/android/mydroid/external/dropbear/svr-authpam.c +# http://svn.dd-wrt.com/changeset/16642#file64 +# +# http://svn.dd-wrt.com/changeset/16642/src/router/dropbear/svr-authpasswd.c +# # Author: Francis Russell # Zak B. Elep From 52972164a273963ded6f0a244deab2f938e49cd4 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 12 Nov 2013 18:13:35 +1100 Subject: [PATCH 064/165] BF: exim filter to be DoS resistant --- config/filter.d/exim.conf | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/config/filter.d/exim.conf b/config/filter.d/exim.conf index 5f786594..66743390 100644 --- a/config/filter.d/exim.conf +++ b/config/filter.d/exim.conf @@ -16,7 +16,7 @@ before = exim-common.conf failregex = ^%(pid)s %(host_info)ssender verify fail for <\S+>: (?:Unknown user|Unrouteable address|all relevant MX records point to non-existent hosts)\s*$ ^%(pid)s (plain|login) authenticator failed for (\S+ )?\(\S+\) \[\]: 535 Incorrect authentication data( \(set_id=.*\)|: \d+ Time\(s\))?\s*$ ^%(pid)s %(host_info)sF=(<>|[^@]+@\S+) rejected RCPT [^@]+@\S+: (relay not permitted|Sender verify failed|Unknown user)\s*$ - ^%(pid)s SMTP protocol synchronization error \(.*\): rejected (connection from|"\S+") %(host_info)s(next )?input=".*"\s*$ + ^%(pid)s SMTP protocol synchronization error \([^)]*\): rejected (connection from|"\S+") %(host_info)s(next )?input=".*"\s*$ ^%(pid)s SMTP call from \S+ \[\](:\d+)? (I=\[\S+\]:\d+ )?dropped: too many nonmail commands \(last was "\S+"\)\s*$ ignoreregex = @@ -24,5 +24,9 @@ ignoreregex = # DEV Notes: # The %(host_info) defination contains a match # +# SMTP protocol synchronization error \([^)]*\) <- This needs to be non-greedy +# to void capture beyond ")" to avoid a DoS Injection vulnerabilty as input= is +# user injectable data. +# # Author: Cyril Jaquier # Daniel Black (rewrote with strong regexs) From be60518218cc859af4e7ee57e4d22beab27205d5 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 12 Nov 2013 18:57:01 +1100 Subject: [PATCH 065/165] BF/ENH: DoS resistant roundcube-auth with test cases and more variation in IMAP error given --- config/filter.d/roundcube-auth.conf | 19 ++++++++++++++++--- testcases/files/logs/roundcube-auth | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/config/filter.d/roundcube-auth.conf b/config/filter.d/roundcube-auth.conf index 279c5edd..b093f69c 100644 --- a/config/filter.d/roundcube-auth.conf +++ b/config/filter.d/roundcube-auth.conf @@ -9,8 +9,21 @@ before = common.conf [Definition] -failregex = ^\s*(\[(\s[+-][0-9]{4})?\])?(%(__hostname)s roundcube: IMAP Error)?: (FAILED login|Login failed) for .*? from (\. AUTHENTICATE .*)?\s*$ +failregex = ^\s*(\[(\s[+-][0-9]{4})?\])?(%(__hostname)s roundcube: IMAP Error)?: (FAILED login|Login failed) for .*? from (\. .* in .*?/rcube_imap\.php on line \d+ \(\S+ \S+\))?$ ignoreregex = - -# Author: Teodor Micu & Yaroslav Halchenko & terence namusonge +# DEV Notes: +# +# Source: https://github.com/roundcube/roundcubemail/blob/master/program/lib/Roundcube/rcube_imap.php#L180 +# +# Part after comes straight from IMAP server up until the " in ....." +# Earlier versions didn't log the IMAP response hence optional. +# +# DoS resistance: +# +# Assume that the user can inject "from " into the imap response +# somehow. Write test cases around this to ensure that the combination of +# arbitary user input and IMAP response doesn't inject the wrong IP for +# fail2ban +# +# Author: Teodor Micu & Yaroslav Halchenko & terence namusonge & Daniel Black diff --git a/testcases/files/logs/roundcube-auth b/testcases/files/logs/roundcube-auth index 7c16efbd..43a42192 100644 --- a/testcases/files/logs/roundcube-auth +++ b/testcases/files/logs/roundcube-auth @@ -4,3 +4,21 @@ May 26 07:12:40 hamster roundcube: IMAP Error: Login failed for sales@example.com from 10.1.1.47 # failJSON: { "time": "2005-07-11T03:06:37", "match": true , "host": "1.2.3.4" } Jul 11 03:06:37 myhostname roundcube: IMAP Error: Login failed for admin from 1.2.3.4. AUTHENTICATE PLAIN: A0002 NO Login failed. in /usr/share/roundcube/program/include/rcube_imap.php on line 205 (POST /wmail/?_task=login&_action=login) + +# Made up to attempts to inject a DoS on the server. Assume the user can manipulate the IMAP error response +# +# user = admin from 127.0.0.1 +# failJSON: { "time": "2005-07-11T03:06:37", "match": true , "host": "1.2.3.4" } +Jul 11 03:06:37 myhostname roundcube: IMAP Error: Login failed for admin from 127.0.0.1 from 1.2.3.4. AUTHENTICATE PLAIN: A0002 NO Login failed. in /usr/share/roundcube/program/include/rcube_imap.php on line 205 (POST /wmail/?_task=login&_action=login) +# +# IMAP server logs user=${username} +# failJSON: { "time": "2005-07-11T03:06:37", "match": true , "host": "1.2.3.4" } +Jul 11 03:06:37 myhostname roundcube: IMAP Error: Login failed for admin from 127.0.0.1 from 1.2.3.4. AUTHENTICATE PLAIN: A0002 NO Login failed. user=admin from 127.0.0.1 in /usr/share/roundcube/program/include/rcube_imap.php on line 205 (POST /wmail/?_task=login&_action=login) +# +# Old roundcube version - no IMAP response +# failJSON: { "time": "2005-07-11T03:06:37", "match": true , "host": "1.2.3.4" } +Jul 11 03:06:37 myhostname roundcube: IMAP Error: Login failed for admin from 127.0.0.1 from 1.2.3.4 +# +# user = admin from 127.0.0.1 in +# failJSON: { "time": "2005-07-11T03:06:37", "match": true , "host": "1.2.3.4" } +Jul 11 03:06:37 myhostname roundcube: IMAP Error: Login failed for admin from 127.0.0.1 in from 1.2.3.4. AUTHENTICATE PLAIN: A0002 NO Login failed. user=admin from 127.0.0.1 in in /usr/share/roundcube/program/include/rcube_imap.php on line 205 (POST /wmail/?_task=login&_action=login) From d0498bec691ab31a8b0968b873c3d11b24609224 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 13 Nov 2013 08:05:08 +1100 Subject: [PATCH 066/165] DOC: finalise 0.8.11 release --- ChangeLog | 10 ++++++++-- MANIFEST | 3 +++ README.md | 2 +- common/version.py | 2 +- man/fail2ban-client.1 | 6 +++--- man/fail2ban-regex.1 | 4 ++-- man/fail2ban-server.1 | 6 +++--- 7 files changed, 21 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 50b8bb8e..e901d9af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,10 +4,10 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ================================================================================ -Fail2Ban (version 0.8.11.pre1) 2013/10/30 +Fail2Ban (version 0.8.11) 2013/11/13 ================================================================================ -ver. 0.8.11 (2013/11/XXX) - loves-unittests-and-tight-DoS-free-filter-regexes +ver. 0.8.11 (2013/11/13) - loves-unittests-and-tight-DoS-free-filter-regexes ----------- In light of CVE-2013-2178 that triggered our last release we have put @@ -23,6 +23,12 @@ please provide us with example log lines on the github issue tracker http://github.com/fail2ban/fail2ban/issues and NOT on a random blog in some obscure corner of the Internet. +Many thanks to our contributors for this release Daniel Black, Yaroslav +Halchenko, Steven Hiscocks, Mark McKinstry, Andy Fragen, Orion Poplawski, +Alexander Dietrich, JP Espinosa, Jamyn Shanley, Beau Raines, François +Boulogne and others who have helped on IRC and mailing list, logged issues +and bug requests. + - IMPORTANT incompatible changes: Filter name changes: * 'lighttpd-fastcgi' filter has been renamed to 'suhosin' diff --git a/MANIFEST b/MANIFEST index 43927a7a..0e0eb327 100644 --- a/MANIFEST +++ b/MANIFEST @@ -60,6 +60,7 @@ testcases/files/logs/exim testcases/files/logs/suhosin testcases/files/logs/mysqld-auth testcases/files/logs/named-refused +testcases/files/logs/nginx-http-auth testcases/files/logs/pam-generic testcases/files/logs/postfix testcases/files/logs/proftpd @@ -139,6 +140,7 @@ config/filter.d/apache-badbots.conf config/filter.d/apache-nohome.conf config/filter.d/apache-noscript.conf config/filter.d/apache-overflows.conf +config/filter.d/nginx-http-auth.conf config/filter.d/courierlogin.conf config/filter.d/couriersmtp.conf config/filter.d/cyrus-imap.conf @@ -239,3 +241,4 @@ files/bash-completion files/fail2ban-tmpfiles.conf files/fail2ban.service files/ipmasq-ZZZzzz_fail2ban.rul +files/gen_badbots diff --git a/README.md b/README.md index 7c00233f..24ed11ff 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ / _|__ _(_) |_ ) |__ __ _ _ _ | _/ _` | | |/ /| '_ \/ _` | ' \ |_| \__,_|_|_/___|_.__/\__,_|_||_| - v0.8.11-pre1 2013/10/30 + v0.8.11 2013/11/13 ## Fail2Ban: ban hosts that cause multiple authentication errors diff --git a/common/version.py b/common/version.py index a0cb94ea..c699a8db 100644 --- a/common/version.py +++ b/common/version.py @@ -24,4 +24,4 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko" __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko" __license__ = "GPL" -version = "0.8.11.pre1" +version = "0.8.11" diff --git a/man/fail2ban-client.1 b/man/fail2ban-client.1 index aab2dde4..c5ccb803 100644 --- a/man/fail2ban-client.1 +++ b/man/fail2ban-client.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.12. -.TH FAIL2BAN-CLIENT "1" "October 2013" "fail2ban-client v0.8.11.pre1" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.4. +.TH FAIL2BAN-CLIENT "1" "November 2013" "fail2ban-client v0.8.11" "User Commands" .SH NAME fail2ban-client \- configure and control the server .SH SYNOPSIS .B fail2ban-client [\fIOPTIONS\fR] \fI\fR .SH DESCRIPTION -Fail2Ban v0.8.11.pre1 reads log file that contains password failure report +Fail2Ban v0.8.11 reads log file that contains password failure report and bans the corresponding IP addresses using firewall rules. .SH OPTIONS .TP diff --git a/man/fail2ban-regex.1 b/man/fail2ban-regex.1 index 4a0e272b..e2c99565 100644 --- a/man/fail2ban-regex.1 +++ b/man/fail2ban-regex.1 @@ -1,5 +1,5 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.12. -.TH FAIL2BAN-REGEX "1" "October 2013" "fail2ban-regex 0.8.11.pre1" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.4. +.TH FAIL2BAN-REGEX "1" "November 2013" "fail2ban-regex 0.8.11" "User Commands" .SH NAME fail2ban-regex \- test Fail2ban "failregex" option .SH SYNOPSIS diff --git a/man/fail2ban-server.1 b/man/fail2ban-server.1 index 7e09b49e..147bdeaa 100644 --- a/man/fail2ban-server.1 +++ b/man/fail2ban-server.1 @@ -1,12 +1,12 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.12. -.TH FAIL2BAN-SERVER "1" "October 2013" "fail2ban-server v0.8.11.pre1" "User Commands" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.4. +.TH FAIL2BAN-SERVER "1" "November 2013" "fail2ban-server v0.8.11" "User Commands" .SH NAME fail2ban-server \- start the server .SH SYNOPSIS .B fail2ban-server [\fIOPTIONS\fR] .SH DESCRIPTION -Fail2Ban v0.8.11.pre1 reads log file that contains password failure report +Fail2Ban v0.8.11 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 From 752ea054db514c0d7a47f86d7673fc63edaa304f Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 13 Nov 2013 09:01:52 +1100 Subject: [PATCH 067/165] DOC: post release version change --- DEVELOP | 10 +++++----- common/version.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/DEVELOP b/DEVELOP index d776d8f7..500f119f 100644 --- a/DEVELOP +++ b/DEVELOP @@ -770,23 +770,23 @@ Look for errors like: Which indicates that testcases/files/logs/mysqld.log has been moved or is a directory - tar -C /tmp -jxf dist/fail2ban-0.8.11.tar.bz2 + tar -C /tmp -jxf dist/fail2ban-0.8.12.tar.bz2 # clean up current direcory - diff -rul --exclude \*.pyc . /tmp/fail2ban-0.8.11/ + diff -rul --exclude \*.pyc . /tmp/fail2ban-0.8.12/ # Only differences should be files that you don't want distributed. # Ensure the tests work from the tarball - cd /tmp/fail2ban-0.8.11/ && ./fail2ban-testcases-all + cd /tmp/fail2ban-0.8.12/ && ./fail2ban-testcases-all # Add/finalize the corresponding entry in the ChangeLog To generate a list of committers use e.g. - git shortlog -sn 0.8.10.. | sed -e 's,^[ 0-9\t]*,,g' | tr '\n' '\|' | sed -e 's:|:, :g' + git shortlog -sn 0.8.11.. | sed -e 's,^[ 0-9\t]*,,g' | tr '\n' '\|' | sed -e 's:|:, :g' Ensure the top of the ChangeLog has the right version and current date. @@ -857,7 +857,7 @@ Post Release Add the following to the top of the ChangeLog -ver. 0.8.12 (2013/XX/XXX) - wanna-be-released +ver. 0.8.13 (2014/XX/XXX) - wanna-be-released ----------- - Fixes: diff --git a/common/version.py b/common/version.py index c699a8db..eec5e794 100644 --- a/common/version.py +++ b/common/version.py @@ -24,4 +24,4 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko" __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko" __license__ = "GPL" -version = "0.8.11" +version = "0.8.11.dev" From a7604c899fba5835891c7650939c0b0e0ed7293e Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 13 Nov 2013 09:43:36 +1100 Subject: [PATCH 068/165] DOC: list Wiki pages to update after a release --- DEVELOP | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/DEVELOP b/DEVELOP index 500f119f..3766d192 100644 --- a/DEVELOP +++ b/DEVELOP @@ -839,10 +839,15 @@ Which indicates that testcases/files/logs/mysqld.log has been moved or is a dire page: http://www.fail2ban.org/wiki/index.php/Commands * Update: - http://www.fail2ban.org/wiki/index.php/Downloads + http://www.fail2ban.org/wiki/index.php?title=Template:Fail2ban_Versions&action=edit + + http://www.fail2ban.org/wiki/index.php?title=Template:Fail2ban_News&action=edit + move old bits to: + http://www.fail2ban.org/wiki/index.php?title=Template:Fail2ban_OldNews&action=edit + + http://www.fail2ban.org/wiki/index.php?title=Template:Fail2ban_Versions&action=edit http://www.fail2ban.org/wiki/index.php/ChangeLog http://www.fail2ban.org/wiki/index.php/Requirements (Check requirement) - http://www.fail2ban.org/wiki/index.php/Main_Page (Add to News) http://www.fail2ban.org/wiki/index.php/Features * See if any filters are upgraded: From ed212fcdccd155ef3cb9b053082c1b843d14fc0f Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 16 Nov 2013 09:40:05 +1100 Subject: [PATCH 069/165] DOC: new ChangeLog header --- ChangeLog | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e901d9af..98792d9e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,9 +4,21 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ================================================================================ -Fail2Ban (version 0.8.11) 2013/11/13 +Fail2Ban (version 0.8.12.dev) 2013/11/13 ================================================================================ +ver. 0.8.12 (2013/12/XX) - things-can-only-get-better +----------- + +- IMPORTANT incompatible changes: + +- Fixes: + +- New Features: + +- Enhancements: + + ver. 0.8.11 (2013/11/13) - loves-unittests-and-tight-DoS-free-filter-regexes ----------- From 88eff70774fe96a5f241ae3d5365f504a3df4c8b Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 16 Nov 2013 09:43:15 +1100 Subject: [PATCH 070/165] ENH: filter.d/solid-pop3d added --- ChangeLog | 3 +++ THANKS | 1 + config/filter.d/solid-pop3d.conf | 18 ++++++++++++++++++ testcases/files/logs/solid-pop3d | 2 ++ 4 files changed, 24 insertions(+) create mode 100644 config/filter.d/solid-pop3d.conf create mode 100644 testcases/files/logs/solid-pop3d diff --git a/ChangeLog b/ChangeLog index 98792d9e..b93a1c31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,6 +16,9 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - New Features: + Daniel Black + * filter.d/solid-pop3d -- added thanks to Jacques Lav!gnotte on mailinglist. + - Enhancements: diff --git a/THANKS b/THANKS index 13303c21..ee3922dd 100644 --- a/THANKS +++ b/THANKS @@ -33,6 +33,7 @@ Georgiy Mernov Guillaume Delvit Hanno 'Rince' Wagner Iain Lea +Jacques Lav!gnotte Jonathan Kamens Jonathan Lanning Jonathan Underwood diff --git a/config/filter.d/solid-pop3d.conf b/config/filter.d/solid-pop3d.conf new file mode 100644 index 00000000..67deafb6 --- /dev/null +++ b/config/filter.d/solid-pop3d.conf @@ -0,0 +1,18 @@ +# Fail2Ban filter for unsuccesful solid-pop3 authentication attempts +# +# +[INCLUDES] + +before = common.conf + +[Definition] + +_daemon = solid-pop3d + +failregex = ^%(__prefix_line)sauthentication failed: no such user: .*? - $ + +ignoreregex = + +# DEV Notes: +# +# Authors: Daniel Black diff --git a/testcases/files/logs/solid-pop3d b/testcases/files/logs/solid-pop3d new file mode 100644 index 00000000..0574084d --- /dev/null +++ b/testcases/files/logs/solid-pop3d @@ -0,0 +1,2 @@ +# failJSON: { "time": "2004-11-15T00:34:53", "match": true , "host": "123.33.44.45" } +Nov 15 00:34:53 rmc1pt2-2-35-70 solid-pop3d[3822]: authentication failed: no such user: adrian - 123.33.44.45 From d4f6ca4f8531f332bcb7ce3a89102f60afaaa08e Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Sat, 16 Nov 2013 22:15:27 -0500 Subject: [PATCH 071/165] ENH: adding custom date format for proftpd when logging in its own log file (default on Debian) -- includes milliseconds Should resolve Debian #648276 --- server/datedetector.py | 7 +++++++ testcases/datedetectortestcase.py | 1 + testcases/files/logs/proftpd | 2 ++ 3 files changed, 10 insertions(+) diff --git a/server/datedetector.py b/server/datedetector.py index ab2dd174..b12a8d46 100644 --- a/server/datedetector.py +++ b/server/datedetector.py @@ -101,6 +101,13 @@ class DateDetector: template.setRegex("\d{2}/\d{2}/\d{4}:\d{2}:\d{2}:\d{2}") template.setPattern("%m/%d/%Y:%H:%M:%S") self._appendTemplate(template) + # proftpd 2013-11-16 21:43:03,296 + # So like Exim below but with ,subsecond + template = DateStrptime() + template.setName("Year-Month-Day Hour:Minute:Second[,subsecond]") + template.setRegex("\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d+") + template.setPattern("%Y-%m-%d %H:%M:%S,%f") + self._appendTemplate(template) # Exim 2006-12-21 06:43:20 template = DateStrptime() template.setName("Year-Month-Day Hour:Minute:Second") diff --git a/testcases/datedetectortestcase.py b/testcases/datedetectortestcase.py index de324aa6..4cc7dcfc 100644 --- a/testcases/datedetectortestcase.py +++ b/testcases/datedetectortestcase.py @@ -74,6 +74,7 @@ class DateDetectorTest(unittest.TestCase): (False, "23/Jan/2005:21:59:59"), (False, "01/23/2005:21:59:59"), (False, "2005-01-23 21:59:59"), + (False, "2005-01-23 21:59:59,099"), # proftpd (False, "23-Jan-2005 21:59:59"), (False, "23-01-2005 21:59:59"), (False, "01-23-2005 21:59:59.252"), # reported on f2b, causes Feb29 fix to break diff --git a/testcases/files/logs/proftpd b/testcases/files/logs/proftpd index 9687d992..b255e91e 100644 --- a/testcases/files/logs/proftpd +++ b/testcases/files/logs/proftpd @@ -14,3 +14,5 @@ Jun 14 00:09:59 platypus.ace-hosting.com.au proftpd[17839] platypus.ace-hosting. May 31 10:53:25 mail proftpd[15302]: xxxxxxxxxx (::ffff:1.2.3.4[::ffff:1.2.3.4]) - Maximum login attempts (3) exceeded # failJSON: { "time": "2004-12-05T15:44:32", "match": true , "host": "1.2.3.4" } Dec 5 15:44:32 serv1 proftpd[70944]: serv1.domain.com (example.com[1.2.3.4]) - USER jtittle@domain.org: no such user found from example.com [1.2.3.4] to 1.2.3.4:21 +# failJSON: { "time": "2013-11-16T21:59:30", "match": true , "host": "1.2.3.4", "desc": "proftpd-basic 1.3.5~rc3-2.1 on Debian uses date format with milliseconds if logging under /var/log/proftpd/proftpd.log" } +2013-11-16 21:59:30,121 novo proftpd[25891] localhost (andy[1.2.3.4]): USER kjsad: no such user found from andy [1.2.3.5] to ::ffff:192.168.1.14:21 From 82174ea4c4521731f3cb88cd84adfb261a8c74a0 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Sat, 16 Nov 2013 22:18:51 -0500 Subject: [PATCH 072/165] Changelog for preceding proftpd date format change --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 98792d9e..2369bc21 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,7 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - IMPORTANT incompatible changes: - Fixes: + - allow for ",milliseconds" in the custom date format of proftpd.log - New Features: From b3b9ea45597e4f8484afbefc6e0887617b61df82 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 18 Nov 2013 07:42:45 +1100 Subject: [PATCH 073/165] ENH: jail for solid-pop3d --- config/jail.conf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/config/jail.conf b/config/jail.conf index 486ea078..0de7f524 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -518,6 +518,14 @@ action = iptables-multiport[name=dovecot-auth, port="pop3,pop3s,imap,imaps,subm logpath = /var/log/secure +[solid-pop3d] + +enabled = false +filter = solid-pop3d +action = iptables-multiport[name=solid-pop3, port="pop3,pop3s", protocol=tcp] +logpath = /var/log/mail.log + + [selinux-ssh] enabled = false filter = selinux-ssh From dab2ddb9dad9c1c9061bc40589d56ecb5368787b Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 18 Nov 2013 07:57:16 +1100 Subject: [PATCH 074/165] ENH: recidive jail to block all protocols. Closes #440 --- ChangeLog | 1 + config/jail.conf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2369bc21..2e1a5b91 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,7 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - Fixes: - allow for ",milliseconds" in the custom date format of proftpd.log + - recidive jail to block all protocols. Closes gh-440 - New Features: diff --git a/config/jail.conf b/config/jail.conf index 486ea078..e9ca3313 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -408,7 +408,7 @@ maxretry = 5 enabled = false filter = recidive logpath = /var/log/fail2ban.log -action = iptables-allports[name=recidive] +action = iptables-allports[name=recidive,protocol=all] sendmail-whois-lines[name=recidive, logpath=/var/log/fail2ban.log] bantime = 604800 ; 1 week findtime = 86400 ; 1 day From 8aa20a7b0efdb8020e59db0f423d8382cf4d8d05 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 18 Nov 2013 07:59:56 +1100 Subject: [PATCH 075/165] ENH: credits for #440 recidive jail protocol=all --- ChangeLog | 2 +- THANKS | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2e1a5b91..dfecbc51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,7 +14,7 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - Fixes: - allow for ",milliseconds" in the custom date format of proftpd.log - - recidive jail to block all protocols. Closes gh-440 + - recidive jail to block all protocols. Closes gh-440. Thanks Ioan Indreias - New Features: diff --git a/THANKS b/THANKS index 13303c21..ac2f4439 100644 --- a/THANKS +++ b/THANKS @@ -33,6 +33,7 @@ Georgiy Mernov Guillaume Delvit Hanno 'Rince' Wagner Iain Lea +Ioan Indreias Jonathan Kamens Jonathan Lanning Jonathan Underwood From 0eea0a35db8061d51c35cba7bed7911ed822ca38 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 18 Nov 2013 08:58:23 +1100 Subject: [PATCH 076/165] ENH: filter.d/solid-pop3d - added log messages and regexes --- config/filter.d/solid-pop3d.conf | 13 ++++++++++++- testcases/files/logs/solid-pop3d | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/config/filter.d/solid-pop3d.conf b/config/filter.d/solid-pop3d.conf index 67deafb6..68ac0a8e 100644 --- a/config/filter.d/solid-pop3d.conf +++ b/config/filter.d/solid-pop3d.conf @@ -1,5 +1,7 @@ # Fail2Ban filter for unsuccesful solid-pop3 authentication attempts # +# Doesn't currently provide PAM support. Please contribute sample logs +# to http://github.com/fail2ban/fail2ban/issues. # [INCLUDES] @@ -9,10 +11,19 @@ before = common.conf _daemon = solid-pop3d -failregex = ^%(__prefix_line)sauthentication failed: no such user: .*? - $ +failregex = ^%(__prefix_line)sauthentication failed: (no such user|can't map user name): .*? - $ + ^%(__prefix_line)s(APOP )?authentication failed for (mapped )?user .*? - $ + ^%(__prefix_line)sroot login not allowed - $ + ^%(__prefix_line)scan't find APOP secret for user .*? - $ ignoreregex = # DEV Notes: # +# solid-pop3d needs to be compiled with --enable-logextend to support +# IP addresses in log messages. +# +# solid-pop3d-0.15/src/main.c contains all authentication errors +# except for PAM authentication messages ( src/authenticate.c ) +# # Authors: Daniel Black diff --git a/testcases/files/logs/solid-pop3d b/testcases/files/logs/solid-pop3d index 0574084d..3fe27e58 100644 --- a/testcases/files/logs/solid-pop3d +++ b/testcases/files/logs/solid-pop3d @@ -1,2 +1,22 @@ # failJSON: { "time": "2004-11-15T00:34:53", "match": true , "host": "123.33.44.45" } Nov 15 00:34:53 rmc1pt2-2-35-70 solid-pop3d[3822]: authentication failed: no such user: adrian - 123.33.44.45 + +# All below are manufactured from looking at log +# failJSON: { "time": "2004-11-15T00:34:53", "match": true , "host": "123.33.44.45" } +Nov 15 00:34:53 rmc1pt2-2-35-70 solid-pop3d[3822]: authentication failed: can't map user name: adrian - 123.33.44.45 + +# failJSON: { "time": "2004-11-15T00:34:53", "match": true , "host": "123.33.44.45" } +Nov 15 00:34:53 rmc1pt2-2-35-70 solid-pop3d[3822]: authentication failed for user adrain - 123.33.44.45 + +# failJSON: { "time": "2004-11-15T00:34:53", "match": true , "host": "123.33.44.45" } +Nov 15 00:34:53 rmc1pt2-2-35-70 solid-pop3d[3822]: authentication failed for mapped user adrain - 123.33.44.45 + +# failJSON: { "time": "2004-11-15T00:34:53", "match": true , "host": "123.33.44.45" } +Nov 15 00:34:53 rmc1pt2-2-35-70 solid-pop3d[3822]: root login not allowed - 123.33.44.45 + +# failJSON: { "time": "2004-11-15T00:34:53", "match": true , "host": "123.33.44.45" } +Nov 15 00:34:53 rmc1pt2-2-35-70 solid-pop3d[3822]: can't find APOP secret for user adrian - 123.33.44.45 + +# failJSON: { "time": "2004-11-15T00:34:53", "match": true , "host": "123.33.44.45" } +Nov 15 00:34:53 rmc1pt2-2-35-70 solid-pop3d[3822]: APOP authentication failed for user adrian - 123.33.44.45 + From 1ea68b2d0c5415709cebec0edd6dbca85e15be5c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 18 Nov 2013 09:44:26 +1100 Subject: [PATCH 077/165] DOC: filter.d/solid-pop3d - document lack of PAM support. Thanks to Jacques for the log messages --- config/filter.d/solid-pop3d.conf | 7 +++++-- testcases/files/logs/solid-pop3d | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/config/filter.d/solid-pop3d.conf b/config/filter.d/solid-pop3d.conf index 68ac0a8e..d97cc134 100644 --- a/config/filter.d/solid-pop3d.conf +++ b/config/filter.d/solid-pop3d.conf @@ -1,7 +1,7 @@ # Fail2Ban filter for unsuccesful solid-pop3 authentication attempts # -# Doesn't currently provide PAM support. Please contribute sample logs -# to http://github.com/fail2ban/fail2ban/issues. +# Doesn't currently provide PAM support as PAM log messages don't include rhost as +# remote IP. # [INCLUDES] @@ -25,5 +25,8 @@ ignoreregex = # # solid-pop3d-0.15/src/main.c contains all authentication errors # except for PAM authentication messages ( src/authenticate.c ) +# +# A pam authentication failure message (note no IP for rhost). +# Nov 17 23:17:50 emf1pt2-2-35-70 solid-pop3d[17176]: pam_unix(solid-pop3d:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost= user=jacques # # Authors: Daniel Black diff --git a/testcases/files/logs/solid-pop3d b/testcases/files/logs/solid-pop3d index 3fe27e58..45c4ecaf 100644 --- a/testcases/files/logs/solid-pop3d +++ b/testcases/files/logs/solid-pop3d @@ -20,3 +20,6 @@ Nov 15 00:34:53 rmc1pt2-2-35-70 solid-pop3d[3822]: can't find APOP secret for us # failJSON: { "time": "2004-11-15T00:34:53", "match": true , "host": "123.33.44.45" } Nov 15 00:34:53 rmc1pt2-2-35-70 solid-pop3d[3822]: APOP authentication failed for user adrian - 123.33.44.45 +# Real log messages again: +# failJSON: { "time": "2004-11-17T23:10:03", "match": true , "host": "190.16.165.230" } +Nov 17 23:10:03 emf1pt2-2-35-70 solid-pop3d[16993]: authentication failed for user jacques - 190.16.165.230 From 284f811c912af2f683c7eb150011337912516934 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 19 Nov 2013 10:27:55 +1100 Subject: [PATCH 078/165] BF: apache filters using error log weren't matched when referer existed in HTTP header --- ChangeLog | 1 + THANKS | 1 + config/filter.d/apache-auth.conf | 26 ++++++++++++++------------ config/filter.d/apache-noscript.conf | 4 ++-- config/filter.d/apache-overflows.conf | 2 +- testcases/files/logs/apache-auth | 3 +++ 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2369bc21..4eb8968c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,7 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - Fixes: - allow for ",milliseconds" in the custom date format of proftpd.log + - allow for ", referer ..." in apache-* filter for apache error logs. - New Features: diff --git a/THANKS b/THANKS index 13303c21..45528bc7 100644 --- a/THANKS +++ b/THANKS @@ -70,6 +70,7 @@ Tyler Vaclav Misek Vincent Deffontaines Yaroslav Halchenko +Winston Smith ykimon Yehuda Katz zugeschmiert diff --git a/config/filter.d/apache-auth.conf b/config/filter.d/apache-auth.conf index 3df91c15..f4213487 100644 --- a/config/filter.d/apache-auth.conf +++ b/config/filter.d/apache-auth.conf @@ -10,19 +10,19 @@ before = apache-common.conf [Definition] -failregex = ^%(_apache_error_client)s (AH01797: )?client denied by server configuration: (uri )?\S*\s*$ - ^%(_apache_error_client)s (AH01617: )?user .* authentication failure for "\S*": Password Mismatch$ - ^%(_apache_error_client)s (AH01618: )?user .* not found(: )?\S*\s*$ - ^%(_apache_error_client)s (AH01614: )?client used wrong authentication scheme: \S*\s*$ +failregex = ^%(_apache_error_client)s (AH01797: )?client denied by server configuration: (uri )?\S*(, referer: \S+)?\s*$ + ^%(_apache_error_client)s (AH01617: )?user .*? authentication failure for "\S*": Password Mismatch(, referer: \S+)?$ + ^%(_apache_error_client)s (AH01618: )?user .*? not found(: )?\S*(, referer: \S+)?\s*$ + ^%(_apache_error_client)s (AH01614: )?client used wrong authentication scheme: \S*(, referer: \S+)?\s*$ ^%(_apache_error_client)s (AH\d+: )?Authorization of user \S+ to access \S* failed, reason: .*$ - ^%(_apache_error_client)s (AH0179[24]: )?(Digest: )?user .*: password mismatch: \S*\s*$ - ^%(_apache_error_client)s (AH0179[01]: |Digest: )user `.*' in realm `.+' (not found|denied by provider): \S*\s*$ - ^%(_apache_error_client)s (AH01631: )?user .*: authorization failure for "\S*":\s*$ - ^%(_apache_error_client)s (AH01775: )?(Digest: )?invalid nonce .* received - length is not \S+\s*$ - ^%(_apache_error_client)s (AH01788: )?(Digest: )?realm mismatch - got `.*' but expected `.+'\s*$ - ^%(_apache_error_client)s (AH01789: )?(Digest: )?unknown algorithm `.*' received: \S*\s*$ - ^%(_apache_error_client)s (AH01793: )?invalid qop `.*' received: \S*\s*$ - ^%(_apache_error_client)s (AH01777: )?(Digest: )?invalid nonce .* received - user attempted time travel\s*$ + ^%(_apache_error_client)s (AH0179[24]: )?(Digest: )?user .*?: password mismatch: \S*(, referer: \S+)?\s*$ + ^%(_apache_error_client)s (AH0179[01]: |Digest: )user `.*?' in realm `.+' (not found|denied by provider): \S*(, referer: \S+)?\s*$ + ^%(_apache_error_client)s (AH01631: )?user .*?: authorization failure for "\S*":(, referer: \S+)?\s*$ + ^%(_apache_error_client)s (AH01775: )?(Digest: )?invalid nonce .* received - length is not \S+(, referer: \S+)?\s*$ + ^%(_apache_error_client)s (AH01788: )?(Digest: )?realm mismatch - got `.*?' but expected `.+'(, referer: \S+)?\s*$ + ^%(_apache_error_client)s (AH01789: )?(Digest: )?unknown algorithm `.*?' received: \S*(, referer: \S+)?\s*$ + ^%(_apache_error_client)s (AH01793: )?invalid qop `.*?' received: \S*(, referer: \S+)?\s*$ + ^%(_apache_error_client)s (AH01777: )?(Digest: )?invalid nonce .*? received - user attempted time travel(, referer: \S+)?\s*$ ignoreregex = @@ -50,5 +50,7 @@ ignoreregex = # ^%(_apache_error_client)s (AH01779: )?user .*: one-time-nonce mismatch - sending new nonce\s*$ # ^%(_apache_error_client)s (AH02486: )?realm mismatch - got `.*' but no realm specified\s*$ # +# referer is always in error log messages if it exists added as per the log_error_core function in server/log.c +# # Author: Cyril Jaquier # Major edits by Daniel Black diff --git a/config/filter.d/apache-noscript.conf b/config/filter.d/apache-noscript.conf index f3c6246a..7ea257b2 100644 --- a/config/filter.d/apache-noscript.conf +++ b/config/filter.d/apache-noscript.conf @@ -9,8 +9,8 @@ before = apache-common.conf [Definition] -failregex = ^%(_apache_error_client)s ((AH001(28|30): )?File does not exist|(AH01264: )?script not found or unable to stat): /\S*(\.php|\.asp|\.exe|\.pl)\s*$ - ^%(_apache_error_client)s script '/\S*(\.php|\.asp|\.exe|\.pl)\S*' not found or unable to stat\s*$ +failregex = ^%(_apache_error_client)s ((AH001(28|30): )?File does not exist|(AH01264: )?script not found or unable to stat): /\S*(\.php|\.asp|\.exe|\.pl)(, referer: \S+)?\s*$ + ^%(_apache_error_client)s script '/\S*(\.php|\.asp|\.exe|\.pl)\S*' not found or unable to stat(, referer: \S+)?\s*$ ignoreregex = diff --git a/config/filter.d/apache-overflows.conf b/config/filter.d/apache-overflows.conf index 92551525..74e44b8e 100644 --- a/config/filter.d/apache-overflows.conf +++ b/config/filter.d/apache-overflows.conf @@ -8,7 +8,7 @@ before = apache-common.conf [Definition] -failregex = ^%(_apache_error_client)s ((AH0013[456]: )?Invalid (method|URI) in request .*( - possible attempt to establish SSL connection on non-SSL port)?|(AH00565: )?request failed: URI too long \(longer than \d+\)|request failed: erroneous characters after protocol string: .*|AH00566: request failed: invalid characters in URI)$ +failregex = ^%(_apache_error_client)s ((AH0013[456]: )?Invalid (method|URI) in request .*( - possible attempt to establish SSL connection on non-SSL port)?|(AH00565: )?request failed: URI too long \(longer than \d+\)|request failed: erroneous characters after protocol string: .*|AH00566: request failed: invalid characters in URI)(, referer: \S+)?$ ignoreregex = diff --git a/testcases/files/logs/apache-auth b/testcases/files/logs/apache-auth index d6c40ac5..787d160a 100644 --- a/testcases/files/logs/apache-auth +++ b/testcases/files/logs/apache-auth @@ -115,3 +115,6 @@ # failJSON: { "time": "2013-06-01T02:17:42", "match": true , "host": "192.168.0.2" } [Sat Jun 01 02:17:42 2013] [error] [client 192.168.0.2] user root not found + +# failJSON: { "time": "2013-11-18T22:39:33", "match": true , "host": "91.49.82.139" } +[Mon Nov 18 22:39:33 2013] [error] [client 91.49.82.139] user gg not found: /, referer: http://sj.hopto.org/management.html From 015b403df07b4bcafa367e1b8b04611aa988a9a0 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 20 Nov 2013 10:01:06 +1100 Subject: [PATCH 079/165] TST: more test cases for suhosin --- testcases/files/logs/suhosin | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/testcases/files/logs/suhosin b/testcases/files/logs/suhosin index 90ed7bf1..a9b0002a 100644 --- a/testcases/files/logs/suhosin +++ b/testcases/files/logs/suhosin @@ -2,3 +2,9 @@ Mar 11 22:52:12 lighttpd[53690]: (mod_fastcgi.c.2676) FastCGI-stderr: ALERT - configured request variable name length limit exceeded - dropped variable 'upqchi07vFfAFuBjnIKGIwiLrHo3Vt68T3yqvhQu2TqetQ78roy7Q6bpTfDUtYFR593/MA' (attacker '198.51.100.167', file '/usr/local/captiveportal/index.php') # failJSON: { "time": "2005-02-26T22:52:29", "match": true , "host": "198.51.100.77" } Feb 26 22:52:29 host suhosin[9636]: ALERT - script tried to increase memory_limit to 268435456 bytes which is above the allowed value (attacker '198.51.100.77', file '/var/www/wordpress/wp-admin/includes/image.php', line 161) + +# failJSON: { "time": "2004-11-18T20:18:31", "match": true , "host": "188.132.244.3" } +Nov 18 20:18:31 platypus suhosin[28433]: ALERT - ASCII-NUL chars not allowed within request variables - dropped variable 'templatefile' (attacker '188.132.244.3', file '/home/ace-hosting/public_html/cart.php') + +# failJSON: { "time": "2004-10-25T10:59:49", "match": true , "host": "38.111.147.83" } +Oct 25 10:59:49 platypus suhosin[13953]: ALERT - configured GET variable value length limit exceeded - dropped variable '_route_' (attacker '38.111.147.83', file '/home/thegoblin/public_html/index.php') From 28d8aec511a96470db3816aa0ba9d35b3c5f6239 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 21 Nov 2013 07:05:21 +1100 Subject: [PATCH 080/165] DOC: Arch Linux link --- DEVELOP | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DEVELOP b/DEVELOP index 3766d192..40182ff9 100644 --- a/DEVELOP +++ b/DEVELOP @@ -805,6 +805,8 @@ Which indicates that testcases/files/logs/mysqld.log has been moved or is a dire # Provide a release sample to distributors + * Arch Linux: + https://www.archlinux.org/packages/community/any/fail2ban/ * Debian: Yaroslav Halchenko http://packages.qa.debian.org/f/fail2ban.html * FreeBSD: Christoph Theis theis@gmx.at>, Nick Hilliard From d34d8db3d2bf361853cf7f9fa8b2cd3ca0edc707 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Fri, 22 Nov 2013 15:57:03 -0500 Subject: [PATCH 081/165] BF/ENH: include [PID] into logging msgs, remove indentation from syslog messages Otherwise leads to incorrect parsing of the log messages by syslog(-ng). See http://bugs.debian.org/730202 I also removed %(levelname)-6s from syslog messages completely since they are passed to the syslog and it is up to the configuration/admin to decide include levels into the messages or not (I have checked that at least debug level indeed goes to /var/log/debug) --- server/server.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server/server.py b/server/server.py index 773fdf0b..44d8ae68 100644 --- a/server/server.py +++ b/server/server.py @@ -347,13 +347,12 @@ class Server: try: self.__loggingLock.acquire() # set a format which is simpler for console use - formatter = logging.Formatter("%(asctime)s %(name)-16s: %(levelname)-6s %(message)s") + formatter = logging.Formatter("%(name)s[%(process)d]: %(levelname)-7s %(message)s") if target == "SYSLOG": # Syslog daemons already add date to the message. - formatter = logging.Formatter("%(name)-16s: %(levelname)-6s %(message)s") + formatter = logging.Formatter("%(name)s[%(process)d]: %(message)s") facility = logging.handlers.SysLogHandler.LOG_DAEMON - hdlr = logging.handlers.SysLogHandler("/dev/log", - facility = facility) + hdlr = logging.handlers.SysLogHandler("/dev/log", facility=facility) elif target == "STDOUT": hdlr = logging.StreamHandler(sys.stdout) elif target == "STDERR": From f2c529ca7ba558e44f3f0177cea96c70c0e70d4f Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 23 Nov 2013 11:33:41 +1100 Subject: [PATCH 082/165] ENH: move signal.signal(signal.SIGHUP, signal.SIG_IGN) before fork in server. closes #446 --- server/server.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/server/server.py b/server/server.py index 773fdf0b..f5dbc3c8 100644 --- a/server/server.py +++ b/server/server.py @@ -409,6 +409,14 @@ class Server: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/278731 """ + # When the first child terminates, all processes in the second child + # are sent a SIGHUP, so it's ignored. + + # We need to set this in the parent process, so it gets inherited by the + # child process, and this makes sure that it is effect even if the parent + # terminates quickly. + signal.signal(signal.SIGHUP, signal.SIG_IGN) + try: # Fork a child process so the parent can exit. This will return control # to the command line or shell. This is required so that the new process @@ -431,10 +439,6 @@ class Server: # leader. os.setsid() - # When the first child terminates, all processes in the second child - # are sent a SIGHUP, so it's ignored. - signal.signal(signal.SIGHUP, signal.SIG_IGN) - try: # Fork a second child to prevent zombies. Since the first child is # a session leader without a controlling terminal, it's possible for From 9a82bc3c617c488dd376571370d08b05bf1954af Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sun, 24 Nov 2013 18:21:02 +1100 Subject: [PATCH 083/165] BF: kernel messages can have space. Thanks ag4ve(shawn). Closes #448 --- ChangeLog | 1 + THANKS | 1 + config/filter.d/common.conf | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 24f01e9a..6636ef76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - Fixes: - allow for ",milliseconds" in the custom date format of proftpd.log - allow for ", referer ..." in apache-* filter for apache error logs. + - allow for spaces at the beginning of kernel messages. Closes gh-448 - New Features: diff --git a/THANKS b/THANKS index 46c7bc5e..e71eefea 100644 --- a/THANKS +++ b/THANKS @@ -8,6 +8,7 @@ be added Adrien Clerc ache +ag4ve (Shawn) Amir Caspi Andrey G. Grozin Andy Fragen diff --git a/config/filter.d/common.conf b/config/filter.d/common.conf index b992e4b8..ae8e8b7b 100644 --- a/config/filter.d/common.conf +++ b/config/filter.d/common.conf @@ -34,7 +34,7 @@ __daemon_combs_re = (?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_r # Some messages have a kernel prefix with a timestamp # EXAMPLES: kernel: [769570.846956] -__kernel_prefix = kernel: \[\d+\.\d+\] +__kernel_prefix = kernel: \[ *\d+\.\d+\] __hostname = \S+ From a989787e0dace5b609028b95526c1eb212e1ebef Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sun, 24 Nov 2013 18:43:23 +1100 Subject: [PATCH 084/165] DOC: more distro bug tracker urls --- DEVELOP | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/DEVELOP b/DEVELOP index 40182ff9..3939fe47 100644 --- a/DEVELOP +++ b/DEVELOP @@ -743,10 +743,14 @@ Releasing * https://github.com/fail2ban/fail2ban/issues?sort=updated&state=open * http://bugs.debian.org/cgi-bin/pkgreport.cgi?dist=unstable;package=fail2ban + * https://bugs.launchpad.net/ubuntu/+source/fail2ban * http://bugs.sabayon.org/buglist.cgi?quicksearch=net-analyzer%2Ffail2ban + * https://bugs.archlinux.org/?project=5&cat%5B%5D=33&string=fail2ban * https://bugs.gentoo.org/buglist.cgi?query_format=advanced&short_desc=fail2ban&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=IN_PROGRESS&short_desc_type=allwords * https://bugzilla.redhat.com/buglist.cgi?query_format=advanced&bug_status=NEW&bug_status=ASSIGNED&component=fail2ban&classification=Red%20Hat&classification=Fedora * http://www.freebsd.org/cgi/query-pr-summary.cgi?text=fail2ban + * https://bugs.mageia.org/buglist.cgi?quicksearch=fail2ban + * https://build.opensuse.org/package/requests/openSUSE:Factory/fail2ban # Make sure the tests pass From a6f085786ca46485557c0adbe6b6510f1a06253b Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Sun, 24 Nov 2013 09:50:39 -0500 Subject: [PATCH 085/165] ENH: reintroducing levelnameinto syslog msgs, time stamp and indentation in non-syslog msgs any indentation from syslog msgs wsa removed -- no need --- server/server.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/server.py b/server/server.py index 44d8ae68..6ac93a54 100644 --- a/server/server.py +++ b/server/server.py @@ -347,10 +347,10 @@ class Server: try: self.__loggingLock.acquire() # set a format which is simpler for console use - formatter = logging.Formatter("%(name)s[%(process)d]: %(levelname)-7s %(message)s") + formatter = logging.Formatter("%(asctime)s %(name)-16s[%(process)d]: %(levelname)-7s %(message)s") if target == "SYSLOG": # Syslog daemons already add date to the message. - formatter = logging.Formatter("%(name)s[%(process)d]: %(message)s") + formatter = logging.Formatter("%(name)s[%(process)d]: %(levelname)s %(message)s") facility = logging.handlers.SysLogHandler.LOG_DAEMON hdlr = logging.handlers.SysLogHandler("/dev/log", facility=facility) elif target == "STDOUT": From a26d4f42b7b4b3a7359e64eba4d5997eef25db46 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Sun, 24 Nov 2013 09:59:45 -0500 Subject: [PATCH 086/165] ENH: added optional [PID] matching in recidive.conf --- config/filter.d/recidive.conf | 2 +- testcases/files/logs/recidive | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/filter.d/recidive.conf b/config/filter.d/recidive.conf index b29acaf3..13d2f53a 100644 --- a/config/filter.d/recidive.conf +++ b/config/filter.d/recidive.conf @@ -27,6 +27,6 @@ _daemon = fail2ban\.actions # jail using this filter 'recidive', or change this line! _jailname = recidive -failregex = ^(%(__prefix_line)s|,\d{3} fail2ban.actions:\s+)WARNING\s+\[(?!%(_jailname)s\])(?:.*)\]\s+Ban\s+\s*$ +failregex = ^(%(__prefix_line)s|,\d{3} fail2ban.actions%(__pid_re)s?:\s+)WARNING\s+\[(?!%(_jailname)s\])(?:.*)\]\s+Ban\s+\s*$ # Author: Tom Hendrikx, modifications by Amir Caspi diff --git a/testcases/files/logs/recidive b/testcases/files/logs/recidive index 6af85137..83acc3e1 100644 --- a/testcases/files/logs/recidive +++ b/testcases/files/logs/recidive @@ -1,5 +1,7 @@ # failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4" } 2006-02-13 15:52:30,388 fail2ban.actions: WARNING [sendmail] Ban 1.2.3.4 +# failJSON: { "time": "2006-02-13T15:52:30", "match": true , "host": "1.2.3.4", "desc": "Extended with [PID]" } +2006-02-13 15:52:30,388 fail2ban.actions[123]: WARNING [sendmail] Ban 1.2.3.4 # failJSON: { "match": false } 2006-02-13 16:07:31,183 fail2ban.actions: WARNING [sendmail] Unban 1.2.3.4 # failJSON: { "match": false } From 085ebbe1de7477733b28e06204ccbb19ea2c3d09 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Sun, 24 Nov 2013 11:55:58 -0500 Subject: [PATCH 087/165] Changelog entries for the last changes --- ChangeLog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index 24f01e9a..a26257f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,8 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - Fixes: - allow for ",milliseconds" in the custom date format of proftpd.log - allow for ", referer ..." in apache-* filter for apache error logs. + - remove indentation of name and loglevel while logging to SYSLOG to + resolve syslog(-ng) parsing problems. Closes Debian bug #730202. - New Features: @@ -22,6 +24,7 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better * filter.d/solid-pop3d -- added thanks to Jacques Lav!gnotte on mailinglist. - Enhancements: + - loglines now also report "[PID]" after the name portion ver. 0.8.11 (2013/11/13) - loves-unittests-and-tight-DoS-free-filter-regexes From 093aee967622216c5d2d4023fb9842388f87c3b1 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 25 Nov 2013 07:54:49 +1100 Subject: [PATCH 088/165] TST: no python-2.5 any more - https://github.com/travis-ci/travis-ci/issues/1668 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2d091754..d693f975 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ # travis-ci.org definition for Fail2Ban build language: python python: - - "2.5" - "2.6" - "2.7" before_install: From dc154c792e6d09abe3592e1321581f9103dd47fe Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 25 Nov 2013 08:08:20 +1100 Subject: [PATCH 089/165] BF: add init section with name for action.d/apf. Closes #398 --- config/action.d/apf.conf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/action.d/apf.conf b/config/action.d/apf.conf index 9af3066d..f1d54dd2 100644 --- a/config/action.d/apf.conf +++ b/config/action.d/apf.conf @@ -41,3 +41,10 @@ actionban = apf --deny "banned by Fail2Ban " # Values: CMD # actionunban = apf --remove + +[Init] + +# Name used in APF configuration +# +name = default + From 99838440c8a7cb8c55d2479f6bf5fa32c8fc3640 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 28 Nov 2013 23:18:34 +1100 Subject: [PATCH 090/165] DOC: document rational behind 20 character jail name limit --- ChangeLog | 2 ++ server/jail.py | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 58f8f84a..e94a1338 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,8 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - allow for ", referer ..." in apache-* filter for apache error logs. - allow for spaces at the beginning of kernel messages. Closes gh-448 - recidive jail to block all protocols. Closes gh-440. Thanks Ioan Indreias + - long names on jails documented based on iptables limit of 30 less + len("fail2ban-"). - New Features: diff --git a/server/jail.py b/server/jail.py index 5e60ec7f..7ce12e46 100644 --- a/server/jail.py +++ b/server/jail.py @@ -102,9 +102,11 @@ class Jail: self.__filter = FilterPyinotify(self) def setName(self, name): + # 20 based on iptable chain name limit of 30 less len('fail2ban-') if len(name) >= 20: - logSys.warning("Jail name %r might be too long and some commands " - "might not function correctly. Please shorten" + logSys.warning("Jail name %r might be too long and some commands" + " (e.g. iptables) might not function correctly." + " Please shorten" % name) self.__name = name From fb666b69ffff45d8cbd6e381e5ffccfc6419d939 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 28 Nov 2013 23:35:05 +1100 Subject: [PATCH 091/165] BF: firewall-cmd-direct-new was too long. Thanks Joel. --- ChangeLog | 2 + config/action.d/firewall-cmd-direct-new.conf | 52 -------------------- 2 files changed, 2 insertions(+), 52 deletions(-) delete mode 100644 config/action.d/firewall-cmd-direct-new.conf diff --git a/ChangeLog b/ChangeLog index 58f8f84a..7a210b2c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,8 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - IMPORTANT incompatible changes: - Fixes: + - Rename firewall-cmd-direct-new to firewall-cmd-new to fit within jail name + name length. As per gh-395 - allow for ",milliseconds" in the custom date format of proftpd.log - allow for ", referer ..." in apache-* filter for apache error logs. - allow for spaces at the beginning of kernel messages. Closes gh-448 diff --git a/config/action.d/firewall-cmd-direct-new.conf b/config/action.d/firewall-cmd-direct-new.conf deleted file mode 100644 index 55b6762d..00000000 --- a/config/action.d/firewall-cmd-direct-new.conf +++ /dev/null @@ -1,52 +0,0 @@ -# Fail2Ban configuration file -# -# Author: Edgar Hoch -# Copied from iptables-new.conf and modified for use with firewalld by Edgar Hoch. -# It uses "firewall-cmd" instead of "iptables". -# -# Because of the --remove-rules in stop this action requires firewalld-0.3.8+ - -[INCLUDES] - -before = iptables-blocktype.conf - -[Definition] - -actionstart = firewall-cmd --direct --add-chain ipv4 filter fail2ban- - firewall-cmd --direct --add-rule ipv4 filter fail2ban- 1000 -j RETURN - firewall-cmd --direct --add-rule ipv4 filter 0 -m state --state NEW -p --dport -j fail2ban- - -actionstop = firewall-cmd --direct --remove-rule ipv4 filter 0 -m state --state NEW -p --dport -j fail2ban- - firewall-cmd --direct --remove-rules ipv4 filter fail2ban- - firewall-cmd --direct --remove-chain ipv4 filter fail2ban- - -actioncheck = firewall-cmd --direct --get-chains ipv4 filter | grep -q 'fail2ban-[ \t]' - -actionban = firewall-cmd --direct --add-rule ipv4 filter fail2ban- 0 -s -j - -actionunban = firewall-cmd --direct --remove-rule ipv4 filter fail2ban- 0 -s -j - -[Init] - -# Default name of the chain -# -name = default - -# Option: port -# Notes.: specifies port to monitor -# Values: [ NUM | STRING ] -# -port = ssh - -# Option: protocol -# Notes.: internally used by config reader for interpolations. -# Values: [ tcp | udp | icmp | all ] -# -protocol = tcp - -# Option: chain -# Notes specifies the iptables chain to which the fail2ban rules should be -# added -# Values: [ STRING ] -# -chain = INPUT_direct From 9e538927087d2d7382631063c6423af8a4a6b95e Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 29 Nov 2013 19:26:24 +1100 Subject: [PATCH 092/165] BF: did remove instead of move --- config/action.d/firewalld-cmd-new.conf | 52 ++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 config/action.d/firewalld-cmd-new.conf diff --git a/config/action.d/firewalld-cmd-new.conf b/config/action.d/firewalld-cmd-new.conf new file mode 100644 index 00000000..837352e9 --- /dev/null +++ b/config/action.d/firewalld-cmd-new.conf @@ -0,0 +1,52 @@ +# Fail2Ban configuration file +# +# Author: Edgar Hoch +# Copied from iptables-new.conf and modified for use with firewalld by Edgar Hoch. +# It uses "firewall-cmd" instead of "iptables". +# +# Because of the --remove-rules in stop this action requires firewalld-0.3.8+ + +[INCLUDES] + +before = iptables-blocktype.conf + +[Definition] + +actionstart = firewall-cmd --direct --add-chain ipv4 filter f2b- + firewall-cmd --direct --add-rule ipv4 filter f2b- 1000 -j RETURN + firewall-cmd --direct --add-rule ipv4 filter 0 -m state --state NEW -p --dport -j f2b- + +actionstop = firewall-cmd --direct --remove-rule ipv4 filter 0 -m state --state NEW -p --dport -j f2b- + firewall-cmd --direct --remove-rules ipv4 filter f2b- + firewall-cmd --direct --remove-chain ipv4 filter f2b- + +actioncheck = firewall-cmd --direct --get-chains ipv4 filter | grep -q 'f2b-[ \t]' + +actionban = firewall-cmd --direct --add-rule ipv4 filter f2b- 0 -s -j + +actionunban = firewall-cmd --direct --remove-rule ipv4 filter f2b- 0 -s -j + +[Init] + +# Default name of the chain +# +name = default + +# Option: port +# Notes.: specifies port to monitor +# Values: [ NUM | STRING ] +# +port = ssh + +# Option: protocol +# Notes.: internally used by config reader for interpolations. +# Values: [ tcp | udp | icmp | all ] +# +protocol = tcp + +# Option: chain +# Notes specifies the iptables chain to which the fail2ban rules should be +# added +# Values: [ STRING ] +# +chain = INPUT_direct From cade7463079a9601ffe50036ecd7a6077b2e8c39 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 29 Nov 2013 21:45:11 +1100 Subject: [PATCH 093/165] BF: jail name mysqld-syslog-iptables too long. removed -iptables. Thanks Stefan (#447) --- ChangeLog | 1 + THANKS | 1 + config/jail.conf | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 58f8f84a..02c55bb7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,7 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - allow for ", referer ..." in apache-* filter for apache error logs. - allow for spaces at the beginning of kernel messages. Closes gh-448 - recidive jail to block all protocols. Closes gh-440. Thanks Ioan Indreias + - mysqld-syslog-iptables rule was too long. Part of gh-447. - New Features: diff --git a/THANKS b/THANKS index afc72aa3..04c8728d 100644 --- a/THANKS +++ b/THANKS @@ -66,6 +66,7 @@ Russell Odom Sebastian Arcus Sireyessire silviogarbes +Stefan Tatschner Stephen Gildea Steven Hiscocks Tom Pike diff --git a/config/jail.conf b/config/jail.conf index 433170a5..05f4b768 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -389,7 +389,7 @@ logpath = /var/log/mysqld.log maxretry = 5 -[mysqld-syslog-iptables] +[mysqld-syslog] enabled = false filter = mysqld-auth From b9b2ddf99625837ce8b76ab54ae9e2943b3159b2 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 29 Nov 2013 21:47:53 +1100 Subject: [PATCH 094/165] BF: smtps not IANA standard. Closes #447 --- ChangeLog | 2 ++ config/jail.conf | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 58f8f84a..299a89c8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,6 +17,8 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - allow for ", referer ..." in apache-* filter for apache error logs. - allow for spaces at the beginning of kernel messages. Closes gh-448 - recidive jail to block all protocols. Closes gh-440. Thanks Ioan Indreias + - smtps not a IANA standard and has been removed from Arch. Replaced with + 465. Thanks Stefan. Closes gh-447 - New Features: diff --git a/config/jail.conf b/config/jail.conf index 433170a5..481f0880 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -506,7 +506,7 @@ logpath = /var/log/auth.log enabled = false filter = dovecot -action = iptables-multiport[name=dovecot, port="pop3,pop3s,imap,imaps,submission,smtps,sieve", protocol=tcp] +action = iptables-multiport[name=dovecot, port="pop3,pop3s,imap,imaps,submission,465,sieve", protocol=tcp] logpath = /var/log/mail.log @@ -514,7 +514,7 @@ logpath = /var/log/mail.log enabled = false filter = dovecot -action = iptables-multiport[name=dovecot-auth, port="pop3,pop3s,imap,imaps,submission,smtps,sieve", protocol=tcp] +action = iptables-multiport[name=dovecot-auth, port="pop3,pop3s,imap,imaps,submission,465,sieve", protocol=tcp] logpath = /var/log/secure From 86a0a5962a9ed2c8c3c5b4fd7b75adb2c740b803 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 30 Nov 2013 08:05:20 +1100 Subject: [PATCH 095/165] BF: revert to fail2ban- prefix as f2b- was intended for 0.9 --- config/action.d/firewalld-cmd-new.conf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/config/action.d/firewalld-cmd-new.conf b/config/action.d/firewalld-cmd-new.conf index 837352e9..55b6762d 100644 --- a/config/action.d/firewalld-cmd-new.conf +++ b/config/action.d/firewalld-cmd-new.conf @@ -12,19 +12,19 @@ before = iptables-blocktype.conf [Definition] -actionstart = firewall-cmd --direct --add-chain ipv4 filter f2b- - firewall-cmd --direct --add-rule ipv4 filter f2b- 1000 -j RETURN - firewall-cmd --direct --add-rule ipv4 filter 0 -m state --state NEW -p --dport -j f2b- +actionstart = firewall-cmd --direct --add-chain ipv4 filter fail2ban- + firewall-cmd --direct --add-rule ipv4 filter fail2ban- 1000 -j RETURN + firewall-cmd --direct --add-rule ipv4 filter 0 -m state --state NEW -p --dport -j fail2ban- -actionstop = firewall-cmd --direct --remove-rule ipv4 filter 0 -m state --state NEW -p --dport -j f2b- - firewall-cmd --direct --remove-rules ipv4 filter f2b- - firewall-cmd --direct --remove-chain ipv4 filter f2b- +actionstop = firewall-cmd --direct --remove-rule ipv4 filter 0 -m state --state NEW -p --dport -j fail2ban- + firewall-cmd --direct --remove-rules ipv4 filter fail2ban- + firewall-cmd --direct --remove-chain ipv4 filter fail2ban- -actioncheck = firewall-cmd --direct --get-chains ipv4 filter | grep -q 'f2b-[ \t]' +actioncheck = firewall-cmd --direct --get-chains ipv4 filter | grep -q 'fail2ban-[ \t]' -actionban = firewall-cmd --direct --add-rule ipv4 filter f2b- 0 -s -j +actionban = firewall-cmd --direct --add-rule ipv4 filter fail2ban- 0 -s -j -actionunban = firewall-cmd --direct --remove-rule ipv4 filter f2b- 0 -s -j +actionunban = firewall-cmd --direct --remove-rule ipv4 filter fail2ban- 0 -s -j [Init] From 56b6bf7d25766a47febba1a079629567a63892c7 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 30 Nov 2013 10:30:29 +1100 Subject: [PATCH 096/165] ENH: reduce firewalld-cmd-new -> firewallcmd-new --- config/action.d/{firewalld-cmd-new.conf => firewallcmd-new.conf} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename config/action.d/{firewalld-cmd-new.conf => firewallcmd-new.conf} (100%) diff --git a/config/action.d/firewalld-cmd-new.conf b/config/action.d/firewallcmd-new.conf similarity index 100% rename from config/action.d/firewalld-cmd-new.conf rename to config/action.d/firewallcmd-new.conf From 95845b7b6571cd80385777de6fdd932612165831 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 30 Nov 2013 17:47:10 +1100 Subject: [PATCH 097/165] BF: complain action could match too many IP addresses --- ChangeLog | 1 + config/action.d/complain.conf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3cc0f453..12fc70f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,7 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - smtps not a IANA standard and has been removed from Arch. Replaced with 465. Thanks Stefan. Closes gh-447 - mysqld-syslog-iptables rule was too long. Part of gh-447. + - complain action - ensure where not matching other IPs in log sample. - Enhancements: - long names on jails documented based on iptables limit of 30 less diff --git a/config/action.d/complain.conf b/config/action.d/complain.conf index ad14a87e..d1ca25c7 100644 --- a/config/action.d/complain.conf +++ b/config/action.d/complain.conf @@ -58,7 +58,7 @@ actioncheck = actionban = ADDRESSES=`whois | perl -e 'while () { next if /^changed|@(ripe|apnic)\.net/io; $m += (/abuse|trouble:|report|spam|security/io?3:0); if (/([a-z0-9_\-\.+]+@[a-z0-9\-]+(\.[[a-z0-9\-]+)+)/io) { while (s/([a-z0-9_\-\.+]+@[a-z0-9\-]+(\.[[a-z0-9\-]+)+)//io) { if ($m) { $a{lc($1)}=$m } else { $b{lc($1)}=$m } } $m=0 } else { $m && --$m } } if (%%a) {print join(",",keys(%%a))} else {print join(",",keys(%%b))}'` IP= if [ ! -z "$ADDRESSES" ]; then - (printf %%b "\n"; date '+Note: Local timezone is %%z (%%Z)'; grep '' ) | "Abuse from " $ADDRESSES + (printf %%b "\n"; date '+Note: Local timezone is %%z (%%Z)'; grep '[^0-9][^0-9]' ) | "Abuse from " $ADDRESSES fi # Option: actionunban From 0495aa098eefb1ad7111c7f98ee761e8e642c65e Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 30 Nov 2013 18:01:45 +1100 Subject: [PATCH 098/165] BF: grep matches on shouldn't include other IPs --- config/action.d/ipfw.conf | 2 +- config/action.d/mail-whois-lines.conf | 2 +- config/action.d/sendmail-whois-lines.conf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/action.d/ipfw.conf b/config/action.d/ipfw.conf index 09045815..37625209 100644 --- a/config/action.d/ipfw.conf +++ b/config/action.d/ipfw.conf @@ -43,7 +43,7 @@ actionban = ipfw add tcp from to # Tags: See jail.conf(5) man page # Values: CMD # -actionunban = ipfw delete `ipfw list | grep -i | awk '{print $1;}'` +actionunban = ipfw delete `ipfw list | grep -i "[^0-9][^0-9]" | awk '{print $1;}'` [Init] diff --git a/config/action.d/mail-whois-lines.conf b/config/action.d/mail-whois-lines.conf index 758c4eff..6b7b3841 100644 --- a/config/action.d/mail-whois-lines.conf +++ b/config/action.d/mail-whois-lines.conf @@ -42,7 +42,7 @@ actionban = printf %%b "Hi,\n Here are more information about :\n `whois `\n\n Lines containing IP: in \n - `grep '\<\>' `\n\n + `grep '[^0-9][^0-9]' `\n\n Regards,\n Fail2Ban"|mail -s "[Fail2Ban] : banned from `uname -n`" diff --git a/config/action.d/sendmail-whois-lines.conf b/config/action.d/sendmail-whois-lines.conf index 5a331e24..a0f0a9c3 100644 --- a/config/action.d/sendmail-whois-lines.conf +++ b/config/action.d/sendmail-whois-lines.conf @@ -58,7 +58,7 @@ actionban = printf %%b "Subject: [Fail2Ban] : banned from `uname -n` Here are more information about :\n `/usr/bin/whois `\n\n Lines containing IP: in \n - `grep '\<\>' `\n\n + `grep '[^0-9][^0-9]' `\n\n Regards,\n Fail2Ban" | /usr/sbin/sendmail -f From b5d6310d281c1c45112ffb285c77a858da99d6f6 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 4 Dec 2013 20:51:30 +1100 Subject: [PATCH 099/165] BF: create flushlogs command to prevent logrotation clobbering logtarget. Closes gh-458 --- ChangeLog | 2 ++ client/beautifier.py | 2 ++ common/protocol.py | 1 + files/fail2ban-logrotate | 2 +- server/server.py | 13 ++++++++++++- server/transmitter.py | 2 ++ 6 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3cc0f453..fcfe82cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,8 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - smtps not a IANA standard and has been removed from Arch. Replaced with 465. Thanks Stefan. Closes gh-447 - mysqld-syslog-iptables rule was too long. Part of gh-447. + - add 'flushlogs' command to allow logrotation without clobbering logtarget + settings. Closes gh-458, Debian bug #697333, Redhat bug #891798. - Enhancements: - long names on jails documented based on iptables limit of 30 less diff --git a/client/beautifier.py b/client/beautifier.py index 8e690656..bc9e89b1 100644 --- a/client/beautifier.py +++ b/client/beautifier.py @@ -63,6 +63,8 @@ class Beautifier: msg = "Jail stopped" elif inC[0] == "add": msg = "Added jail " + response + elif inC[0] == "flushlogs": + msg = "logs: " + response elif inC[0:1] == ['status']: if len(inC) > 1: # Create IP list diff --git a/common/protocol.py b/common/protocol.py index 9309ce7f..278ccd53 100644 --- a/common/protocol.py +++ b/common/protocol.py @@ -43,6 +43,7 @@ protocol = [ ["get loglevel", "gets the logging level"], ["set logtarget ", "sets logging target to . Can be STDOUT, STDERR, SYSLOG or a file"], ["get logtarget", "gets logging target"], +["flushlogs", "flushes the logtarget if a file and reopens it. For log rotation."], ['', "JAIL CONTROL", ""], ["add ", "creates using "], ["start ", "starts the jail "], diff --git a/files/fail2ban-logrotate b/files/fail2ban-logrotate index 67c6364a..a09870af 100644 --- a/files/fail2ban-logrotate +++ b/files/fail2ban-logrotate @@ -13,6 +13,6 @@ missingok compress postrotate - /usr/bin/fail2ban-client set logtarget /var/log/fail2ban.log 1>/dev/null || true + /usr/bin/fail2ban-client flushlogs 1>/dev/null || true endscript } diff --git a/server/server.py b/server/server.py index 6ac93a54..1358391b 100644 --- a/server/server.py +++ b/server/server.py @@ -361,7 +361,7 @@ class Server: # Target should be a file try: open(target, "a").close() - hdlr = logging.FileHandler(target) + hdlr = logging.handlers.RotatingFileHandler(target) except IOError: logSys.error("Unable to log to " + target) logSys.info("Logging to previous target " + self.__logTarget) @@ -401,6 +401,17 @@ class Server: finally: self.__loggingLock.release() + def flushLogs(self): + if self.__logTarget not in ['STDERR', 'STDOUT', 'SYSLOG']: + for handler in logging.getLogger("fail2ban").handlers: + handler.doRollover() + return "rolled over" + else: + for handler in logging.getLogger("fail2ban").handlers: + handler.flush() + return "flushed" + + def __createDaemon(self): # pragma: no cover """ Detach a process from the controlling terminal and run it in the background as a daemon. diff --git a/server/transmitter.py b/server/transmitter.py index deaf9adf..cf65dada 100644 --- a/server/transmitter.py +++ b/server/transmitter.py @@ -92,6 +92,8 @@ class Transmitter: value = command[1] time.sleep(int(value)) return None + elif command[0] == "flushlogs": + return self.__server.flushLogs() elif command[0] == "set": return self.__commandSet(command[1:]) elif command[0] == "get": From e108de3f6d19eecb0a3860405ceb6bf37c6201ff Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 4 Dec 2013 22:27:23 +1100 Subject: [PATCH 100/165] ENH: banning an IP in the ignoreIPList now issues warning to log, but still continues --- server/filter.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/filter.py b/server/filter.py index 80433c01..66d3fbf0 100644 --- a/server/filter.py +++ b/server/filter.py @@ -219,6 +219,9 @@ class Filter(JailThread): # to enable banip fail2ban-client BAN command def addBannedIP(self, ip): + if self.inIgnoreIPList(ip): + logSys.warning('Requested to manually ban an ignored IP ' + ip + '. User knows best. Proceeding to ban it.') + unixTime = MyTime.time() for i in xrange(self.failManager.getMaxRetry()): self.failManager.addFailure(FailTicket(ip, unixTime)) From 97d7f46bb757514f5ccb9140ffcdbb7fd0f70d59 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 4 Dec 2013 22:40:48 +1100 Subject: [PATCH 101/165] DOC: correct grammar - s/Here are more information/Here is more information/ --- config/action.d/mail-whois-lines.conf | 2 +- config/action.d/mail-whois.conf | 2 +- config/action.d/sendmail-whois-lines.conf | 2 +- config/action.d/sendmail-whois.conf | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/action.d/mail-whois-lines.conf b/config/action.d/mail-whois-lines.conf index 758c4eff..bbf66a59 100644 --- a/config/action.d/mail-whois-lines.conf +++ b/config/action.d/mail-whois-lines.conf @@ -39,7 +39,7 @@ actioncheck = actionban = printf %%b "Hi,\n The IP has just been banned by Fail2Ban after attempts against .\n\n - Here are more information about :\n + Here is more information about :\n `whois `\n\n Lines containing IP: in \n `grep '\<\>' `\n\n diff --git a/config/action.d/mail-whois.conf b/config/action.d/mail-whois.conf index fa133ab3..c132b086 100644 --- a/config/action.d/mail-whois.conf +++ b/config/action.d/mail-whois.conf @@ -39,7 +39,7 @@ actioncheck = actionban = printf %%b "Hi,\n The IP has just been banned by Fail2Ban after attempts against .\n\n - Here are more information about :\n + Here is more information about :\n `whois `\n Regards,\n Fail2Ban"|mail -s "[Fail2Ban] : banned from `uname -n`" diff --git a/config/action.d/sendmail-whois-lines.conf b/config/action.d/sendmail-whois-lines.conf index 5a331e24..b40b1084 100644 --- a/config/action.d/sendmail-whois-lines.conf +++ b/config/action.d/sendmail-whois-lines.conf @@ -55,7 +55,7 @@ actionban = printf %%b "Subject: [Fail2Ban] : banned from `uname -n` Hi,\n The IP has just been banned by Fail2Ban after attempts against .\n\n - Here are more information about :\n + Here is more information about :\n `/usr/bin/whois `\n\n Lines containing IP: in \n `grep '\<\>' `\n\n diff --git a/config/action.d/sendmail-whois.conf b/config/action.d/sendmail-whois.conf index a65f9875..f2b07d9e 100644 --- a/config/action.d/sendmail-whois.conf +++ b/config/action.d/sendmail-whois.conf @@ -55,7 +55,7 @@ actionban = printf %%b "Subject: [Fail2Ban] : banned from `uname -n` Hi,\n The IP has just been banned by Fail2Ban after attempts against .\n\n - Here are more information about :\n + Here is more information about :\n `/usr/bin/whois `\n Regards,\n Fail2Ban" | /usr/sbin/sendmail -f From 4dc51e5defdc8ce56db4b71b9b6b53d654908d56 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 4 Dec 2013 22:43:06 +1100 Subject: [PATCH 102/165] BF: put notice in email if whois program could not provide more information. Closes gh-471 --- config/action.d/mail-whois-lines.conf | 2 +- config/action.d/mail-whois.conf | 2 +- config/action.d/sendmail-whois-lines.conf | 2 +- config/action.d/sendmail-whois.conf | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/action.d/mail-whois-lines.conf b/config/action.d/mail-whois-lines.conf index bbf66a59..067c5819 100644 --- a/config/action.d/mail-whois-lines.conf +++ b/config/action.d/mail-whois-lines.conf @@ -40,7 +40,7 @@ actionban = printf %%b "Hi,\n The IP has just been banned by Fail2Ban after attempts against .\n\n Here is more information about :\n - `whois `\n\n + `whois || echo missing whois program`\n\n Lines containing IP: in \n `grep '\<\>' `\n\n Regards,\n diff --git a/config/action.d/mail-whois.conf b/config/action.d/mail-whois.conf index c132b086..e4c8450e 100644 --- a/config/action.d/mail-whois.conf +++ b/config/action.d/mail-whois.conf @@ -40,7 +40,7 @@ actionban = printf %%b "Hi,\n The IP has just been banned by Fail2Ban after attempts against .\n\n Here is more information about :\n - `whois `\n + `whois || echo missing whois program`\n Regards,\n Fail2Ban"|mail -s "[Fail2Ban] : banned from `uname -n`" diff --git a/config/action.d/sendmail-whois-lines.conf b/config/action.d/sendmail-whois-lines.conf index b40b1084..8cdafc0b 100644 --- a/config/action.d/sendmail-whois-lines.conf +++ b/config/action.d/sendmail-whois-lines.conf @@ -56,7 +56,7 @@ actionban = printf %%b "Subject: [Fail2Ban] : banned from `uname -n` The IP has just been banned by Fail2Ban after attempts against .\n\n Here is more information about :\n - `/usr/bin/whois `\n\n + `/usr/bin/whois || echo missing whois program`\n\n Lines containing IP: in \n `grep '\<\>' `\n\n Regards,\n diff --git a/config/action.d/sendmail-whois.conf b/config/action.d/sendmail-whois.conf index f2b07d9e..e428c44d 100644 --- a/config/action.d/sendmail-whois.conf +++ b/config/action.d/sendmail-whois.conf @@ -56,7 +56,7 @@ actionban = printf %%b "Subject: [Fail2Ban] : banned from `uname -n` The IP has just been banned by Fail2Ban after attempts against .\n\n Here is more information about :\n - `/usr/bin/whois `\n + `/usr/bin/whois || echo missing whois program`\n Regards,\n Fail2Ban" | /usr/sbin/sendmail -f From e810ec009d56a51478fd740c60f2770448a7a752 Mon Sep 17 00:00:00 2001 From: Steven Hiscocks Date: Thu, 5 Dec 2013 08:22:20 +0000 Subject: [PATCH 103/165] ENH: Added blocklist.de reporting API action --- config/action.d/blocklist_de.conf | 55 +++++++++++++++++++++++++++++++ config/jail.conf | 12 +++++++ 2 files changed, 67 insertions(+) create mode 100644 config/action.d/blocklist_de.conf diff --git a/config/action.d/blocklist_de.conf b/config/action.d/blocklist_de.conf new file mode 100644 index 00000000..d11b175b --- /dev/null +++ b/config/action.d/blocklist_de.conf @@ -0,0 +1,55 @@ +# Fail2Ban configuration file +# +# Author: Steven Hiscocks +# +# + +# Action to report IP address to blocklist.de +# Blocklist.de must be signed up to at www.blocklist.de +# Once registered, one or more servers can be added. +# This action requires the server 'email address' and the assoicate apikey. +# +# From blocklist.de: +# www.blocklist.de is a free and voluntary service provided by a +# Fraud/Abuse-specialist, whose servers are often attacked on SSH-, +# Mail-Login-, FTP-, Webserver- and other services. +# The mission is to report all attacks to the abuse deparments of the +# infected PCs/servers to ensure that the responsible provider can inform +# the customer about the infection and disable them +# + +[Definition] + +# Option: actionstart +# Notes.: command executed once at the start of Fail2Ban. +# Values: CMD +# +actionstart = + +# Option: actionstop +# Notes.: command executed once at the end of Fail2Ban +# Values: CMD +# +actionstop = + +# Option: actioncheck +# Notes.: command executed once before each actionban command +# Values: CMD +# +actioncheck = + +# Option: actionban +# Notes.: command executed when banning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionban = ! curl --data-urlencode 'server=' --data 'apikey=' --data 'service=' --data 'ip=' --data-urlencode 'logs=' --data 'format=text' "https://www.blocklist.de/en/httpreports.html" | grep "status: error" + +# Option: actionunban +# Notes.: command executed when unbanning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: See jail.conf(5) man page +# Values: CMD +# +actionunban = diff --git a/config/jail.conf b/config/jail.conf index 33d1d439..cbcfb758 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -532,3 +532,15 @@ filter = selinux-ssh action = iptables[name=SELINUX-SSH, port=ssh, protocol=tcp] logpath = /var/log/audit/audit.log maxretry = 5 + +# Report block via blocklist.de fail2ban reporting service API +# See action.d/blocklist_de.conf for more information +[ssh-blocklist] + +enabled = false +filter = sshd +action = iptables[name=SSH, port=ssh, protocol=tcp] + sendmail-whois[name=SSH, dest=you@example.com, sender=fail2ban@example.com, sendername="Fail2Ban"] + blocklist_de[email="fail2ban@example.com", apikey="xxxxxx", service=%(filter)s] +logpath = /var/log/sshd.log +maxretry = 5 From f742ed0e4bc3182f36f348345bce2858b6db4369 Mon Sep 17 00:00:00 2001 From: Steven Hiscocks Date: Thu, 5 Dec 2013 18:06:53 +0000 Subject: [PATCH 104/165] DOC: when to use blocklist.de reporting Taken from commit 1846056606d24abe4e7d3f2e1cf56407c65b9008 --- config/action.d/blocklist_de.conf | 10 ++++++++++ config/jail.conf | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/config/action.d/blocklist_de.conf b/config/action.d/blocklist_de.conf index d11b175b..468f3fc9 100644 --- a/config/action.d/blocklist_de.conf +++ b/config/action.d/blocklist_de.conf @@ -17,6 +17,16 @@ # infected PCs/servers to ensure that the responsible provider can inform # the customer about the infection and disable them # +# IMPORTANT: +# +# Reporting an IP of abuse is a serious complaint. Make sure that it is +# serious. Fail2ban developers and network owners recommend you only use this +# action for: +# * The recidive where the IP has been banned multiple times +# * Where maxretry has been set quite high, beyond the normal user typing +# password incorrectly. +# * For filters that have a low likelyhood of receiving human errors +# [Definition] diff --git a/config/jail.conf b/config/jail.conf index cbcfb758..3b8220e5 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -533,6 +533,9 @@ action = iptables[name=SELINUX-SSH, port=ssh, protocol=tcp] logpath = /var/log/audit/audit.log maxretry = 5 +# See the IMPORTANT note in action.d/blocklist_de.conf for when to +# use this action +# # Report block via blocklist.de fail2ban reporting service API # See action.d/blocklist_de.conf for more information [ssh-blocklist] @@ -543,4 +546,4 @@ action = iptables[name=SSH, port=ssh, protocol=tcp] sendmail-whois[name=SSH, dest=you@example.com, sender=fail2ban@example.com, sendername="Fail2Ban"] blocklist_de[email="fail2ban@example.com", apikey="xxxxxx", service=%(filter)s] logpath = /var/log/sshd.log -maxretry = 5 +maxretry = 20 From a19b33cc7263c0758d6848ecbaa0e5ad4e24b962 Mon Sep 17 00:00:00 2001 From: Steven Hiscocks Date: Thu, 5 Dec 2013 18:12:15 +0000 Subject: [PATCH 105/165] ENH: blocklist.de action added fail2ban version as user agent --- config/action.d/blocklist_de.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/action.d/blocklist_de.conf b/config/action.d/blocklist_de.conf index 468f3fc9..6f47d87b 100644 --- a/config/action.d/blocklist_de.conf +++ b/config/action.d/blocklist_de.conf @@ -54,7 +54,7 @@ actioncheck = # Tags: See jail.conf(5) man page # Values: CMD # -actionban = ! curl --data-urlencode 'server=' --data 'apikey=' --data 'service=' --data 'ip=' --data-urlencode 'logs=' --data 'format=text' "https://www.blocklist.de/en/httpreports.html" | grep "status: error" +actionban = ! curl --data-urlencode 'server=' --data 'apikey=' --data 'service=' --data 'ip=' --data-urlencode 'logs=' --data 'format=text' --user-agent "`fail2ban-client --version | head -1`" "https://www.blocklist.de/en/httpreports.html" | grep "status: error" # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the From 008952035db55c803b1b33ed78bf93c6eb74cf62 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 6 Dec 2013 08:08:11 +1100 Subject: [PATCH 106/165] BF: files/redhat-initd - as per http://pkgs.fedoraproject.org/cgit/fail2ban.git/tree/fail2ban-init.patch --- files/redhat-initd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/redhat-initd b/files/redhat-initd index 43147c95..08eb0f3c 100755 --- a/files/redhat-initd +++ b/files/redhat-initd @@ -1,6 +1,6 @@ #!/bin/bash # -# chkconfig: 345 92 08 +# chkconfig: - 92 08 # processname: fail2ban-server # config: /etc/fail2ban/fail2ban.conf # pidfile: /var/run/fail2ban/fail2ban.pid From b3c173795e1fe023adcc4a781674075d071bc756 Mon Sep 17 00:00:00 2001 From: Steven Hiscocks Date: Fri, 6 Dec 2013 08:22:21 +0000 Subject: [PATCH 107/165] ENH: blocklist.de action error on HTTP response code 4xx --- config/action.d/blocklist_de.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/action.d/blocklist_de.conf b/config/action.d/blocklist_de.conf index 6f47d87b..f45882d3 100644 --- a/config/action.d/blocklist_de.conf +++ b/config/action.d/blocklist_de.conf @@ -54,7 +54,7 @@ actioncheck = # Tags: See jail.conf(5) man page # Values: CMD # -actionban = ! curl --data-urlencode 'server=' --data 'apikey=' --data 'service=' --data 'ip=' --data-urlencode 'logs=' --data 'format=text' --user-agent "`fail2ban-client --version | head -1`" "https://www.blocklist.de/en/httpreports.html" | grep "status: error" +actionban = curl --fail --data-urlencode 'server=' --data 'apikey=' --data 'service=' --data 'ip=' --data-urlencode 'logs=' --data 'format=text' --user-agent "fail2ban v0.8.12" "https://www.blocklist.de/en/httpreports.html" # Option: actionunban # Notes.: command executed when unbanning an IP. Take care that the From 476bbdd284836b47b77f0ccafbfbb3776a5df807 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 7 Dec 2013 10:57:05 +1100 Subject: [PATCH 108/165] TST: test case for flushlogs --- testcases/servertestcase.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/testcases/servertestcase.py b/testcases/servertestcase.py index c93326a5..af6f538d 100644 --- a/testcases/servertestcase.py +++ b/testcases/servertestcase.py @@ -25,7 +25,7 @@ __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" import unittest, socket, time, tempfile, os, sys -from server.server import Server +from server.server import Server, logSys from server.jail import Jail from common.exceptions import UnknownJailException @@ -521,6 +521,33 @@ class TransmitterLogging(TransmitterBase): self.setGetTest("loglevel", "0", 0) self.setGetTestNOK("loglevel", "Bird") + def testFlushLogs(self): + self.assertEqual(self.transm.proceed(["flushlogs"]), (0, "flushed")) + try: + f, fn = tempfile.mkstemp("fail2ban.log") + os.close(f) + self.server.setLogLevel(2) + self.assertEqual(self.transm.proceed(["set", "logtarget", fn]), (0, fn)) + logSys.warn("Before file moved") + try: + f2, fn2 = tempfile.mkstemp("fail2ban.log") + os.close(f2) + os.rename(fn, fn2) + logSys.warn("After file moved") + self.assertEqual(self.transm.proceed(["flushlogs"]), (0, "flushed")) + logSys.warn("After flushlogs") + with open(fn2,'r') as f: + self.assertTrue(f.next().endswith("Before file moved\n")) + self.assertTrue(f.next().endswith("After file moved\n")) + self.assertRaises(StopIteration, f.next) + with open(fn,'r') as f: + self.assertTrue(f.next().endswith("After flushlogs\n")) + self.assertRaises(StopIteration, f.next) + finally: + os.remove(fn2) + finally: + os.remove(fn) + class JailTests(unittest.TestCase): From 8451f720f03c8b7535deba7b3b3993458edbe720 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 7 Dec 2013 11:04:06 +1100 Subject: [PATCH 109/165] TST: fix flushlogs and include test for STDERR flushing --- testcases/servertestcase.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testcases/servertestcase.py b/testcases/servertestcase.py index af6f538d..e6137d2f 100644 --- a/testcases/servertestcase.py +++ b/testcases/servertestcase.py @@ -522,7 +522,7 @@ class TransmitterLogging(TransmitterBase): self.setGetTestNOK("loglevel", "Bird") def testFlushLogs(self): - self.assertEqual(self.transm.proceed(["flushlogs"]), (0, "flushed")) + self.assertEqual(self.transm.proceed(["flushlogs"]), (0, "rolled over")) try: f, fn = tempfile.mkstemp("fail2ban.log") os.close(f) @@ -534,7 +534,7 @@ class TransmitterLogging(TransmitterBase): os.close(f2) os.rename(fn, fn2) logSys.warn("After file moved") - self.assertEqual(self.transm.proceed(["flushlogs"]), (0, "flushed")) + self.assertEqual(self.transm.proceed(["flushlogs"]), (0, "rolled over")) logSys.warn("After flushlogs") with open(fn2,'r') as f: self.assertTrue(f.next().endswith("Before file moved\n")) @@ -547,6 +547,8 @@ class TransmitterLogging(TransmitterBase): os.remove(fn2) finally: os.remove(fn) + self.assertEqual(self.transm.proceed(["set", "logtarget", "STDERR"]), (0, "STDERR")) + self.assertEqual(self.transm.proceed(["flushlogs"]), (0, "flushed")) class JailTests(unittest.TestCase): From 630dd91dcdd6a3f5501b2e15a06577cee32dab0c Mon Sep 17 00:00:00 2001 From: Steven Hiscocks Date: Fri, 6 Dec 2013 18:01:36 +0000 Subject: [PATCH 110/165] BF: Add [Init] section to blocklist.de action --- config/action.d/blocklist_de.conf | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/config/action.d/blocklist_de.conf b/config/action.d/blocklist_de.conf index f45882d3..d4170cab 100644 --- a/config/action.d/blocklist_de.conf +++ b/config/action.d/blocklist_de.conf @@ -63,3 +63,24 @@ actionban = curl --fail --data-urlencode 'server=' --data 'apikey= Date: Mon, 9 Dec 2013 09:21:55 +1100 Subject: [PATCH 111/165] BF: action.d/complain - match IP at beginning and end of lines --- config/action.d/complain.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/action.d/complain.conf b/config/action.d/complain.conf index d1ca25c7..62331f19 100644 --- a/config/action.d/complain.conf +++ b/config/action.d/complain.conf @@ -58,7 +58,7 @@ actioncheck = actionban = ADDRESSES=`whois | perl -e 'while () { next if /^changed|@(ripe|apnic)\.net/io; $m += (/abuse|trouble:|report|spam|security/io?3:0); if (/([a-z0-9_\-\.+]+@[a-z0-9\-]+(\.[[a-z0-9\-]+)+)/io) { while (s/([a-z0-9_\-\.+]+@[a-z0-9\-]+(\.[[a-z0-9\-]+)+)//io) { if ($m) { $a{lc($1)}=$m } else { $b{lc($1)}=$m } } $m=0 } else { $m && --$m } } if (%%a) {print join(",",keys(%%a))} else {print join(",",keys(%%b))}'` IP= if [ ! -z "$ADDRESSES" ]; then - (printf %%b "\n"; date '+Note: Local timezone is %%z (%%Z)'; grep '[^0-9][^0-9]' ) | "Abuse from " $ADDRESSES + (printf %%b "\n"; date '+Note: Local timezone is %%z (%%Z)'; grep -E '(^|[^0-9])([^0-9]|$)' ) | "Abuse from " $ADDRESSES fi # Option: actionunban From e8eab11615e1d753f20345339e8a7bd0a8a12db6 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 9 Dec 2013 14:45:09 +1100 Subject: [PATCH 112/165] DOC: proftp - turn off ReverseDNS --- config/filter.d/proftpd.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/filter.d/proftpd.conf b/config/filter.d/proftpd.conf index bf8f9b5f..b7e13414 100644 --- a/config/filter.d/proftpd.conf +++ b/config/filter.d/proftpd.conf @@ -1,5 +1,7 @@ # Fail2Ban fitler for the Proftpd FTP daemon # +# Set "UseReverseDNS off" in proftpd to avoid the need for DNS. +# See: http://www.proftpd.org/docs/howto/DNS.html [INCLUDES] From db4c21acde6830eb8fbcdd34d1a5e71a11ed9e34 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 9 Dec 2013 14:46:01 +1100 Subject: [PATCH 113/165] BF/DOC: fix filename in documentation for filter.d/proftpd --- config/filter.d/proftpd.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/filter.d/proftpd.conf b/config/filter.d/proftpd.conf index b7e13414..ac714cc1 100644 --- a/config/filter.d/proftpd.conf +++ b/config/filter.d/proftpd.conf @@ -1,6 +1,6 @@ # Fail2Ban fitler for the Proftpd FTP daemon # -# Set "UseReverseDNS off" in proftpd to avoid the need for DNS. +# Set "UseReverseDNS off" in proftpd.conf to avoid the need for DNS. # See: http://www.proftpd.org/docs/howto/DNS.html [INCLUDES] From 916649119ef124e952f50e6c27cf3003897f15f9 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 9 Dec 2013 23:07:42 +1100 Subject: [PATCH 114/165] ENH: use format string rather than concatination on log message --- server/filter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/filter.py b/server/filter.py index 66d3fbf0..0ef756d2 100644 --- a/server/filter.py +++ b/server/filter.py @@ -220,7 +220,7 @@ class Filter(JailThread): def addBannedIP(self, ip): if self.inIgnoreIPList(ip): - logSys.warning('Requested to manually ban an ignored IP ' + ip + '. User knows best. Proceeding to ban it.') + logSys.warning('Requested to manually ban an ignored IP %s. User knows best. Proceeding to ban it.' % ip) unixTime = MyTime.time() for i in xrange(self.failManager.getMaxRetry()): From 66374913ec773175ef921798d3efdd4c47f27e01 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 10 Dec 2013 21:24:37 +1100 Subject: [PATCH 115/165] ENH: add squid filter --- ChangeLog | 1 + THANKS | 1 + config/filter.d/squid.conf | 13 +++++++++++++ testcases/files/logs/squid | 13 +++++++++++++ 4 files changed, 28 insertions(+) create mode 100644 config/filter.d/squid.conf create mode 100644 testcases/files/logs/squid diff --git a/ChangeLog b/ChangeLog index 90b8ba27..a0624630 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,6 +32,7 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better len("fail2ban-"). - remove indentation of name and loglevel while logging to SYSLOG to resolve syslog(-ng) parsing problems. Closes Debian bug #730202. + - added squid filter. Thanks Roman Gelfand. - New Features: diff --git a/THANKS b/THANKS index 04c8728d..6d4845bb 100644 --- a/THANKS +++ b/THANKS @@ -62,6 +62,7 @@ RealRancor René Berber Robert Edeker Rolf Fokkens +Roman Gelfand Russell Odom Sebastian Arcus Sireyessire diff --git a/config/filter.d/squid.conf b/config/filter.d/squid.conf new file mode 100644 index 00000000..8cbf744f --- /dev/null +++ b/config/filter.d/squid.conf @@ -0,0 +1,13 @@ +# Fail2Ban filter for Squid attempted proxy bypasses +# +# + +[Definition] + +failregex = ^\s+\d\s\s+[A-Z]+_DENIED/403 .*$ + ^\s+\d\s\s+NONE/405 .*$ + + + +# Author: Daniel Black + diff --git a/testcases/files/logs/squid b/testcases/files/logs/squid new file mode 100644 index 00000000..fa2c593c --- /dev/null +++ b/testcases/files/logs/squid @@ -0,0 +1,13 @@ +# Logs thanks to Roman Gelfand +# +# failJSON: { "time": "2013-12-08T23:55:23", "match": true , "host": "91.188.124.227" } +1386543323.511 4 91.188.124.227 TCP_DENIED/403 4099 GET http://www.proxy-listen.de/azenv.php - HIER_NONE/- text/html + +# failJSON: { "time": "2013-12-08T23:58:20", "match": true , "host": "175.44.0.184" } +1386543500.220 5 175.44.0.184 NONE/405 3364 CONNECT error:method-not-allowed - HIER_NONE/- text/html + +# failJSON: { "time": "2013-12-09T00:08:04", "match": true , "host": "198.74.125.200" } +1386544084.763 3 198.74.125.200 TCP_DENIED/403 3722 GET http://www2t.biglobe.ne.jp/~take52/test/env.cgi - HIER_NONE/- text/html + +# failJSON: { "time": "2013-12-09T00:09:06", "match": true , "host": "175.42.91.151" } +1386544146.088 1 175.42.91.151 TCP_DENIED/403 3745 GET http://pkfsp.ru/wp-content/uploads/proxyc/engine.php - HIER_NONE/- text/html From 9d532828fcb51ca245b330c026a16da8bdecc941 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 07:44:41 +1100 Subject: [PATCH 116/165] BF: multiple _ separated values according to http://wiki.squid-cache.org/SquidFaq/SquidLogs#Squid_result_codes. Thanks Steven --- config/filter.d/squid.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/filter.d/squid.conf b/config/filter.d/squid.conf index 8cbf744f..da282692 100644 --- a/config/filter.d/squid.conf +++ b/config/filter.d/squid.conf @@ -4,7 +4,7 @@ [Definition] -failregex = ^\s+\d\s\s+[A-Z]+_DENIED/403 .*$ +failregex = ^\s+\d\s\s+[A-Z_]+_DENIED/403 .*$ ^\s+\d\s\s+NONE/405 .*$ From 5688c064ad757006bb268bb1e4d1ce6c120df0cd Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 09:50:17 +1100 Subject: [PATCH 117/165] ENH: separate out log capture framework for other test cases - now utils.LogCaptureTestCase --- testcases/actiontestcase.py | 27 +++++---------------------- testcases/utils.py | 29 ++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/testcases/actiontestcase.py b/testcases/actiontestcase.py index 14356ee5..e0587b3d 100644 --- a/testcases/actiontestcase.py +++ b/testcases/actiontestcase.py @@ -24,40 +24,23 @@ __author__ = "Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" -import unittest, time +import time import logging, sys from server.action import Action -from StringIO import StringIO +from utils import LogCaptureTestCase -class ExecuteAction(unittest.TestCase): +class ExecuteAction(LogCaptureTestCase): def setUp(self): """Call before every test case.""" self.__action = Action("Test") - - # For extended testing of what gets output into logging - # system, we will redirect it to a string - logSys = logging.getLogger("fail2ban") - - # Keep old settings - self._old_level = logSys.level - self._old_handlers = logSys.handlers - # Let's log everything into a string - self._log = StringIO() - logSys.handlers = [logging.StreamHandler(self._log)] - logSys.setLevel(getattr(logging, 'DEBUG')) + LogCaptureTestCase.setUp(self) def tearDown(self): """Call after every test case.""" - # print "O: >>%s<<" % self._log.getvalue() - logSys = logging.getLogger("fail2ban") - logSys.handlers = self._old_handlers - logSys.level = self._old_level + LogCaptureTestCase.tearDown(self) self.__action.execActionStop() - def _is_logged(self, s): - return s in self._log.getvalue() - def testNameChange(self): self.assertEqual(self.__action.getName(), "Test") self.__action.setName("Tricky Test") diff --git a/testcases/utils.py b/testcases/utils.py index 643c9ad1..b048c8c6 100644 --- a/testcases/utils.py +++ b/testcases/utils.py @@ -22,8 +22,9 @@ __author__ = "Yaroslav Halchenko" __copyright__ = "Copyright (c) 2013 Yaroslav Halchenko" __license__ = "GPL" -import logging, os, re, tempfile, sys, time, traceback +import unittest, logging, os, re, tempfile, sys, time, traceback from os.path import basename, dirname +from StringIO import StringIO # # Following "traceback" functions are adopted from PyMVPA distributed @@ -105,3 +106,29 @@ def mtimesleep(): # no sleep now should be necessary since polling tracks now not only # mtime but also ino and size pass + +class LogCaptureTestCase(unittest.TestCase): + + def setUp(self): + + # For extended testing of what gets output into logging + # system, we will redirect it to a string + logSys = logging.getLogger("fail2ban") + + # Keep old settings + self._old_level = logSys.level + self._old_handlers = logSys.handlers + # Let's log everything into a string + self._log = StringIO() + logSys.handlers = [logging.StreamHandler(self._log)] + logSys.setLevel(getattr(logging, 'DEBUG')) + + def tearDown(self): + """Call after every test case.""" + # print "O: >>%s<<" % self._log.getvalue() + logSys = logging.getLogger("fail2ban") + logSys.handlers = self._old_handlers + logSys.level = self._old_level + + def _is_logged(self, s): + return s in self._log.getvalue() From f4661d81779683e0ef92b3278347639e3260bb36 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 09:56:04 +1100 Subject: [PATCH 118/165] ENH: rebase LogFileMonitor on LogCaptureTestCase --- testcases/filtertestcase.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index 8bc24085..6ab99d82 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -39,7 +39,7 @@ from server.failmanager import FailManagerEmpty # Useful helpers # -from utils import mtimesleep +from utils import mtimesleep, LogCaptureTestCase # yoh: per Steven Hiscocks's insight while troubleshooting # https://github.com/fail2ban/fail2ban/issues/103#issuecomment-15542836 @@ -194,11 +194,12 @@ class LogFile(unittest.TestCase): self.assertTrue(self.filter.isModified(LogFile.FILENAME)) -class LogFileMonitor(unittest.TestCase): +class LogFileMonitor(LogCaptureTestCase): """Few more tests for FilterPoll API """ def setUp(self): """Call before every test case.""" + LogCaptureTestCase.setUp(self) self.filter = self.name = 'NA' _, self.name = tempfile.mkstemp('fail2ban', 'monitorfailures') self.file = open(self.name, 'a') @@ -208,6 +209,7 @@ class LogFileMonitor(unittest.TestCase): self.filter.addFailRegex("(?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) ") def tearDown(self): + LogCaptureTestCase.tearDown(self) _killfile(self.file, self.name) pass From f4531e7b45c97cb03480b5e58749bad83f914231 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 10:10:31 +1100 Subject: [PATCH 119/165] TST: test cases fro filter.delFailRegex and filter.delIgnoreRegex --- testcases/filtertestcase.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index 6ab99d82..b7b161d3 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -227,6 +227,16 @@ class LogFileMonitor(LogCaptureTestCase): # shorter wait time for not modified status return not self.isModified(0.4) + def testRemovingFailRegex(self): + self.filter.delFailRegex(0) + self.assertFalse(self._is_logged('Cannot remove regular expression. Index 0 is not valid')) + self.filter.delFailRegex(0) + self.assertTrue(self._is_logged('Cannot remove regular expression. Index 0 is not valid')) + + def testRemovingIgnoreRegex(self): + self.filter.delIgnoreRegex(0) + self.assertTrue(self._is_logged('Cannot remove regular expression. Index 0 is not valid')) + def testNewChangeViaIsModified(self): # it is a brand new one -- so first we think it is modified self.assertTrue(self.isModified()) From 44bbaebfe511e679e8a0dfa251e1383138f90002 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 10:15:24 +1100 Subject: [PATCH 120/165] TST: CIDR for ignoreip --- testcases/filtertestcase.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index b7b161d3..892a4a6e 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -173,6 +173,15 @@ class IgnoreIP(unittest.TestCase): self.filter.addIgnoreIP("www.epfl.ch") self.assertFalse(self.filter.inIgnoreIPList("127.177.50.10")) + def testIgnoreIPCIDR(self): + self.filter.addIgnoreIP('192.168.1.0/25') + self.assertTrue(self.filter.inIgnoreIPList('192.168.1.0')) + self.assertTrue(self.filter.inIgnoreIPList('192.168.1.1')) + self.assertTrue(self.filter.inIgnoreIPList('192.168.1.127')) + self.assertFalse(self.filter.inIgnoreIPList('192.168.1.128')) + self.assertFalse(self.filter.inIgnoreIPList('192.168.1.255')) + self.assertFalse(self.filter.inIgnoreIPList('192.168.0.255')) + class LogFile(unittest.TestCase): From 988e14d8c652a077fcb47a0ec1a88eb3ca3fdb5f Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 10:17:55 +1100 Subject: [PATCH 121/165] TST: negative match for DNS lookup test added --- testcases/filtertestcase.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index 892a4a6e..0d2b58fb 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -163,6 +163,8 @@ class IgnoreIP(unittest.TestCase): self.filter.addIgnoreIP("www.epfl.ch") self.assertTrue(self.filter.inIgnoreIPList("128.178.50.12")) + self.assertFalse(self.filter.inIgnoreIPList("128.178.50.11")) + self.assertFalse(self.filter.inIgnoreIPList("128.178.50.13")) def testIgnoreIPNOK(self): ipList = "", "999.999.999.999", "abcdef", "192.168.0." From 60c4957a5278b033c41e71c18d2824441507ea14 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 10:21:19 +1100 Subject: [PATCH 122/165] DOC/TST: remove TODO as all regexs have samples --- testcases/samplestestcase.py | 1 - 1 file changed, 1 deletion(-) diff --git a/testcases/samplestestcase.py b/testcases/samplestestcase.py index d88be5e9..6b4d4530 100644 --- a/testcases/samplestestcase.py +++ b/testcases/samplestestcase.py @@ -123,7 +123,6 @@ def testSampleRegexsFactory(name): regexsUsed.add(failregex) - # TODO: Remove exception handling once all regexs have samples for failRegexIndex, failRegex in enumerate(self.filter.getFailRegex()): self.assertTrue( failRegexIndex in regexsUsed, From a8b5c5b5f3f5de2c5a103c22f40672481ab33906 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 10:31:58 +1100 Subject: [PATCH 123/165] TST: check IgnoreIP happens in filter.processLine --- testcases/filtertestcase.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index 0d2b58fb..63f23400 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -144,15 +144,13 @@ def _copy_lines_between_files(fin, fout, n=None, skip=0, mode='a', terminal_line # Actual tests # -class IgnoreIP(unittest.TestCase): +class IgnoreIP(LogCaptureTestCase): def setUp(self): """Call before every test case.""" + LogCaptureTestCase.setUp(self) self.filter = FileFilter(None) - def tearDown(self): - """Call after every test case.""" - def testIgnoreIPOK(self): ipList = "127.0.0.1", "192.168.0.1", "255.255.255.255", "99.99.99.99" for ip in ipList: @@ -184,6 +182,12 @@ class IgnoreIP(unittest.TestCase): self.assertFalse(self.filter.inIgnoreIPList('192.168.1.255')) self.assertFalse(self.filter.inIgnoreIPList('192.168.0.255')) + def testIgnoreInProcessLine(self): + self.filter.addIgnoreIP('192.168.1.0/25') + self.filter.addFailRegex('') + self.filter.processLineAndAdd('Thu Jul 11 01:21:43 2013 192.168.1.32') + self.assertTrue(self._is_logged('Ignore 192.168.1.32')) + class LogFile(unittest.TestCase): From ebf4a02004ed2d312a3329f0dd4ab36cb0028f8f Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 10:43:47 +1100 Subject: [PATCH 124/165] TST: get/set use DNS on Filters --- fail2ban-testcases | 1 + testcases/filtertestcase.py | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/fail2ban-testcases b/fail2ban-testcases index f44e84d4..16c92c5f 100755 --- a/fail2ban-testcases +++ b/fail2ban-testcases @@ -174,6 +174,7 @@ tests.addTest(unittest.makeSuite(misctestcase.CustomDateFormatsTest)) # Filter if not opts.no_network: tests.addTest(unittest.makeSuite(filtertestcase.IgnoreIP)) +tests.addTest(unittest.makeSuite(filtertestcase.BasicFilter)) tests.addTest(unittest.makeSuite(filtertestcase.LogFile)) tests.addTest(unittest.makeSuite(filtertestcase.LogFileMonitor)) if not opts.no_network: diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index 63f23400..7b09ffed 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -31,7 +31,7 @@ import tempfile from server.jail import Jail from server.filterpoll import FilterPoll -from server.filter import FileFilter, DNSUtils +from server.filter import Filter, FileFilter, DNSUtils from server.failmanager import FailManager from server.failmanager import FailManagerEmpty @@ -144,6 +144,20 @@ def _copy_lines_between_files(fin, fout, n=None, skip=0, mode='a', terminal_line # Actual tests # +class BasicFilter(unittest.TestCase): + + def setUp(self): + self.filter = Filter('name') + + def testGetSetUseDNS(self): + # default is warn + self.assertEqual(self.filter.getUseDns(), 'warn') + self.filter.setUseDns(True) + self.assertEqual(self.filter.getUseDns(), 'yes') + self.filter.setUseDns(False) + self.assertEqual(self.filter.getUseDns(), 'no') + + class IgnoreIP(LogCaptureTestCase): def setUp(self): From f3c42851180f08316a5b898ad5566000ab7b4af9 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 10:46:52 +1100 Subject: [PATCH 125/165] TST: no test coverage on subclass overwritten function _delLogPath --- server/filter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/filter.py b/server/filter.py index 0ef756d2..52bb8c4c 100644 --- a/server/filter.py +++ b/server/filter.py @@ -446,7 +446,7 @@ class FileFilter(Filter): self._delLogPath(path) return - def _delLogPath(self, path): + def _delLogPath(self, path): # pragma: no cover - overwritten function # nothing to do by default # to be overridden by backends pass From 2b89457dc94249d44295cc5e79d17e0ec0fb3522 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 10:55:06 +1100 Subject: [PATCH 126/165] TST: addBanned IP when ignore exists --- testcases/filtertestcase.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index 7b09ffed..29491ae5 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -34,6 +34,7 @@ from server.filterpoll import FilterPoll from server.filter import Filter, FileFilter, DNSUtils from server.failmanager import FailManager from server.failmanager import FailManagerEmpty +from dummyjail import DummyJail # # Useful helpers @@ -163,7 +164,8 @@ class IgnoreIP(LogCaptureTestCase): def setUp(self): """Call before every test case.""" LogCaptureTestCase.setUp(self) - self.filter = FileFilter(None) + self.jail = DummyJail() + self.filter = FileFilter(self.jail) def testIgnoreIPOK(self): ipList = "127.0.0.1", "192.168.0.1", "255.255.255.255", "99.99.99.99" @@ -202,6 +204,11 @@ class IgnoreIP(LogCaptureTestCase): self.filter.processLineAndAdd('Thu Jul 11 01:21:43 2013 192.168.1.32') self.assertTrue(self._is_logged('Ignore 192.168.1.32')) + def testIgnoreAddBannedIP(self): + self.filter.addIgnoreIP('192.168.1.0/25') + self.filter.addBannedIP('192.168.1.32') + self.assertFalse(self._is_logged('Ignore 192.168.1.32')) + self.assertTrue(self._is_logged('Requested to manually ban an ignored IP 192.168.1.32. User knows best. Proceeding to ban it.')) class LogFile(unittest.TestCase): @@ -347,7 +354,6 @@ class LogFileMonitor(LogCaptureTestCase): from threading import Lock -from dummyjail import DummyJail def get_monitor_failures_testcase(Filter_): """Generator of TestCase's for different filters/backends From c13b91fa709a39e8c402d55453178af35dd20c29 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 12:08:23 +1100 Subject: [PATCH 127/165] TST: separate out DNS based IgnoreIP tests --- fail2ban-testcases | 3 ++- testcases/filtertestcase.py | 25 ++++++++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/fail2ban-testcases b/fail2ban-testcases index 16c92c5f..21b8fda4 100755 --- a/fail2ban-testcases +++ b/fail2ban-testcases @@ -173,7 +173,8 @@ tests.addTest(unittest.makeSuite(misctestcase.CustomDateFormatsTest)) # Filter if not opts.no_network: - tests.addTest(unittest.makeSuite(filtertestcase.IgnoreIP)) + tests.addTest(unittest.makeSuite(filtertestcase.IgnoreIPDNS)) +tests.addTest(unittest.makeSuite(filtertestcase.IgnoreIP)) tests.addTest(unittest.makeSuite(filtertestcase.BasicFilter)) tests.addTest(unittest.makeSuite(filtertestcase.LogFile)) tests.addTest(unittest.makeSuite(filtertestcase.LogFileMonitor)) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index 29491ae5..46870d41 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -173,21 +173,12 @@ class IgnoreIP(LogCaptureTestCase): self.filter.addIgnoreIP(ip) self.assertTrue(self.filter.inIgnoreIPList(ip)) - # Test DNS - self.filter.addIgnoreIP("www.epfl.ch") - - self.assertTrue(self.filter.inIgnoreIPList("128.178.50.12")) - self.assertFalse(self.filter.inIgnoreIPList("128.178.50.11")) - self.assertFalse(self.filter.inIgnoreIPList("128.178.50.13")) def testIgnoreIPNOK(self): ipList = "", "999.999.999.999", "abcdef", "192.168.0." for ip in ipList: self.filter.addIgnoreIP(ip) self.assertFalse(self.filter.inIgnoreIPList(ip)) - # Test DNS - self.filter.addIgnoreIP("www.epfl.ch") - self.assertFalse(self.filter.inIgnoreIPList("127.177.50.10")) def testIgnoreIPCIDR(self): self.filter.addIgnoreIP('192.168.1.0/25') @@ -210,6 +201,22 @@ class IgnoreIP(LogCaptureTestCase): self.assertFalse(self._is_logged('Ignore 192.168.1.32')) self.assertTrue(self._is_logged('Requested to manually ban an ignored IP 192.168.1.32. User knows best. Proceeding to ban it.')) + +class IgnoreIPDNS(IgnoreIP): + + def testIgnoreIPDNSOK(self): + self.filter.addIgnoreIP("www.epfl.ch") + self.assertTrue(self.filter.inIgnoreIPList("128.178.50.12")) + + def testIgnoreIPDNSNOK(self): + # Test DNS + self.filter.addIgnoreIP("www.epfl.ch") + print self._log.getvalue() + self.assertFalse(self.filter.inIgnoreIPList("127.177.50.10")) + self.assertFalse(self.filter.inIgnoreIPList("128.178.50.11")) + self.assertFalse(self.filter.inIgnoreIPList("128.178.50.13")) + + class LogFile(unittest.TestCase): FILENAME = "testcases/files/testcase01.log" From 33d96ae4626d0b9d40afef39dfc5a02bafb7aeb1 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 12:10:44 +1100 Subject: [PATCH 128/165] TST: separate out DNS based IgnoreIP tests --- testcases/filtertestcase.py | 1 - 1 file changed, 1 deletion(-) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index 46870d41..a4d0230f 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -211,7 +211,6 @@ class IgnoreIPDNS(IgnoreIP): def testIgnoreIPDNSNOK(self): # Test DNS self.filter.addIgnoreIP("www.epfl.ch") - print self._log.getvalue() self.assertFalse(self.filter.inIgnoreIPList("127.177.50.10")) self.assertFalse(self.filter.inIgnoreIPList("128.178.50.11")) self.assertFalse(self.filter.inIgnoreIPList("128.178.50.13")) From 5005719180bb7a344b00740851fc0b133233f0bb Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 12:34:26 +1100 Subject: [PATCH 129/165] TST: permission denied on log file --- testcases/filtertestcase.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index a4d0230f..000ff353 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -269,6 +269,11 @@ class LogFileMonitor(LogCaptureTestCase): # shorter wait time for not modified status return not self.isModified(0.4) + def testNoLogFile(self): + os.chmod(self.name, 0) + self.filter.getFailures(self.name) + self.assertTrue(self._is_logged('Unable to open %s' % self.name)) + def testRemovingFailRegex(self): self.filter.delFailRegex(0) self.assertFalse(self._is_logged('Cannot remove regular expression. Index 0 is not valid')) From a03815facf198472273918b0763d97dd61286ac7 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 11 Dec 2013 13:07:08 +1100 Subject: [PATCH 130/165] TST: FileFilter tail tests --- server/filter.py | 3 +++ testcases/filtertestcase.py | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/server/filter.py b/server/filter.py index 52bb8c4c..b92289ef 100644 --- a/server/filter.py +++ b/server/filter.py @@ -568,6 +568,9 @@ class FileContainer: def getFileName(self): return self.__filename + def getPos(self): + return self.__pos + def open(self): self.__handler = open(self.__filename) # Set the file descriptor to be FD_CLOEXEC diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index 000ff353..7b18c4bf 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -603,7 +603,13 @@ class GetFailures(unittest.TestCase): def tearDown(self): """Call after every test case.""" - + def testTail(self): + self.filter.addLogPath(LogFile.FILENAME, tail=True) + self.assertEqual(self.filter.getLogPath()[-1].getPos(), 1653) + self.filter.getLogPath()[-1].close() + self.assertEqual(self.filter.getLogPath()[-1].readline(), "") + self.filter.delLogPath(LogFile.FILENAME) + self.assertEqual(self.filter.getLogPath(),[]) def testGetFailures01(self, filename=None, failures=None): filename = filename or GetFailures.FILENAME_01 From f2c58e74c144b91c59b6f3fee9d48098a30f437e Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 12 Dec 2013 08:24:29 +0000 Subject: [PATCH 131/165] TST: check client.JailReader.setName --- testcases/clientreadertestcase.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testcases/clientreadertestcase.py b/testcases/clientreadertestcase.py index 773d5072..0e3e6132 100644 --- a/testcases/clientreadertestcase.py +++ b/testcases/clientreadertestcase.py @@ -114,6 +114,8 @@ class JailReaderTest(unittest.TestCase): self.assertTrue(jail.getOptions()) self.assertFalse(jail.isEnabled()) self.assertEqual(jail.getName(), 'ssh-iptables') + jail.setName('ssh-funky-blocker') + self.assertEqual(jail.getName(), 'ssh-funky-blocker') def testSplitAction(self): action = "mail-whois[name=SSH]" From 970fd5d2891f59c7ac3943d8c50715badbd1047c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 12 Dec 2013 08:52:01 +0000 Subject: [PATCH 132/165] BF: ensure dangling symlink error message is reachable $ ls -la /tmp/f2b-tempq0ipGY/f2 lrwxrwxrwx. 1 dan dan 11 Dec 12 08:42 /tmp/f2b-tempq0ipGY/f2 -> nonexisting In [3]: os.path.exists('/tmp/f2b-tempq0ipGY/f2') Out[3]: False In [4]: os.path.lexists('/tmp/f2b-tempq0ipGY/f2') Out[4]: True --- client/jailreader.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/jailreader.py b/client/jailreader.py index 7fbac423..8980431e 100644 --- a/client/jailreader.py +++ b/client/jailreader.py @@ -65,9 +65,10 @@ class JailReader(ConfigReader): pathList = [] for p in glob.glob(path): if not os.path.exists(p): - logSys.warning("File %s doesn't even exist, thus cannot be monitored" % p) - elif not os.path.lexists(p): - logSys.warning("File %s is a dangling link, thus cannot be monitored" % p) + if os.path.lexists(p): + logSys.warning("File %s is a dangling link, thus cannot be monitored" % p) + else: + logSys.warning("File %s doesn't even exist, thus cannot be monitored" % p) else: pathList.append(p) return pathList From f84a03d6b57b9a82fc42cd8e98dd71c11ddceeb8 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 12 Dec 2013 09:08:42 +0000 Subject: [PATCH 133/165] BF: remove nonreachable parts of code Glob ensures the file exists so only a check that a missing dangling symlink needs to be done. $ ls -la /tmp/f2b-tempq0ipGY/f2 lrwxrwxrwx. 1 dan dan 11 Dec 12 08:42 /tmp/f2b-tempq0ipGY/f2 -> xisting In [3]: os.path.exists('/tmp/f2b-tempq0ipGY/f2') Out[3]: False In [4]: os.path.lexists('/tmp/f2b-tempq0ipGY/f2') Out[4]: True --- client/jailreader.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/client/jailreader.py b/client/jailreader.py index 8980431e..1c651fe9 100644 --- a/client/jailreader.py +++ b/client/jailreader.py @@ -64,13 +64,10 @@ class JailReader(ConfigReader): """ pathList = [] for p in glob.glob(path): - if not os.path.exists(p): - if os.path.lexists(p): - logSys.warning("File %s is a dangling link, thus cannot be monitored" % p) - else: - logSys.warning("File %s doesn't even exist, thus cannot be monitored" % p) - else: + if os.path.exists(p): pathList.append(p) + else: + logSys.warning("File %s is a dangling link, thus cannot be monitored" % p) return pathList def getOptions(self): From cb4f1e51422bd5976f1598995996ccaa4cf29cc9 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 12 Dec 2013 09:10:12 +0000 Subject: [PATCH 134/165] TST: remove temp files in glob test --- testcases/clientreadertestcase.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/testcases/clientreadertestcase.py b/testcases/clientreadertestcase.py index 0e3e6132..7f85dbd9 100644 --- a/testcases/clientreadertestcase.py +++ b/testcases/clientreadertestcase.py @@ -135,6 +135,10 @@ class JailReaderTest(unittest.TestCase): self.assertEqual(JailReader._glob(os.path.join(d, '*')), [os.path.join(d, 'f1')]) # since f2 is dangling -- empty list self.assertEqual(JailReader._glob(os.path.join(d, 'f2')), []) + self.assertEqual(JailReader._glob(os.path.join(d, 'nonexisting')), []) + os.remove(os.path.join(d, 'f1')) + os.remove(os.path.join(d, 'f2')) + os.rmdir(d) class JailsReaderTest(unittest.TestCase): From 3036afca9167524e7cd54fb54fb63507f040fb12 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 12 Dec 2013 10:13:57 +0000 Subject: [PATCH 135/165] TST: check dangling link log message --- testcases/clientreadertestcase.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/testcases/clientreadertestcase.py b/testcases/clientreadertestcase.py index 7f85dbd9..0937a5a5 100644 --- a/testcases/clientreadertestcase.py +++ b/testcases/clientreadertestcase.py @@ -27,6 +27,7 @@ from client.configreader import ConfigReader from client.jailreader import JailReader from client.jailsreader import JailsReader from client.configurator import Configurator +from utils import LogCaptureTestCase class ConfigReaderTest(unittest.TestCase): @@ -106,7 +107,7 @@ option = %s self.assertEqual(self._getoption(), 1) -class JailReaderTest(unittest.TestCase): +class JailReaderTest(LogCaptureTestCase): def testStockSSHJail(self): jail = JailReader('ssh-iptables', basedir='config') # we are running tests from root project dir atm @@ -127,17 +128,21 @@ class JailReaderTest(unittest.TestCase): d = tempfile.mkdtemp(prefix="f2b-temp") # Generate few files # regular file - open(os.path.join(d, 'f1'), 'w').close() + f1 = os.path.join(d, 'f1') + open(f1, 'w').close() # dangling link - os.symlink('nonexisting', os.path.join(d, 'f2')) + + f2 = os.path.join(d, 'f2') + os.symlink('nonexisting',f2) # must be only f1 - self.assertEqual(JailReader._glob(os.path.join(d, '*')), [os.path.join(d, 'f1')]) + self.assertEqual(JailReader._glob(os.path.join(d, '*')), [f1]) # since f2 is dangling -- empty list - self.assertEqual(JailReader._glob(os.path.join(d, 'f2')), []) + self.assertEqual(JailReader._glob(f2), []) + self.assertTrue(self._is_logged('File %s is a dangling link, thus cannot be monitored' % f2)) self.assertEqual(JailReader._glob(os.path.join(d, 'nonexisting')), []) - os.remove(os.path.join(d, 'f1')) - os.remove(os.path.join(d, 'f2')) + os.remove(f1) + os.remove(f2) os.rmdir(d) class JailsReaderTest(unittest.TestCase): From b18ce122dd236776d500799475b675d52d7840b8 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 12 Dec 2013 20:07:09 +0000 Subject: [PATCH 136/165] BF/ENH: fix error when action doesn't match regex. Document unreachable code. Simplify regex --- client/jailreader.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/jailreader.py b/client/jailreader.py index 1c651fe9..2138acee 100644 --- a/client/jailreader.py +++ b/client/jailreader.py @@ -35,7 +35,7 @@ logSys = logging.getLogger("fail2ban.client.config") class JailReader(ConfigReader): - actionCRE = re.compile("^((?:\w|-|_|\.)+)(?:\[(.*)\])?$") + actionCRE = re.compile("^([\w_.-]+)(?:\[(.*)\])?$") def __init__(self, name, force_enable=False, **kwargs): ConfigReader.__init__(self, **kwargs) @@ -173,12 +173,16 @@ class JailReader(ConfigReader): def splitAction(action): m = JailReader.actionCRE.match(action) d = dict() - mgroups = m.groups() + try: + mgroups = m.groups() + except AttributeError: + raise ValueError("While reading action %s we should have got 1 or " + "2 groups. Got: 0" % action) if len(mgroups) == 2: action_name, action_opts = mgroups elif len(mgroups) == 1: action_name, action_opts = mgroups[0], None - else: + else: # pragma: nocover - unreachable - regex only can capture 2 groups raise ValueError("While reading action %s we should have got up to " "2 groups. Got: %r" % (action, mgroups)) if not action_opts is None: From c6d14dcf0eedef9513b3b5fb5b028ff301908734 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 12 Dec 2013 20:35:30 +0000 Subject: [PATCH 137/165] TST: complete coverage of splitAction --- client/jailreader.py | 2 +- testcases/clientreadertestcase.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/client/jailreader.py b/client/jailreader.py index 2138acee..131a4dd5 100644 --- a/client/jailreader.py +++ b/client/jailreader.py @@ -180,7 +180,7 @@ class JailReader(ConfigReader): "2 groups. Got: 0" % action) if len(mgroups) == 2: action_name, action_opts = mgroups - elif len(mgroups) == 1: + elif len(mgroups) == 1: # pragma: nocover - unreachable - .* on second group always matches action_name, action_opts = mgroups[0], None else: # pragma: nocover - unreachable - regex only can capture 2 groups raise ValueError("While reading action %s we should have got up to " diff --git a/testcases/clientreadertestcase.py b/testcases/clientreadertestcase.py index 0937a5a5..c22f028a 100644 --- a/testcases/clientreadertestcase.py +++ b/testcases/clientreadertestcase.py @@ -123,7 +123,19 @@ class JailReaderTest(LogCaptureTestCase): expected = ['mail-whois', {'name': 'SSH'}] result = JailReader.splitAction(action) self.assertEqual(expected, result) + + self.assertEqual(['mail.who_is', {}], JailReader.splitAction("mail.who_is")) + self.assertEqual(['mail.who_is', {'a':'cat', 'b':'dog'}], JailReader.splitAction("mail.who_is[a=cat,b=dog]")) + self.assertEqual(['mail--ho_is', {}], JailReader.splitAction("mail--ho_is")) + + self.assertEqual(['mail--ho_is', {}], JailReader.splitAction("mail--ho_is['s']")) + self.assertTrue(self._is_logged("Invalid argument ['s'] in ''s''")) + + self.assertEqual(['mail', {'a': ','}], JailReader.splitAction("mail[a=',']")) + self.assertRaises(ValueError, JailReader.splitAction ,'mail-how[') + + def testGlob(self): d = tempfile.mkdtemp(prefix="f2b-temp") # Generate few files From 3ddf8da76e6c69e0f91c9f2fdebba96f9932eff3 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 13 Dec 2013 08:45:10 +0000 Subject: [PATCH 138/165] ENH: ensure filter is defined in jail before its read --- client/jailreader.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/client/jailreader.py b/client/jailreader.py index 131a4dd5..1b5bf1ae 100644 --- a/client/jailreader.py +++ b/client/jailreader.py @@ -87,15 +87,18 @@ class JailReader(ConfigReader): if self.isEnabled(): # Read filter - self.__filter = FilterReader(self.__opts["filter"], self.__name, - basedir=self.getBaseDir()) - ret = self.__filter.read() - if ret: - self.__filter.getOptions(self.__opts) + if self.__opts["filter"]: + self.__filter = FilterReader(self.__opts["filter"], self.__name, + basedir=self.getBaseDir()) + ret = self.__filter.read() + if ret: + self.__filter.getOptions(self.__opts) + else: + logSys.error("Unable to read the filter") + return False else: - logSys.error("Unable to read the filter") - return False - + logSys.warn("No filter set for jail %s" % self.__name) + # Read action for act in self.__opts["action"].split('\n'): try: From d74dd31d2301d7e0c5479192405bdc55a70b3c62 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 13 Dec 2013 10:00:34 +0000 Subject: [PATCH 139/165] BF: corrected tests for missing jail Previously tests relied on the missing filter to trigger the conditions required for a missing jail. We now handle this explicitly. --- client/configreader.py | 2 +- client/jailreader.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/client/configreader.py b/client/configreader.py index 96aab5f3..470f029f 100644 --- a/client/configreader.py +++ b/client/configreader.py @@ -112,7 +112,7 @@ class ConfigReader(SafeConfigParserWithIncludes): except NoSectionError, e: # No "Definition" section or wrong basedir logSys.error(e) - values[option[1]] = option[2] + return False except NoOptionError: if not option[2] is None: logSys.warn("'%s' not defined in '%s'. Using default one: %r" diff --git a/client/jailreader.py b/client/jailreader.py index 1b5bf1ae..d7c7b84c 100644 --- a/client/jailreader.py +++ b/client/jailreader.py @@ -54,7 +54,7 @@ class JailReader(ConfigReader): return ConfigReader.read(self, "jail") def isEnabled(self): - return self.__force_enable or self.__opts["enabled"] + return self.__force_enable or ( self.__opts and self.__opts["enabled"] ) @staticmethod def _glob(path): @@ -84,6 +84,8 @@ class JailReader(ConfigReader): ["string", "filter", ""], ["string", "action", ""]] self.__opts = ConfigReader.getOptions(self, self.__name, opts) + if not self.__opts: + return False if self.isEnabled(): # Read filter From 1407b955e6673c025c8bd6252f7daca1251ea477 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 13 Dec 2013 10:03:51 +0000 Subject: [PATCH 140/165] TST: more client/jailreader tests --- MANIFEST | 4 ++++ testcases/clientreadertestcase.py | 19 ++++++++++++++++++- testcases/config/action.d/brokenaction.conf | 4 ++++ testcases/config/fail2ban.conf | 5 +++++ testcases/config/filter.d/simple.conf | 4 ++++ testcases/config/jail.conf | 20 ++++++++++++++++++++ 6 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 testcases/config/action.d/brokenaction.conf create mode 100644 testcases/config/fail2ban.conf create mode 100644 testcases/config/filter.d/simple.conf create mode 100644 testcases/config/jail.conf diff --git a/MANIFEST b/MANIFEST index 0e0eb327..a7fefd5c 100644 --- a/MANIFEST +++ b/MANIFEST @@ -242,3 +242,7 @@ files/fail2ban-tmpfiles.conf files/fail2ban.service files/ipmasq-ZZZzzz_fail2ban.rul files/gen_badbots +testcases/config/jail.conf +testcases/config/fail2ban.conf +testcases/config/filter.d/simple.conf +testcases/config/action.d/brokenaction.conf diff --git a/testcases/clientreadertestcase.py b/testcases/clientreadertestcase.py index c22f028a..2dec428e 100644 --- a/testcases/clientreadertestcase.py +++ b/testcases/clientreadertestcase.py @@ -109,6 +109,22 @@ option = %s class JailReaderTest(LogCaptureTestCase): + def testJailActionEmpty(self): + jail = JailReader('emptyaction', basedir=os.path.join('testcases','config')) + self.assertTrue(jail.read()) + self.assertTrue(jail.getOptions()) + self.assertTrue(jail.isEnabled()) + self.assertTrue(self._is_logged('No filter set for jail emptyaction')) + self.assertTrue(self._is_logged('No actions were defined for emptyaction')) + + def testJailActionBrokenDef(self): + jail = JailReader('brokenactiondef', basedir=os.path.join('testcases','config')) + self.assertTrue(jail.read()) + self.assertFalse(jail.getOptions()) + self.assertTrue(jail.isEnabled()) + self.assertTrue(self._is_logged('Error in action definition joho[foo')) + self.assertTrue(self._is_logged('Caught exception: While reading action joho[foo we should have got 1 or 2 groups. Got: 0')) + def testStockSSHJail(self): jail = JailReader('ssh-iptables', basedir='config') # we are running tests from root project dir atm self.assertTrue(jail.read()) @@ -157,7 +173,7 @@ class JailReaderTest(LogCaptureTestCase): os.remove(f2) os.rmdir(d) -class JailsReaderTest(unittest.TestCase): +class JailsReaderTest(LogCaptureTestCase): def testProvidingBadBasedir(self): if not os.path.exists('/XXX'): @@ -176,6 +192,7 @@ class JailsReaderTest(unittest.TestCase): # We should not "read" some bogus jail old_comm_commands = comm_commands[:] # make a copy self.assertFalse(jails.getOptions("BOGUS")) + self.assertTrue(self._is_logged("No section: 'BOGUS'")) # and there should be no side-effects self.assertEqual(jails.convert(), old_comm_commands) diff --git a/testcases/config/action.d/brokenaction.conf b/testcases/config/action.d/brokenaction.conf new file mode 100644 index 00000000..d2c8d059 --- /dev/null +++ b/testcases/config/action.d/brokenaction.conf @@ -0,0 +1,4 @@ + +[Definition] + +actioban = hit with big stick diff --git a/testcases/config/fail2ban.conf b/testcases/config/fail2ban.conf new file mode 100644 index 00000000..36984c78 --- /dev/null +++ b/testcases/config/fail2ban.conf @@ -0,0 +1,5 @@ +[Definition] + +# 3 = INFO +loglevel = 3 + diff --git a/testcases/config/filter.d/simple.conf b/testcases/config/filter.d/simple.conf new file mode 100644 index 00000000..4a2c0bb7 --- /dev/null +++ b/testcases/config/filter.d/simple.conf @@ -0,0 +1,4 @@ + +[Definition] + +failregex = diff --git a/testcases/config/jail.conf b/testcases/config/jail.conf new file mode 100644 index 00000000..419e2e2c --- /dev/null +++ b/testcases/config/jail.conf @@ -0,0 +1,20 @@ + +[DEFAULT] +filter = simple + +[emptyaction] +enabled = true +filter = +action = + +[brokenactiondef] +enabled = true +action = joho[foo + +[brokenaction] +enabled = true +action = brokenaction + +[missingaction] +enabled = true +action = thefunkychickendance From e916fcdce4cd5a0b927644c9f79e75375e8141d0 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 13 Dec 2013 10:51:38 +0000 Subject: [PATCH 141/165] TST: test case for actions and filters missing in a jail --- testcases/clientreadertestcase.py | 9 +++++++++ testcases/config/jail.conf | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/testcases/clientreadertestcase.py b/testcases/clientreadertestcase.py index 2dec428e..e85ddff8 100644 --- a/testcases/clientreadertestcase.py +++ b/testcases/clientreadertestcase.py @@ -117,6 +117,15 @@ class JailReaderTest(LogCaptureTestCase): self.assertTrue(self._is_logged('No filter set for jail emptyaction')) self.assertTrue(self._is_logged('No actions were defined for emptyaction')) + def testJailActionFilterMissing(self): + jail = JailReader('missingbitsjail', basedir=os.path.join('testcases','config')) + self.assertTrue(jail.read()) + self.assertFalse(jail.getOptions()) + self.assertTrue(jail.isEnabled()) + #print self._log.getvalue() + self.assertTrue(self._is_logged("Found no accessible config files for 'filter.d/catchallthebadies' under testcases/config")) + self.assertTrue(self._is_logged('Unable to read the filter')) + def testJailActionBrokenDef(self): jail = JailReader('brokenactiondef', basedir=os.path.join('testcases','config')) self.assertTrue(jail.read()) diff --git a/testcases/config/jail.conf b/testcases/config/jail.conf index 419e2e2c..4bdd74cf 100644 --- a/testcases/config/jail.conf +++ b/testcases/config/jail.conf @@ -15,6 +15,6 @@ action = joho[foo enabled = true action = brokenaction -[missingaction] -enabled = true +[missingbitsjail] +filter = catchallthebadies action = thefunkychickendance From f6fb737e6cece7d535e64a848fcc0b137519e51c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 13 Dec 2013 10:55:15 +0000 Subject: [PATCH 142/165] TST: remove commented test print --- testcases/clientreadertestcase.py | 1 - 1 file changed, 1 deletion(-) diff --git a/testcases/clientreadertestcase.py b/testcases/clientreadertestcase.py index e85ddff8..96f9134f 100644 --- a/testcases/clientreadertestcase.py +++ b/testcases/clientreadertestcase.py @@ -122,7 +122,6 @@ class JailReaderTest(LogCaptureTestCase): self.assertTrue(jail.read()) self.assertFalse(jail.getOptions()) self.assertTrue(jail.isEnabled()) - #print self._log.getvalue() self.assertTrue(self._is_logged("Found no accessible config files for 'filter.d/catchallthebadies' under testcases/config")) self.assertTrue(self._is_logged('Unable to read the filter')) From 2f3648c458e675de99acac6fef0a506c49a0daac Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 13 Dec 2013 11:11:58 +0000 Subject: [PATCH 143/165] DOC: add missing jail directives --- man/jail.conf.5 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/man/jail.conf.5 b/man/jail.conf.5 index 8ea44316..6c114c56 100644 --- a/man/jail.conf.5 +++ b/man/jail.conf.5 @@ -63,6 +63,12 @@ Comments: use '#' for comment lines and ';' (following a space) for inline comme .SH DEFAULT The following options are applicable to all jails. Their meaning is described in the default \fIjail.conf\fR file. .TP +\fBfilter\fR +.TP +\fBlogpath\fR +.TP +\fBaction\fR +.TP \fBignoreip\fR .TP \fBbantime\fR @@ -74,6 +80,10 @@ The following options are applicable to all jails. Their meaning is described in \fBbackend\fR .TP \fBusedns\fR +.TP +\fBfailregex\fR +.TP +\fBignoreregex\fR .SH "ACTION FILES" From b147270be769ff5b456e29d56d12d27dacd95480 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 13 Dec 2013 11:36:00 +0000 Subject: [PATCH 144/165] BF: allow processing with empty filter --- client/jailreader.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/jailreader.py b/client/jailreader.py index d7c7b84c..6f78275b 100644 --- a/client/jailreader.py +++ b/client/jailreader.py @@ -99,6 +99,7 @@ class JailReader(ConfigReader): logSys.error("Unable to read the filter") return False else: + self.__filter = None logSys.warn("No filter set for jail %s" % self.__name) # Read action @@ -168,7 +169,8 @@ class JailReader(ConfigReader): # Do not send a command if the rule is empty. if regex != '': stream.append(["set", self.__name, "addignoreregex", regex]) - stream.extend(self.__filter.convert()) + if self.__filter: + stream.extend(self.__filter.convert()) for action in self.__actions: stream.extend(action.convert()) stream.insert(0, ["add", self.__name, backend]) From 18f0e58caad68212e84f711526e3e1857ae7ae7b Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 13 Dec 2013 11:41:40 +0000 Subject: [PATCH 145/165] TST: increase coverage in jailreader --- testcases/clientreadertestcase.py | 32 +++++++++++++++++++++++++++++++ testcases/config/jail.conf | 12 ++++++++++++ 2 files changed, 44 insertions(+) diff --git a/testcases/clientreadertestcase.py b/testcases/clientreadertestcase.py index 96f9134f..f55be051 100644 --- a/testcases/clientreadertestcase.py +++ b/testcases/clientreadertestcase.py @@ -188,6 +188,38 @@ class JailsReaderTest(LogCaptureTestCase): reader = JailsReader(basedir='/XXX') self.assertRaises(ValueError, reader.read) + def testReadTestJailConf(self): + jails = JailsReader(basedir=os.path.join('testcases','config')) + self.assertTrue(jails.read()) # opens fine + self.assertFalse(jails.getOptions()) # reads not sof ine + self.assertRaises(ValueError, jails.convert) + comm_commands = jails.convert(allow_no_files=True) + self.maxDiff = None + self.assertEqual(comm_commands, + [['add', 'emptyaction', 'auto'], + ['set', 'emptyaction', 'usedns', 'warn'], + ['set', 'emptyaction', 'addlogpath', '/var/log/messages'], + ['set', 'emptyaction', 'maxretry', 3], + ['set', 'emptyaction', 'findtime', 600], + ['set', 'emptyaction', 'bantime', 600], + ['add', 'special', 'auto'], + ['set', 'special', 'usedns', 'warn'], + ['set', 'special', 'addlogpath', '/var/log/messages'], + ['set', 'special', 'maxretry', 3], + ['set', 'special', 'addfailregex', ''], + ['set', 'special', 'findtime', 600], + ['set', 'special', 'bantime', 600], + ['add', 'missinglogfiles', 'auto'], + ['set', 'missinglogfiles', 'usedns', 'warn'], + ['set', 'missinglogfiles', 'maxretry', 3], + ['set', 'missinglogfiles', 'findtime', 600], + ['set', 'missinglogfiles', 'bantime', 600], + ['set', 'missinglogfiles', 'addfailregex', ''], + ['start', 'emptyaction'], + ['start', 'special'], + ['start', 'missinglogfiles']]) + + def testReadStockJailConf(self): jails = JailsReader(basedir='config') # we are running tests from root project dir atm self.assertTrue(jails.read()) # opens fine diff --git a/testcases/config/jail.conf b/testcases/config/jail.conf index 4bdd74cf..ab791451 100644 --- a/testcases/config/jail.conf +++ b/testcases/config/jail.conf @@ -7,6 +7,14 @@ enabled = true filter = action = +[special] +failregex = +ignoreregex = +ignoreip = + +[missinglogfiles] +logpath = /weapons/of/mass/destruction + [brokenactiondef] enabled = true action = joho[foo @@ -18,3 +26,7 @@ action = brokenaction [missingbitsjail] filter = catchallthebadies action = thefunkychickendance + +[parse_to_end_of_jail.conf] +enabled = true +action = From 13ccebe78f2c9eafc148382559a79ced32354b50 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 13 Dec 2013 23:40:51 +0000 Subject: [PATCH 146/165] BF: fix actioncheck in firewallcmd --- ChangeLog | 1 + THANKS | 1 + config/action.d/firewallcmd-new.conf | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a0624630..0eca4e37 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,6 +26,7 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better settings. Closes gh-458, Debian bug #697333, Redhat bug #891798. - complain action - ensure where not matching other IPs in log sample. Closes gh-467 + - Fix firewall-cmd actioncheck - patch from Adam Tkac. Redhat Bug #979622 - Enhancements: - long names on jails documented based on iptables limit of 30 less diff --git a/THANKS b/THANKS index 6d4845bb..e448e09e 100644 --- a/THANKS +++ b/THANKS @@ -6,6 +6,7 @@ the project. If you have been left off, please let us know (preferably send a pull request on github with the "fix") and you will be added +Adam Tkac Adrien Clerc ache ag4ve (Shawn) diff --git a/config/action.d/firewallcmd-new.conf b/config/action.d/firewallcmd-new.conf index 55b6762d..d3443e4e 100644 --- a/config/action.d/firewallcmd-new.conf +++ b/config/action.d/firewallcmd-new.conf @@ -20,7 +20,7 @@ actionstop = firewall-cmd --direct --remove-rule ipv4 filter 0 -m state firewall-cmd --direct --remove-rules ipv4 filter fail2ban- firewall-cmd --direct --remove-chain ipv4 filter fail2ban- -actioncheck = firewall-cmd --direct --get-chains ipv4 filter | grep -q 'fail2ban-[ \t]' +actioncheck = firewall-cmd --direct --get-chains ipv4 filter | grep -Eq 'fail2ban-$|fail2ban- ' actionban = firewall-cmd --direct --add-rule ipv4 filter fail2ban- 0 -s -j From b39729a2ab1abea9835fb4f5377c60d56308df9b Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 14 Dec 2013 06:51:36 +0000 Subject: [PATCH 147/165] BF: fix unintential typo --- testcases/config/action.d/brokenaction.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testcases/config/action.d/brokenaction.conf b/testcases/config/action.d/brokenaction.conf index d2c8d059..59e97b7f 100644 --- a/testcases/config/action.d/brokenaction.conf +++ b/testcases/config/action.d/brokenaction.conf @@ -1,4 +1,4 @@ [Definition] -actioban = hit with big stick +actionban = hit with big stick From 603095bc16ff08798cf16b789bc0360aa62ed112 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 14 Dec 2013 07:00:41 +0000 Subject: [PATCH 148/165] BF: errors in a jail prevents further sections from being parsed. Closes #485 --- client/jailsreader.py | 5 +++-- testcases/clientreadertestcase.py | 30 +++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/client/jailsreader.py b/client/jailsreader.py index 00c63e3c..d32e6561 100644 --- a/client/jailsreader.py +++ b/client/jailsreader.py @@ -60,6 +60,7 @@ class JailsReader(ConfigReader): sections = [ section ] # Get the options of all jails. + parse_status = True for sec in sections: jail = JailReader(sec, basedir=self.getBaseDir(), force_enable=self.__force_enable) @@ -71,8 +72,8 @@ class JailsReader(ConfigReader): self.__jails.append(jail) else: logSys.error("Errors in jail %r. Skipping..." % sec) - return False - return True + parse_status = False + return parse_status def convert(self, allow_no_files=False): """Convert read before __opts and jails to the commands stream diff --git a/testcases/clientreadertestcase.py b/testcases/clientreadertestcase.py index f55be051..91689836 100644 --- a/testcases/clientreadertestcase.py +++ b/testcases/clientreadertestcase.py @@ -215,9 +215,37 @@ class JailsReaderTest(LogCaptureTestCase): ['set', 'missinglogfiles', 'findtime', 600], ['set', 'missinglogfiles', 'bantime', 600], ['set', 'missinglogfiles', 'addfailregex', ''], + ['add', 'brokenaction', 'auto'], + ['set', 'brokenaction', 'usedns', 'warn'], + ['set', 'brokenaction', 'addlogpath', '/var/log/messages'], + ['set', 'brokenaction', 'maxretry', 3], + ['set', 'brokenaction', 'findtime', 600], + ['set', 'brokenaction', 'bantime', 600], + ['set', 'brokenaction', 'addfailregex', ''], + ['set', 'brokenaction', 'addaction', 'brokenaction'], + ['set', + 'brokenaction', + 'actionban', + 'brokenaction', + 'hit with big stick '], + ['set', 'brokenaction', 'actionstop', 'brokenaction', ''], + ['set', 'brokenaction', 'actionstart', 'brokenaction', ''], + ['set', 'brokenaction', 'actionunban', 'brokenaction', ''], + ['set', 'brokenaction', 'actioncheck', 'brokenaction', ''], + ['add', 'parse_to_end_of_jail.conf', 'auto'], + ['set', 'parse_to_end_of_jail.conf', 'usedns', 'warn'], + ['set', 'parse_to_end_of_jail.conf', 'addlogpath', '/var/log/messages'], + ['set', 'parse_to_end_of_jail.conf', 'maxretry', 3], + ['set', 'parse_to_end_of_jail.conf', 'findtime', 600], + ['set', 'parse_to_end_of_jail.conf', 'bantime', 600], + ['set', 'parse_to_end_of_jail.conf', 'addfailregex', ''], ['start', 'emptyaction'], ['start', 'special'], - ['start', 'missinglogfiles']]) + ['start', 'missinglogfiles'], + ['start', 'brokenaction'], + ['start', 'parse_to_end_of_jail.conf'],]) + self.assertTrue(self._is_logged("Errors in jail 'missingbitsjail'. Skipping...")) + self.assertTrue(self._is_logged("No file(s) found for glob /weapons/of/mass/destruction")) def testReadStockJailConf(self): From 4ffc57e14f1254942c88c9d9f94e9ef791af5e5f Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 14 Dec 2013 07:11:29 +0000 Subject: [PATCH 149/165] ENH: simplify firewallcmd-new actioncheck and provide output samples --- config/action.d/firewallcmd-new.conf | 30 +++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/config/action.d/firewallcmd-new.conf b/config/action.d/firewallcmd-new.conf index d3443e4e..7a5c03de 100644 --- a/config/action.d/firewallcmd-new.conf +++ b/config/action.d/firewallcmd-new.conf @@ -1,9 +1,5 @@ # Fail2Ban configuration file # -# Author: Edgar Hoch -# Copied from iptables-new.conf and modified for use with firewalld by Edgar Hoch. -# It uses "firewall-cmd" instead of "iptables". -# # Because of the --remove-rules in stop this action requires firewalld-0.3.8+ [INCLUDES] @@ -20,7 +16,7 @@ actionstop = firewall-cmd --direct --remove-rule ipv4 filter 0 -m state firewall-cmd --direct --remove-rules ipv4 filter fail2ban- firewall-cmd --direct --remove-chain ipv4 filter fail2ban- -actioncheck = firewall-cmd --direct --get-chains ipv4 filter | grep -Eq 'fail2ban-$|fail2ban- ' +actioncheck = firewall-cmd --direct --get-chains ipv4 filter | grep -Eq 'fail2ban-( |$)' actionban = firewall-cmd --direct --add-rule ipv4 filter fail2ban- 0 -s -j @@ -50,3 +46,27 @@ protocol = tcp # Values: [ STRING ] # chain = INPUT_direct + +# DEV NOTES: +# +# Author: Edgar Hoch +# Copied from iptables-new.conf and modified for use with firewalld by Edgar Hoch. +# It uses "firewall-cmd" instead of "iptables". +# +# Output: +# +# $ firewall-cmd --direct --add-chain ipv4 filter fail2ban-name +# success +# $ firewall-cmd --direct --add-rule ipv4 filter fail2ban-name 1000 -j RETURN +# success +# $ sudo firewall-cmd --direct --add-rule ipv4 filter INPUT_direct 0 -m state --state NEW -p tcp --dport 22 -j fail2ban-name +# success +# $ firewall-cmd --direct --get-chains ipv4 filter +# fail2ban-name +# $ firewall-cmd --direct --get-chains ipv4 filter | od -h +# 0000000 6166 6c69 6232 6e61 6e2d 6d61 0a65 +# $ firewall-cmd --direct --get-chains ipv4 filter | grep -Eq 'fail2ban-name( |$)' ; echo $? +# 0 +# $ firewall-cmd -V +# 0.3.8 + From a398c51d6c49ac5de70f9eee68f8c72c1fed10ba Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sun, 15 Dec 2013 22:36:47 +0000 Subject: [PATCH 150/165] ENH: simplify actioncheck on firewallcmd-new a little more --- config/action.d/firewallcmd-new.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/action.d/firewallcmd-new.conf b/config/action.d/firewallcmd-new.conf index 7a5c03de..bae72ca2 100644 --- a/config/action.d/firewallcmd-new.conf +++ b/config/action.d/firewallcmd-new.conf @@ -16,7 +16,7 @@ actionstop = firewall-cmd --direct --remove-rule ipv4 filter 0 -m state firewall-cmd --direct --remove-rules ipv4 filter fail2ban- firewall-cmd --direct --remove-chain ipv4 filter fail2ban- -actioncheck = firewall-cmd --direct --get-chains ipv4 filter | grep -Eq 'fail2ban-( |$)' +actioncheck = firewall-cmd --direct --get-chains ipv4 filter | grep -q '^fail2ban-$' actionban = firewall-cmd --direct --add-rule ipv4 filter fail2ban- 0 -s -j From 5c26bcbd2b24328a4fc85be0360090ee787bf6d9 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 16 Dec 2013 10:07:41 +0000 Subject: [PATCH 151/165] TST: hopefully normalise config so that consistent test results occur on travis and locally --- testcases/clientreadertestcase.py | 4 ---- testcases/config/jail.conf | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/testcases/clientreadertestcase.py b/testcases/clientreadertestcase.py index 91689836..42c3fa28 100644 --- a/testcases/clientreadertestcase.py +++ b/testcases/clientreadertestcase.py @@ -198,13 +198,11 @@ class JailsReaderTest(LogCaptureTestCase): self.assertEqual(comm_commands, [['add', 'emptyaction', 'auto'], ['set', 'emptyaction', 'usedns', 'warn'], - ['set', 'emptyaction', 'addlogpath', '/var/log/messages'], ['set', 'emptyaction', 'maxretry', 3], ['set', 'emptyaction', 'findtime', 600], ['set', 'emptyaction', 'bantime', 600], ['add', 'special', 'auto'], ['set', 'special', 'usedns', 'warn'], - ['set', 'special', 'addlogpath', '/var/log/messages'], ['set', 'special', 'maxretry', 3], ['set', 'special', 'addfailregex', ''], ['set', 'special', 'findtime', 600], @@ -217,7 +215,6 @@ class JailsReaderTest(LogCaptureTestCase): ['set', 'missinglogfiles', 'addfailregex', ''], ['add', 'brokenaction', 'auto'], ['set', 'brokenaction', 'usedns', 'warn'], - ['set', 'brokenaction', 'addlogpath', '/var/log/messages'], ['set', 'brokenaction', 'maxretry', 3], ['set', 'brokenaction', 'findtime', 600], ['set', 'brokenaction', 'bantime', 600], @@ -234,7 +231,6 @@ class JailsReaderTest(LogCaptureTestCase): ['set', 'brokenaction', 'actioncheck', 'brokenaction', ''], ['add', 'parse_to_end_of_jail.conf', 'auto'], ['set', 'parse_to_end_of_jail.conf', 'usedns', 'warn'], - ['set', 'parse_to_end_of_jail.conf', 'addlogpath', '/var/log/messages'], ['set', 'parse_to_end_of_jail.conf', 'maxretry', 3], ['set', 'parse_to_end_of_jail.conf', 'findtime', 600], ['set', 'parse_to_end_of_jail.conf', 'bantime', 600], diff --git a/testcases/config/jail.conf b/testcases/config/jail.conf index ab791451..525308e3 100644 --- a/testcases/config/jail.conf +++ b/testcases/config/jail.conf @@ -1,6 +1,7 @@ [DEFAULT] filter = simple +logpath = /non/exist [emptyaction] enabled = true From 729929ada98f63558ae8cd61586868173bc234ef Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 16 Dec 2013 10:21:46 +0000 Subject: [PATCH 152/165] TST: jails can occur in any order once parsed. Sort results to facilitate comparison --- testcases/clientreadertestcase.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/testcases/clientreadertestcase.py b/testcases/clientreadertestcase.py index 42c3fa28..28387703 100644 --- a/testcases/clientreadertestcase.py +++ b/testcases/clientreadertestcase.py @@ -190,13 +190,13 @@ class JailsReaderTest(LogCaptureTestCase): def testReadTestJailConf(self): jails = JailsReader(basedir=os.path.join('testcases','config')) - self.assertTrue(jails.read()) # opens fine - self.assertFalse(jails.getOptions()) # reads not sof ine + self.assertTrue(jails.read()) + self.assertFalse(jails.getOptions()) self.assertRaises(ValueError, jails.convert) comm_commands = jails.convert(allow_no_files=True) self.maxDiff = None - self.assertEqual(comm_commands, - [['add', 'emptyaction', 'auto'], + self.assertEqual(sorted(comm_commands), + sorted([['add', 'emptyaction', 'auto'], ['set', 'emptyaction', 'usedns', 'warn'], ['set', 'emptyaction', 'maxretry', 3], ['set', 'emptyaction', 'findtime', 600], @@ -239,7 +239,7 @@ class JailsReaderTest(LogCaptureTestCase): ['start', 'special'], ['start', 'missinglogfiles'], ['start', 'brokenaction'], - ['start', 'parse_to_end_of_jail.conf'],]) + ['start', 'parse_to_end_of_jail.conf'],])) self.assertTrue(self._is_logged("Errors in jail 'missingbitsjail'. Skipping...")) self.assertTrue(self._is_logged("No file(s) found for glob /weapons/of/mass/destruction")) From 5f623596ee3d96d433458c3106e0f44cd7be04f6 Mon Sep 17 00:00:00 2001 From: alasdairdc Date: Tue, 17 Dec 2013 17:45:50 +0000 Subject: [PATCH 153/165] Updated check_fail2ban to return performance data for all jails Allows perf data from all jails to enable pnp4nagios to display a chart per jail when run with the command: check_fail2ban -p -w 1 -c 5 -P /usr/bin/fail2ban-client sample output: CHECK FAIL2BAN ACTIVITY - CRITICAL - 9 detected jails with 5 current banned IP(s) | apache-noscript.currentBannedIP=0 sendmail.currentBannedIP=0 postfix.currentBannedIP=0 ssh-probe.currentBannedIP=3 ssh-ddos.currentBannedIP=0 apache-multiport.currentBannedIP=0 apache.currentBannedIP=0 ssh.currentBannedIP=2 apache-overflows.currentBannedIP=0 --- files/nagios/check_fail2ban | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/files/nagios/check_fail2ban b/files/nagios/check_fail2ban index 77a63393..afde57d9 100755 --- a/files/nagios/check_fail2ban +++ b/files/nagios/check_fail2ban @@ -165,7 +165,7 @@ if (($critical < 0) or ($warning < 0) or ($critical < $warning)) { # Core script # ----------- -my ($how_many_jail,$how_many_banned,$return_print,$plugstate) = (0,0,"","OK"); +my ($how_many_jail,$how_many_banned,$return_print,$perf_print,$plugstate) = (0,0,"","","OK"); ### Test the connection to the fail2ban server @@ -214,6 +214,7 @@ else { else { print "DEBUG : the jail $jail_name has currently $current_ban_number banned IPs\n" if ($verbose_value); $how_many_banned += int($current_ban_number); + $perf_print .= "$jail_name.currentBannedIP=$current_ban_number " if ($perfdata_value); } } $return_print = $how_many_jail.' detected jails with '.$how_many_banned.' current banned IP(s)'; @@ -224,7 +225,7 @@ $plugstate = "CRITICAL" if ($how_many_banned >= $critical); $plugstate = "WARNING" if (($how_many_banned >= $warning) && ($how_many_banned < $critical)); $return_print = $display." - ".$plugstate." - ".$return_print; -$return_print .= " | currentBannedIP=$how_many_banned" if ($perfdata_value); +$return_print .= " | $perf_print" if ($perfdata_value); print $return_print; exit $ERRORS{"$plugstate"}; From 2e5a2b26fbd433a82016deae68dabd0d7a051c77 Mon Sep 17 00:00:00 2001 From: alasdairdc Date: Tue, 17 Dec 2013 17:48:19 +0000 Subject: [PATCH 154/165] Updated check_fail2ban to return performance data for all jails and applied to specific jail code --- files/nagios/check_fail2ban | 1 + 1 file changed, 1 insertion(+) diff --git a/files/nagios/check_fail2ban b/files/nagios/check_fail2ban index afde57d9..9bf14305 100755 --- a/files/nagios/check_fail2ban +++ b/files/nagios/check_fail2ban @@ -190,6 +190,7 @@ if ($jail_specific) { else { $how_many_banned = int($current_ban_number); $return_print = $how_many_banned.' current banned IP(s) for the specific jail '.$jail_specific; + $perf_print .= "$jail_name.currentBannedIP=$current_ban_number " if ($perfdata_value); } } ### To analyze all the jail From 4e4f194457c89253c75d5734eb185446129e489b Mon Sep 17 00:00:00 2001 From: alasdairdc Date: Wed, 18 Dec 2013 08:31:54 +0000 Subject: [PATCH 155/165] Updated Thanks. --- THANKS | 1 + 1 file changed, 1 insertion(+) diff --git a/THANKS b/THANKS index e448e09e..84f96b9a 100644 --- a/THANKS +++ b/THANKS @@ -10,6 +10,7 @@ Adam Tkac Adrien Clerc ache ag4ve (Shawn) +Alasdair D. Campbell Amir Caspi Andrey G. Grozin Andy Fragen From 04c267c307c670b17c0f7572a20a104d165d044e Mon Sep 17 00:00:00 2001 From: alasdairdc Date: Wed, 18 Dec 2013 08:36:30 +0000 Subject: [PATCH 156/165] Updated Changelog --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 0eca4e37..77fd6a03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,7 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - remove indentation of name and loglevel while logging to SYSLOG to resolve syslog(-ng) parsing problems. Closes Debian bug #730202. - added squid filter. Thanks Roman Gelfand. + - updated check_fail2ban to return performance data for all jails. - New Features: From d22716ab63a6e38c3f2c5c40c15c9fd2e2d3c421 Mon Sep 17 00:00:00 2001 From: Steven Hiscocks Date: Wed, 18 Dec 2013 22:31:54 +0000 Subject: [PATCH 157/165] ENH: Add nsd filter and amend DateEpoch to match date format --- ChangeLog | 2 ++ THANKS | 1 + config/filter.d/nsd.conf | 26 ++++++++++++++++++++++++++ server/datetemplate.py | 2 +- testcases/files/logs/nsd | 4 ++++ 5 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 config/filter.d/nsd.conf create mode 100644 testcases/files/logs/nsd diff --git a/ChangeLog b/ChangeLog index 77fd6a03..e9b3d638 100644 --- a/ChangeLog +++ b/ChangeLog @@ -40,6 +40,8 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better Daniel Black * filter.d/solid-pop3d -- added thanks to Jacques Lav!gnotte on mailinglist. + Bas van den Dikkenberg & Steven Hiscocks + * filter.d/nsd.conf -- also amended Unix date template to match nsd format - Enhancements: - loglines now also report "[PID]" after the name portion diff --git a/THANKS b/THANKS index 84f96b9a..b9b86043 100644 --- a/THANKS +++ b/THANKS @@ -16,6 +16,7 @@ Andrey G. Grozin Andy Fragen Arturo 'Buanzo' Busleiman Axel Thimm +Bas van den Dikkenberg Beau Raines Bill Heaton Carlos Alberto Lopez Perez diff --git a/config/filter.d/nsd.conf b/config/filter.d/nsd.conf new file mode 100644 index 00000000..cd4ce35f --- /dev/null +++ b/config/filter.d/nsd.conf @@ -0,0 +1,26 @@ +# Fail2Ban configuration file +# +# Author: Bas van den Dikkenberg +# +# + +[INCLUDES] + +# Read common prefixes. If any customizations available -- read them from +# common.local +before = common.conf + + +[Definition] + +_daemon = nsd + +# Option: failregex +# Notes.: regex to match the password failures 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[\w\-.^_]+) +# Values: TEXT + +failregex = ^\[\]%(__prefix_line)sinfo: ratelimit block .* query TYPE255$ + ^\[\]%(__prefix_line)sinfo: .* refused, no acl matches\.$ diff --git a/server/datetemplate.py b/server/datetemplate.py index decaee1c..33c69703 100644 --- a/server/datetemplate.py +++ b/server/datetemplate.py @@ -78,7 +78,7 @@ class DateEpoch(DateTemplate): def __init__(self): DateTemplate.__init__(self) - self.setRegex("(?:^|(?P(?<=audit\()))\d{10}(?:\.\d{3,6})?(?(selinux)(?=:\d+\)))") + self.setRegex("(?:^|(?P(?<=^\[))|(?P(?<=audit\()))\d{10}(?:\.\d{3,6})?(?(selinux)(?=:\d+\))(?(square)(?=\])))") def getDate(self, line): date = None diff --git a/testcases/files/logs/nsd b/testcases/files/logs/nsd new file mode 100644 index 00000000..a33a52a9 --- /dev/null +++ b/testcases/files/logs/nsd @@ -0,0 +1,4 @@ +# failJSON: { "time": "2013-12-17T14:58:14", "match": true , "host": "192.0.2.105" } +[1387288694] nsd[7745]: info: ratelimit block example.com. type any target 192.0.2.0/24 query 192.0.2.105 TYPE255 +# failJSON: { "time": "2013-12-18T07:42:15", "match": true , "host": "192.0.2.115" } +[1387348935] nsd[23600]: info: axfr for zone domain.nl. from client 192.0.2.115 refused, no acl matches. From a9b7d33c51ab3eb23f28a774ab088c9d35f74a03 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 19 Dec 2013 10:01:24 +0000 Subject: [PATCH 158/165] ENH: apache-noscript now matched php-cgi scripts. Closes gh-503 --- ChangeLog | 1 + THANKS | 1 + config/filter.d/apache-noscript.conf | 4 ++-- testcases/files/logs/apache-noscript | 11 +++++++++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0eca4e37..cbfb2618 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,7 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - remove indentation of name and loglevel while logging to SYSLOG to resolve syslog(-ng) parsing problems. Closes Debian bug #730202. - added squid filter. Thanks Roman Gelfand. + - filter apache-noscript added php cgi scripts. Thanks dani. closes gh-503 - New Features: diff --git a/THANKS b/THANKS index e448e09e..dbf9db8f 100644 --- a/THANKS +++ b/THANKS @@ -24,6 +24,7 @@ Christoph Haas Christos Psonis Cyril Jaquier Daniel B. Cid +Daniel B. Daniel Black David Nutter Eric Gerbier diff --git a/config/filter.d/apache-noscript.conf b/config/filter.d/apache-noscript.conf index 7ea257b2..9a591ca3 100644 --- a/config/filter.d/apache-noscript.conf +++ b/config/filter.d/apache-noscript.conf @@ -9,8 +9,8 @@ before = apache-common.conf [Definition] -failregex = ^%(_apache_error_client)s ((AH001(28|30): )?File does not exist|(AH01264: )?script not found or unable to stat): /\S*(\.php|\.asp|\.exe|\.pl)(, referer: \S+)?\s*$ - ^%(_apache_error_client)s script '/\S*(\.php|\.asp|\.exe|\.pl)\S*' not found or unable to stat(, referer: \S+)?\s*$ +failregex = ^%(_apache_error_client)s ((AH001(28|30): )?File does not exist|(AH01264: )?script not found or unable to stat): /\S*(php([45]|[.-]cgi)?|\.asp|\.exe|\.pl)(, referer: \S+)?\s*$ + ^%(_apache_error_client)s script '/\S*(php([45]|[.-]cgi)?|\.asp|\.exe|\.pl)\S*' not found or unable to stat(, referer: \S+)?\s*$ ignoreregex = diff --git a/testcases/files/logs/apache-noscript b/testcases/files/logs/apache-noscript index 53e33baf..19fa408a 100644 --- a/testcases/files/logs/apache-noscript +++ b/testcases/files/logs/apache-noscript @@ -2,3 +2,14 @@ [Sun Jun 09 07:57:47 2013] [error] [client 192.0.43.10] script '/usr/lib/cgi-bin/gitweb.cgiwp-login.php' not found or unable to stat # failJSON: { "time": "2008-07-22T06:48:30", "match": true , "host": "198.51.100.86" } [Tue Jul 22 06:48:30 2008] [error] [client 198.51.100.86] File does not exist: /home/southern/public_html/azenv.php + +# failJSON: { "time": "2008-07-22T06:48:30", "match": true , "host": "198.51.100.86" } +[Tue Jul 22 06:48:30 2008] [error] [client 198.51.100.86] script not found or unable to stat: /home/e-smith/files/ibays/Primary/cgi-bin/php +# failJSON: { "time": "2008-07-22T06:48:30", "match": true , "host": "198.51.100.86" } +[Tue Jul 22 06:48:30 2008] [error] [client 198.51.100.86] script not found or unable to stat: /home/e-smith/files/ibays/Primary/cgi-bin/php5 +# failJSON: { "time": "2008-07-22T06:48:30", "match": true , "host": "198.51.100.86" } +[Tue Jul 22 06:48:30 2008] [error] [client 198.51.100.86] script not found or unable to stat: /home/e-smith/files/ibays/Primary/cgi-bin/php-cgi +# failJSON: { "time": "2008-07-22T06:48:30", "match": true , "host": "198.51.100.86" } +[Tue Jul 22 06:48:30 2008] [error] [client 198.51.100.86] script not found or unable to stat: /home/e-smith/files/ibays/Primary/cgi-bin/php.cgi +# failJSON: { "time": "2008-07-22T06:48:30", "match": true , "host": "198.51.100.86" } +[Tue Jul 22 06:48:30 2008] [error] [client 198.51.100.86] script not found or unable to stat: /home/e-smith/files/ibays/Primary/cgi-bin/php4 From 2d688a5a03ce9f76827a2694e56fbae7680412b0 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sun, 22 Dec 2013 07:47:24 +0000 Subject: [PATCH 159/165] TST: improve polling test case to ensure isModified only returns True once (file static) --- testcases/filtertestcase.py | 1 + 1 file changed, 1 insertion(+) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index 7b18c4bf..8c706d58 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -234,6 +234,7 @@ class LogFile(unittest.TestCase): def testIsModified(self): self.assertTrue(self.filter.isModified(LogFile.FILENAME)) + self.assertFalse(self.filter.isModified(LogFile.FILENAME)) class LogFileMonitor(LogCaptureTestCase): From 2a67ef519c3a28b64b5b1096173b6bf8090d066d Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sun, 22 Dec 2013 08:43:57 +0000 Subject: [PATCH 160/165] TST: missing logpath raises IOError --- fail2ban-testcases | 1 + testcases/filtertestcase.py | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/fail2ban-testcases b/fail2ban-testcases index 21b8fda4..c1191d0e 100755 --- a/fail2ban-testcases +++ b/fail2ban-testcases @@ -177,6 +177,7 @@ if not opts.no_network: tests.addTest(unittest.makeSuite(filtertestcase.IgnoreIP)) tests.addTest(unittest.makeSuite(filtertestcase.BasicFilter)) tests.addTest(unittest.makeSuite(filtertestcase.LogFile)) +tests.addTest(unittest.makeSuite(filtertestcase.LogFileFilterPoll)) tests.addTest(unittest.makeSuite(filtertestcase.LogFileMonitor)) if not opts.no_network: tests.addTest(unittest.makeSuite(filtertestcase.GetFailures)) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index 8c706d58..8111bcd4 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -215,15 +215,28 @@ class IgnoreIPDNS(IgnoreIP): self.assertFalse(self.filter.inIgnoreIPList("128.178.50.11")) self.assertFalse(self.filter.inIgnoreIPList("128.178.50.13")) +class LogFile(LogCaptureTestCase): -class LogFile(unittest.TestCase): + MISSING = 'testcases/missingLogFile' + + def setUp(self): + LogCaptureTestCase.setUp(self) + + def tearDown(self): + LogCaptureTestCase.tearDown(self) + + def testMissingLogFiles(self): + self.filter = FilterPoll(None) + self.assertRaises(IOError, self.filter.addLogPath, LogFile.MISSING) + +class LogFileFilterPoll(unittest.TestCase): FILENAME = "testcases/files/testcase01.log" def setUp(self): """Call before every test case.""" self.filter = FilterPoll(None) - self.filter.addLogPath(LogFile.FILENAME) + self.filter.addLogPath(LogFileFilterPoll.FILENAME) def tearDown(self): """Call after every test case.""" @@ -233,8 +246,8 @@ class LogFile(unittest.TestCase): # self.filter.openLogFile(LogFile.FILENAME) def testIsModified(self): - self.assertTrue(self.filter.isModified(LogFile.FILENAME)) - self.assertFalse(self.filter.isModified(LogFile.FILENAME)) + self.assertTrue(self.filter.isModified(LogFileFilterPoll.FILENAME)) + self.assertFalse(self.filter.isModified(LogFileFilterPoll.FILENAME)) class LogFileMonitor(LogCaptureTestCase): From 7a9252bd0e3773246d40ec13ca87c6088177aada Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sun, 22 Dec 2013 12:08:10 +0000 Subject: [PATCH 161/165] TST BF: local defination --- testcases/filtertestcase.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index 8111bcd4..90f0f28a 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -618,11 +618,11 @@ class GetFailures(unittest.TestCase): """Call after every test case.""" def testTail(self): - self.filter.addLogPath(LogFile.FILENAME, tail=True) + self.filter.addLogPath(GetFailures.FILENAME_01, tail=True) self.assertEqual(self.filter.getLogPath()[-1].getPos(), 1653) self.filter.getLogPath()[-1].close() self.assertEqual(self.filter.getLogPath()[-1].readline(), "") - self.filter.delLogPath(LogFile.FILENAME) + self.filter.delLogPath(GetFailures.FILENAME_01) self.assertEqual(self.filter.getLogPath(),[]) def testGetFailures01(self, filename=None, failures=None): From ce3cc358287a8892a92bc78fdd3f3a24ecc37cea Mon Sep 17 00:00:00 2001 From: leeclemens Date: Sun, 22 Dec 2013 15:33:53 -0500 Subject: [PATCH 162/165] Added myself to THANKS for previous commits --- THANKS | 1 + 1 file changed, 1 insertion(+) diff --git a/THANKS b/THANKS index b9b86043..ef167a10 100644 --- a/THANKS +++ b/THANKS @@ -48,6 +48,7 @@ Justin Shore Kévin Drapel kjohnsonecl kojiro +Lee Clemens Manuel Arostegui Ramirez Marcel Dopita Mark Edgington From 1b7df1181f74ee05a571152150d76b545f52295b Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 23 Dec 2013 08:28:40 +0000 Subject: [PATCH 163/165] BF: apache-2.4 log format fix. Closes gh-516 --- ChangeLog | 2 ++ THANKS | 1 + config/filter.d/apache-common.conf | 3 ++- testcases/files/logs/apache-noscript | 3 +++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 964cdd87..5484a91e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,6 +27,8 @@ ver. 0.8.12 (2013/12/XX) - things-can-only-get-better - complain action - ensure where not matching other IPs in log sample. Closes gh-467 - Fix firewall-cmd actioncheck - patch from Adam Tkac. Redhat Bug #979622 + - Fix apache-common for apache-2.4 log file format. Thanks Mark White. + Closes gh-516 - Enhancements: - long names on jails documented based on iptables limit of 30 less diff --git a/THANKS b/THANKS index 4dc2776f..7e97c04c 100644 --- a/THANKS +++ b/THANKS @@ -54,6 +54,7 @@ Manuel Arostegui Ramirez Marcel Dopita Mark Edgington Mark McKinstry +Mark White Markus Hoffmann Marvin Rouge mEDI diff --git a/config/filter.d/apache-common.conf b/config/filter.d/apache-common.conf index ca8f2417..ce7da6e8 100644 --- a/config/filter.d/apache-common.conf +++ b/config/filter.d/apache-common.conf @@ -8,12 +8,13 @@ after = apache-common.local [DEFAULT] -_apache_error_client = \[[^]]*\] \[(error|\S+:\S+)\]( \[pid \d+:\S+ \d+\])? \[client (:\d{1,5})?\] +_apache_error_client = \[[^]]*\] \[(:?error|\S+:\S+)\]( \[pid \d+(:\S+ \d+)?\])? \[client (:\d{1,5})?\] # Common prefix for [error] apache messages which also would include # Depending on the version it could be # 2.2: [Sat Jun 01 11:23:08 2013] [error] [client 1.2.3.4] # 2.4: [Thu Jun 27 11:55:44.569531 2013] [core:info] [pid 4101:tid 2992634688] [client 1.2.3.4:46652] +# 2.4: [Mon Dec 23 07:49:01.981912 2013] [:error] [pid 3790] [client 204.232.202.107:46301] script '/var/www/timthumb.php' not found or unable to # # Reference: https://github.com/fail2ban/fail2ban/issues/268 # diff --git a/testcases/files/logs/apache-noscript b/testcases/files/logs/apache-noscript index 19fa408a..68fc7c0a 100644 --- a/testcases/files/logs/apache-noscript +++ b/testcases/files/logs/apache-noscript @@ -13,3 +13,6 @@ [Tue Jul 22 06:48:30 2008] [error] [client 198.51.100.86] script not found or unable to stat: /home/e-smith/files/ibays/Primary/cgi-bin/php.cgi # failJSON: { "time": "2008-07-22T06:48:30", "match": true , "host": "198.51.100.86" } [Tue Jul 22 06:48:30 2008] [error] [client 198.51.100.86] script not found or unable to stat: /home/e-smith/files/ibays/Primary/cgi-bin/php4 +# apache 2.4 +# failJSON: { "time": "2013-12-23T07:49:01", "match": true , "host": "204.232.202.107" } +[Mon Dec 23 07:49:01.981912 2013] [:error] [pid 3790] [client 204.232.202.107:46301] script '/var/www/timthumb.php' not found or unable to stat From 382d68f0fe923f33f716a471d82a54fe30dbc505 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 23 Dec 2013 09:09:48 +0000 Subject: [PATCH 164/165] DOC: perfork model for apache log format --- config/filter.d/apache-common.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/filter.d/apache-common.conf b/config/filter.d/apache-common.conf index ce7da6e8..60591481 100644 --- a/config/filter.d/apache-common.conf +++ b/config/filter.d/apache-common.conf @@ -14,7 +14,7 @@ _apache_error_client = \[[^]]*\] \[(:?error|\S+:\S+)\]( \[pid \d+(:\S+ \d+)?\])? # Depending on the version it could be # 2.2: [Sat Jun 01 11:23:08 2013] [error] [client 1.2.3.4] # 2.4: [Thu Jun 27 11:55:44.569531 2013] [core:info] [pid 4101:tid 2992634688] [client 1.2.3.4:46652] -# 2.4: [Mon Dec 23 07:49:01.981912 2013] [:error] [pid 3790] [client 204.232.202.107:46301] script '/var/www/timthumb.php' not found or unable to +# 2.4 (perfork): [Mon Dec 23 07:49:01.981912 2013] [:error] [pid 3790] [client 204.232.202.107:46301] script '/var/www/timthumb.php' not found or unable to # # Reference: https://github.com/fail2ban/fail2ban/issues/268 # From b0ea5698b3eecdd6233e579c7c7319513c59dda8 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 23 Dec 2013 09:18:32 +0000 Subject: [PATCH 165/165] BF: prevent process_file being called in pyinotify backend on log rotation. Closes gh-512 --- server/filterpyinotify.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/server/filterpyinotify.py b/server/filterpyinotify.py index cea82711..9ecb999d 100644 --- a/server/filterpyinotify.py +++ b/server/filterpyinotify.py @@ -115,9 +115,6 @@ class FilterPyinotify(FileFilter): wd = self.__monitor.add_watch(path, pyinotify.IN_MODIFY) self.__watches.update(wd) logSys.debug("Added file watcher for %s", path) - # process the file since we did get even - self._process_file(path) - def _delFileWatcher(self, path): wdInt = self.__watches[path] @@ -143,6 +140,7 @@ class FilterPyinotify(FileFilter): logSys.debug("Added monitor for the parent directory %s", path_dir) self._addFileWatcher(path) + self._process_file(path) ##