From add8e61036a2dcb62250cb46e1209e0a5379b379 Mon Sep 17 00:00:00 2001 From: Cyril Roos Date: Wed, 2 Jul 2014 13:52:06 +0200 Subject: [PATCH 01/82] Added Directadmin filter, jail and log test --- config/filter.d/directadmin.conf | 23 +++++++++++++++++++++++ config/jail.conf | 5 +++++ fail2ban/tests/files/logs/directadmin | 14 ++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 config/filter.d/directadmin.conf create mode 100644 fail2ban/tests/files/logs/directadmin diff --git a/config/filter.d/directadmin.conf b/config/filter.d/directadmin.conf new file mode 100644 index 00000000..7622e548 --- /dev/null +++ b/config/filter.d/directadmin.conf @@ -0,0 +1,23 @@ +# Fail2Ban configuration file for Directadmin +# +# +# + +[INCLUDES] + +before = common.conf + +[Definition] + +failregex = ^: \'\' \d{1,3} failed login attempt(s)?. \s* + +ignoreregex = + +[Init] +datepattern = ^%%Y:%%m:%%d-%%H:%%M:%%S + +# +# Requires Directadmin v1.45.3 or higher. http://www.directadmin.com/features.php?id=1590 +# +# Author: Cyril Roos + diff --git a/config/jail.conf b/config/jail.conf index c42952d8..bfc2a9c2 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -709,3 +709,8 @@ enabled = false logpath = /opt/sun/comms/messaging64/log/mail.log_current maxretry = 6 banaction = iptables-allports + +[directadmin] +enabled = false +logpath = /var/log/directadmin/login.log +port = 2222 diff --git a/fail2ban/tests/files/logs/directadmin b/fail2ban/tests/files/logs/directadmin new file mode 100644 index 00000000..85f7f8b9 --- /dev/null +++ b/fail2ban/tests/files/logs/directadmin @@ -0,0 +1,14 @@ +# failJSON: { "time": "2014-07-02T00:17:45", "match": true , "host": "3.2.1.4" } +2014:07:02-00:17:45: '3.2.1.4' 2 failed login attempts. Account 'test' + +# failJSON: { "time": "2014-07-02T13:07:40", "match": true , "host": "40.40.123.231" } +2014:07:02-13:07:40: '40.40.123.231' 13 failed login attempts. Account 'admin' + +# failJSON: { "time": "2014-07-02T13:07:50", "match": true , "host": "40.40.123.231" } +2014:07:02-13:07:50: '40.40.123.231' 5 failed login attempt. Invalid account 'user%2Ename' + +# failJSON: { "time": "2014-07-02T13:28:39", "match": false , "host": "12.12.123.231" } +2014:07:02-13:28:39: '12.12.123.231' successful login to 'nobody' after 1 attempts + +# failJSON: { "time": "2014-07-02T13:29:38", "match": true , "host": "1.2.3.4" } +2014:07:02-13:29:38: '1.2.3.4' 2 failed login attempts. Account 'user' via 'admin' From 3777591ab0ccb473397ed88ffe4c96d7db893a93 Mon Sep 17 00:00:00 2001 From: Marc Laporte Date: Sat, 5 Jul 2014 11:55:57 -0400 Subject: [PATCH 02/82] typo --- config/jail.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/jail.conf b/config/jail.conf index c42952d8..5c5c7651 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -10,7 +10,7 @@ # # YOU SHOULD NOT MODIFY THIS FILE. # -# It will probably be overwitten or improved in a distribution update. +# It will probably be overwritten or improved in a distribution update. # # Provide customizations in a jail.local file or a jail.d/customisation.local. # For example to change the default bantime for all jails and to enable the From 43950d8b7eb2d3b5bab0e67dfbaa3fbadda16872 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Tue, 8 Jul 2014 11:09:25 -0400 Subject: [PATCH 03/82] BF: fix path to the exim log on Debian systems (/var/log/exim4) --- config/jail.conf | 4 ++-- config/paths-common.conf | 1 + config/paths-debian.conf | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config/jail.conf b/config/jail.conf index c42952d8..0aaed995 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -501,13 +501,13 @@ logpath = %(solidpop3d_log)s [exim] port = smtp,465,submission -logpath = /var/log/exim/mainlog +logpath = %(exim_main_log)s [exim-spam] port = smtp,465,submission -logpath = /var/log/exim/mainlog +logpath = %(exim_main_log)s [kerio] diff --git a/config/paths-common.conf b/config/paths-common.conf index 008dab4e..a2c9f7af 100644 --- a/config/paths-common.conf +++ b/config/paths-common.conf @@ -22,6 +22,7 @@ syslog_user = # from /etc/audit/auditd.conf auditd_log = /var/log/audit/audit.log +exim_main_log = /var/log/exim/mainlog nginx_error_log = /var/log/nginx/error.log diff --git a/config/paths-debian.conf b/config/paths-debian.conf index 50ff948b..eff4fdae 100644 --- a/config/paths-debian.conf +++ b/config/paths-debian.conf @@ -30,6 +30,7 @@ apache_error_log = /var/log/apache2/*error.log apache_access_log = /var/log/apache2/*access.log +exim_main_log = /var/log/exim4/mainlog # was in debian squeezy but not in wheezy # /etc/proftpd/proftpd.conf (SystemLog) From 6cddc65ceeba8d5fe40ed367e5e650c60bc721b1 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Mon, 14 Jul 2014 12:15:07 -0400 Subject: [PATCH 04/82] BF: path to exim's mainlog on Fedora (Thanks Frantisek Sumsal) + changelog entry --- ChangeLog | 1 + config/paths-fedora.conf | 2 ++ 2 files changed, 3 insertions(+) diff --git a/ChangeLog b/ChangeLog index bdae885c..0309b828 100644 --- a/ChangeLog +++ b/ChangeLog @@ -36,6 +36,7 @@ ver. 0.9.1 (2014/xx/xx) - better, faster, stronger Thanks Serg G. Brester * Correct times for non-timezone date times formats during DST * Pass a copy of, not original, aInfo into actions to avoid side-effects + * Per-distribution paths to the exim's main log - New features: - Added monit filter thanks Jason H Martin. diff --git a/config/paths-fedora.conf b/config/paths-fedora.conf index 69322e43..cc574b39 100644 --- a/config/paths-fedora.conf +++ b/config/paths-fedora.conf @@ -32,4 +32,6 @@ apache_access_log = /var/log/httpd/*access_log # proftpd_log = /var/log/proftpd/auth.log # Tested and it worked out in /var/log/messages so assuming syslog_ftp for now. +exim_main_log = /var/log/exim/main.log + mysql_log = /var/lib/mysql/mysqld.log From 84b7e93a4786e89921739e61d4c97dc87eba9cab Mon Sep 17 00:00:00 2001 From: Sean DuBois Date: Fri, 11 Jul 2014 05:08:36 +0000 Subject: [PATCH 05/82] ENH: Add version command to protocol TST: Add test for version server command --- ChangeLog | 1 + THANKS | 1 + fail2ban/client/beautifier.py | 2 ++ fail2ban/protocol.py | 1 + fail2ban/server/transmitter.py | 5 ++++- fail2ban/tests/servertestcase.py | 4 ++++ man/fail2ban-client.1 | 3 +++ 7 files changed, 16 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bdae885c..d453e67b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -39,6 +39,7 @@ ver. 0.9.1 (2014/xx/xx) - better, faster, stronger - New features: - Added monit filter thanks Jason H Martin. + - fail2ban-client can fetch the running server version - Enhancements * Fail2ban-regex - add print-all-matched option. Closes gh-652 diff --git a/THANKS b/THANKS index 5752c475..656a4ad4 100644 --- a/THANKS +++ b/THANKS @@ -88,6 +88,7 @@ Rolf Fokkens Roman Gelfand Russell Odom SATO Kentaro +Sean DuBois Sebastian Arcus Serg G. Brester Sireyessire diff --git a/fail2ban/client/beautifier.py b/fail2ban/client/beautifier.py index cf17e54f..d94216c8 100644 --- a/fail2ban/client/beautifier.py +++ b/fail2ban/client/beautifier.py @@ -51,6 +51,8 @@ class Beautifier: try: if inC[0] == "ping": msg = "Server replied: " + response + elif inC[0] == "version": + msg = response elif inC[0] == "start": msg = "Jail started" elif inC[0] == "stop": diff --git a/fail2ban/protocol.py b/fail2ban/protocol.py index 8d053501..9a6ee675 100644 --- a/fail2ban/protocol.py +++ b/fail2ban/protocol.py @@ -38,6 +38,7 @@ protocol = [ ["status", "gets the current status of the server"], ["ping", "tests if the server is alive"], ["help", "return this output"], +["version", "return the server version"], ['', "LOGGING", ""], ["set loglevel ", "sets logging level to . Levels: CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG"], ["get loglevel", "gets the logging level"], diff --git a/fail2ban/server/transmitter.py b/fail2ban/server/transmitter.py index 0cd30515..39157128 100644 --- a/fail2ban/server/transmitter.py +++ b/fail2ban/server/transmitter.py @@ -28,6 +28,7 @@ import time import json from ..helpers import getLogger +from .. import version # Gets the instance of the logger. logSys = getLogger(__name__) @@ -102,7 +103,9 @@ class Transmitter: elif command[0] == "get": return self.__commandGet(command[1:]) elif command[0] == "status": - return self.status(command[1:]) + return self.status(command[1:]) + elif command[0] == "version": + return version.version raise Exception("Invalid command") def __commandSet(self, command): diff --git a/fail2ban/tests/servertestcase.py b/fail2ban/tests/servertestcase.py index 9b78fda8..fd2a22cc 100644 --- a/fail2ban/tests/servertestcase.py +++ b/fail2ban/tests/servertestcase.py @@ -37,6 +37,7 @@ from ..server.jail import Jail from ..server.jailthread import JailThread from .utils import LogCaptureTestCase from ..helpers import getLogger +from .. import version try: from ..server import filtersystemd @@ -148,6 +149,9 @@ class Transmitter(TransmitterBase): def testPing(self): self.assertEqual(self.transm.proceed(["ping"]), (0, "pong")) + def testVersion(self): + self.assertEqual(self.transm.proceed(["version"]), (0, version.version)) + def testSleep(self): t0 = time.time() self.assertEqual(self.transm.proceed(["sleep", "1"]), (0, None)) diff --git a/man/fail2ban-client.1 b/man/fail2ban-client.1 index 32580e20..e2df68ed 100644 --- a/man/fail2ban-client.1 +++ b/man/fail2ban-client.1 @@ -71,6 +71,9 @@ tests if the server is alive .TP \fBhelp\fR return this output +.TP +\fBversion\fR +return the server version .IP LOGGING .TP From 2f42ab00ad33342abc0a681e79312d19d735adb4 Mon Sep 17 00:00:00 2001 From: Florian Pelgrim Date: Thu, 17 Jul 2014 16:44:45 +0200 Subject: [PATCH 06/82] Adding vagrant support Vagrant will provide you with a default devel box where code can be tested. No further arguments like "On my system it is running. Has to be yours". I choosed a Debian wheezy based box with saltstack installed. Wheezy because it is stable and ships mostly older packages than other distros. Saltstack is used for pre-installing packeges when bringing up our box. So any requierements from fail2ban can be saved here and shipped out with git. You can add multiple other boxes. For example adding CentOS to check if the tests are passing also there. --- .gitignore | 1 + Vagrantfile | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 Vagrantfile diff --git a/.gitignore b/.gitignore index 76a33e60..a8942050 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ htmlcov *.rej *.bak __pycache__ +.vagrant/ diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 00000000..d39b6201 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,122 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + # All Vagrant configuration is done here. The most common configuration + # options are documented and commented below. For a complete reference, + # please see the online documentation at vagrantup.com. + + # Every Vagrant virtual environment requires a box to build off of. + config.vm.box = "h2ometrics/salty-wheezy64" + + # Disable automatic box update checking. If you disable this, then + # boxes will only be checked for updates when the user runs + # `vagrant box outdated`. This is not recommended. + # config.vm.box_check_update = false + + # Create a forwarded port mapping which allows access to a specific port + # within the machine from a port on the host machine. In the example below, + # accessing "localhost:8080" will access port 80 on the guest machine. + # config.vm.network "forwarded_port", guest: 80, host: 8080 + + # Create a private network, which allows host-only access to the machine + # using a specific IP. + # config.vm.network "private_network", ip: "192.168.33.10" + + # Create a public network, which generally matched to bridged network. + # Bridged networks make the machine appear as another physical device on + # your network. + # config.vm.network "public_network" + + # If true, then any SSH connections made will enable agent forwarding. + # Default value: false + # config.ssh.forward_agent = true + + # Share an additional folder to the guest VM. The first argument is + # the path on the host to the actual folder. The second argument is + # the path on the guest to mount the folder. And the optional third + # argument is a set of non-required options. + # config.vm.synced_folder "../data", "/vagrant_data" + + # Provider-specific configuration so you can fine-tune various + # backing providers for Vagrant. These expose provider-specific options. + # Example for VirtualBox: + # + # config.vm.provider "virtualbox" do |vb| + # # Don't boot with headless mode + # vb.gui = true + # + # # Use VBoxManage to customize the VM. For example to change memory: + # vb.customize ["modifyvm", :id, "--memory", "1024"] + # end + # + # View the documentation for the provider you're using for more + # information on available options. + + # Enable provisioning with CFEngine. CFEngine Community packages are + # automatically installed. For example, configure the host as a + # policy server and optionally a policy file to run: + # + # config.vm.provision "cfengine" do |cf| + # cf.am_policy_hub = true + # # cf.run_file = "motd.cf" + # end + # + # You can also configure and bootstrap a client to an existing + # policy server: + # + # config.vm.provision "cfengine" do |cf| + # cf.policy_server_address = "10.0.2.15" + # end + + # Enable provisioning with Puppet stand alone. Puppet manifests + # are contained in a directory path relative to this Vagrantfile. + # You will need to create the manifests directory and a manifest in + # the file default.pp in the manifests_path directory. + # + # config.vm.provision "puppet" do |puppet| + # puppet.manifests_path = "manifests" + # puppet.manifest_file = "site.pp" + # end + + # Enable provisioning with chef solo, specifying a cookbooks path, roles + # path, and data_bags path (all relative to this Vagrantfile), and adding + # some recipes and/or roles. + # + # config.vm.provision "chef_solo" do |chef| + # chef.cookbooks_path = "../my-recipes/cookbooks" + # chef.roles_path = "../my-recipes/roles" + # chef.data_bags_path = "../my-recipes/data_bags" + # chef.add_recipe "mysql" + # chef.add_role "web" + # + # # You may also specify custom JSON attributes: + # chef.json = { mysql_password: "foo" } + # end + + # Enable provisioning with chef server, specifying the chef server URL, + # and the path to the validation key (relative to this Vagrantfile). + # + # The Opscode Platform uses HTTPS. Substitute your organization for + # ORGNAME in the URL and validation key. + # + # If you have your own Chef Server, use the appropriate URL, which may be + # HTTP instead of HTTPS depending on your configuration. Also change the + # validation key to validation.pem. + # + # config.vm.provision "chef_client" do |chef| + # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME" + # chef.validation_key_path = "ORGNAME-validator.pem" + # end + # + # If you're using the Opscode platform, your validator client is + # ORGNAME-validator, replacing ORGNAME with your organization name. + # + # If you have your own Chef Server, the default validation client name is + # chef-validator, unless you changed the configuration. + # + # chef.validation_client_name = "ORGNAME-validator" +end From ac9fa906258e53509b5d5385008d1f4e53b40e5a Mon Sep 17 00:00:00 2001 From: Sean DuBois Date: Thu, 17 Jul 2014 21:57:52 +0000 Subject: [PATCH 07/82] BF: Round timeofban before inserting into the persistant database --- fail2ban/server/database.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fail2ban/server/database.py b/fail2ban/server/database.py index 51161911..47f1a485 100644 --- a/fail2ban/server/database.py +++ b/fail2ban/server/database.py @@ -368,7 +368,7 @@ class Fail2BanDb(object): #TODO: Implement data parts once arbitrary match keys completed cur.execute( "INSERT INTO bans(jail, ip, timeofban, data) VALUES(?, ?, ?, ?)", - (jail.name, ticket.getIP(), ticket.getTime(), + (jail.name, ticket.getIP(), round(ticket.getTime()), {"matches": ticket.getMatches(), "failures": ticket.getAttempt()})) From 5471e99ebe3065120ff148260bc55e202b7feeed Mon Sep 17 00:00:00 2001 From: leftyfb Date: Thu, 17 Jul 2014 22:54:30 -0400 Subject: [PATCH 08/82] Added cloudflare action --- config/action.d/cloudflare.conf | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 config/action.d/cloudflare.conf diff --git a/config/action.d/cloudflare.conf b/config/action.d/cloudflare.conf new file mode 100644 index 00000000..ead0d23e --- /dev/null +++ b/config/action.d/cloudflare.conf @@ -0,0 +1,53 @@ +# +# Author: Mike Rushton +# +# $Revision$ +# + +[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: <ip> IP address +# <failures> number of failures +# <time> unix timestamp of the ban time +# Values: CMD +# +actionban = curl -s "https://www.cloudflare.com/api.html?a=ban&key=&u=&tkn=" +# Option: actionunban +# Notes.: command executed when unbanning an IP. Take care that the +# command is executed with Fail2Ban user rights. +# Tags: <ip> IP address +# <failures> number of failures +# <time> unix timestamp of the ban time +# Values: CMD +# +actionunban = curl -s "https://www.cloudflare.com/api.html?a=nul&key=&u=&tkn=" + + +[Init] + +# Default Cloudflare API token +cftoken = + +# Default Cloudflare username +cfuser = From cba570cabdb8cc04f18ab7c46a0044364590772a Mon Sep 17 00:00:00 2001 From: leftyfb Date: Thu, 17 Jul 2014 23:49:35 -0400 Subject: [PATCH 09/82] Updated comments --- config/action.d/cloudflare.conf | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/config/action.d/cloudflare.conf b/config/action.d/cloudflare.conf index ead0d23e..790a00a9 100644 --- a/config/action.d/cloudflare.conf +++ b/config/action.d/cloudflare.conf @@ -1,7 +1,9 @@ # # Author: Mike Rushton # -# $Revision$ +# Referenced from from http://www.normyee.net/blog/2012/02/02/adding-cloudflare-support-to-fail2ban by NORM YEE +# +# To get your Cloudflare API key: https://www.cloudflare.com/my-account # [Definition] @@ -27,18 +29,18 @@ actioncheck = # Option: actionban # Notes.: command executed when banning an IP. Take care that the # command is executed with Fail2Ban user rights. -# Tags: <ip> IP address -# <failures> number of failures -# <time> unix timestamp of the ban time +# Tags: IP address +# number of failures +#