mirror of https://github.com/fail2ban/fail2ban
Merge commit '0.8.8-276-g5e1d8b0' into debian
* commit '0.8.8-276-g5e1d8b0': (103 commits) ENH: logs/sshd -- have ":" after [daemon] (other uses are uncommon) ENH: logs/sshd -- use example.com as the resolved hostname in sample log lines ENH: filter.d/sshd.conf -- allow for trailing "via IP" in logs ENH: Removed unused log line ENH: logrotate file ENH: some form of logrotate based on what distros are doing DOC: macports distribution of fail2ban TST: test case for <br> tags in action DOC: credits for BSD ssh filter changes EHN: enhance sshd filter for bsd. DOC: purge of svn tags Slight tune up of changelog entry (treeish change due to squashing) fixed test date thx to steven tight control of the filter for ASSP as yaroslav wishes as daniel desires changed from DateASSPlike class to DateStrptime fixed little things added new date format support for ASSP SMTP Proxy Forgotten Changelog entry for "is None" changes ...pull/808/head
commit
d59c41197e
11
.travis.yml
11
.travis.yml
|
@ -5,7 +5,14 @@ python:
|
|||
- "2.5"
|
||||
- "2.6"
|
||||
- "2.7"
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
install:
|
||||
- "pip install pyinotify"
|
||||
- pip install pyinotify
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then sudo apt-get install -qq python-gamin; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then pip install -q coveralls; fi
|
||||
script:
|
||||
- python ./fail2ban-testcases
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then export PYTHONPATH="$PYTHONPATH:/usr/share/pyshared:/usr/lib/pyshared/python2.7"; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then coverage run --rcfile=.travis_coveragerc fail2ban-testcases; else python ./fail2ban-testcases; fi
|
||||
after_success:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then coveralls; fi
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
[run]
|
||||
branch = True
|
||||
omit =
|
||||
/usr/*
|
||||
/home/travis/virtualenv/*
|
114
ChangeLog
114
ChangeLog
|
@ -4,28 +4,132 @@
|
|||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||
|
||||
================================================================================
|
||||
Fail2Ban (version 0.8.8) 2012/12/06
|
||||
Fail2Ban (version 0.8.9) 2013/04/XX
|
||||
================================================================================
|
||||
|
||||
ver. 0.8.9 (2013/04/XX) - wanna-be-stable
|
||||
----------
|
||||
|
||||
Although primarily a bugfix release, it incorporates many new
|
||||
enhancements, few new features, but more importantly -- quite extended
|
||||
tests battery with current 94% coverage. This release incorporates
|
||||
more than a 100 of non-merge commits from 14 contributors (sorted by
|
||||
number of commits): Yaroslav Halchenko, Daniel Black, Steven Hiscocks,
|
||||
ArndRa, hamilton5, pigsyn, Erwan Ben Souiden, Michael Gebetsroither,
|
||||
Orion Poplawski, Artur Penttinen, sebres, Nicolas Collignon, Pascal
|
||||
Borreli, blotus:
|
||||
|
||||
- Fixes:
|
||||
Yaroslav Halchenko
|
||||
* [6f4dad46] Documentation python-2.4 is the minimium version.
|
||||
* [1eb23cf8] do not rely on scripts being under /usr -- might differ eg on
|
||||
Fedora. Closes gh-112. Thanks to Camusensei for the bug report.
|
||||
* [bf4d4af1] Changes for atomic writes. Thanks to Steven Hiscocks for
|
||||
insight. Closes gh-103.
|
||||
* [ab044b75] delay check for the existence of config directory until read.
|
||||
* [3b4084d4] fixing up for handling of TAI64N timestamps.
|
||||
* [154aa38e] do not shutdown logging until all jails stop.
|
||||
* [f2156604] pyinotify -- monitor IN_MOVED_TO events. Closes gh-184.
|
||||
Thanks to Jon Foster for report and troubleshooting.
|
||||
Orion Poplawski
|
||||
* [e4aedfdc00] pyinotify - use bitwise op on masks and do not try tracking
|
||||
newly created directories.
|
||||
Nicolas Collignon
|
||||
* [39667ff6] Avoid leaking file descriptors. Closes gh-167.
|
||||
Sergey Brester
|
||||
* [b6bb2f88 and d17b4153] invalid date recognition, irregular because of
|
||||
sorting template list.
|
||||
Steven Hiscocks
|
||||
* [7a442f07] When changing log target with python2.{4,5} handle KeyError.
|
||||
Closes gh-147, gh-148.
|
||||
* [b6a68f51] Fix delaction on server side. Closes gh-124.
|
||||
Daniel Black
|
||||
* [f0610c01] Allow more that a one word command when changing and Action via
|
||||
the fail2ban-client. Closes gh-134.
|
||||
* [945ad3d9] Fix dates on email actions to work in different locals. Closes
|
||||
gh-70. Thanks to iGeorgeX for the idea.
|
||||
blotus
|
||||
* [96eb8986] ' and " should also be escaped in action tags Closes gh-109
|
||||
- New features:
|
||||
Yaroslav Halchenko
|
||||
* [9ba27353] Add support for jail.d/{confilefile} and fail2ban.d/{configfile}
|
||||
to provide additional flexibility to system adminstrators. Thanks to
|
||||
beilber for the idea. Closes gh-114.
|
||||
* [3ce53e87] Add exim filter.
|
||||
Erwan Ben Souiden
|
||||
* [d7d5228] add nagios integration documentation and script to ensure
|
||||
fail2ban is running. Closes gh-166.
|
||||
Artur Penttinen
|
||||
* [29d0df5] Add mysqld filter. Closes gh-152.
|
||||
ArndRaphael Brandes
|
||||
* [bba3fd8] Add Sogo filter. Closes gh-117.
|
||||
Michael Gebetsriother
|
||||
* [f9b78ba] Add action route to block at routing level.
|
||||
Teodor Micu & Yaroslav Halchenko
|
||||
* [5f2d383] Add roundcube auth filter. Closes Debian bug #699442.
|
||||
Daniel Black
|
||||
* [be06b1b] Add action for iptables-ipsets. Closes gh-102.
|
||||
Soulard Morgan
|
||||
* [f336d9f] Add filter for webmin. Closes gh-99.
|
||||
- Enhancements:
|
||||
Enrico Labedzki
|
||||
* [24a8d07] Added new date format for ASSP SMTP Proxy.
|
||||
Steven Hiscocks
|
||||
* [3d6791f] Ensure restart of Actions after a check fails occurs
|
||||
consistently. Closes gh-172.
|
||||
* [MANY] Improvements to test cases, travis, and code coverage (coveralls).
|
||||
* [b36835f] Add get cinfo to fail2ban-client. Closes gh-124.
|
||||
* [ce3ab34] Added ability to specify PID file.
|
||||
Orion Poplawski
|
||||
* [ddebcab] Enhance fail2ban.service definition dependencies and Pidfile.
|
||||
Closes gh-142.
|
||||
Yaroslav Halchenko
|
||||
* [MANY] Lots of improvements to log messages, man pages and test cases.
|
||||
* [91d5736] Postfix filter improvements - empty helo, from and rcpt to.
|
||||
Closes gh-126. Bug report by Michael Heuberger.
|
||||
* [40c5a2d] adding more of diagnostic messages into -client while starting
|
||||
the daemon.
|
||||
* [8e63d4c] Compare against None with 'is' instead of '=='.
|
||||
Daniel Black
|
||||
* [3aeb1a9] Add jail.conf manual page. Closes gh-143.
|
||||
* [MANY] man page edits.
|
||||
* [7cd6dab] Added help command to fail2ban-client.
|
||||
* [c8c7b0b,23bbc60] Better logging of log file read errors.
|
||||
* [3665e6d] Added code coverage to development process.
|
||||
* [41b9f7b,32d10e9,39750b8] More complete ssh filter rules to match openssh
|
||||
source. Also include BSD changes.
|
||||
* [1d9abd1] Action files can have tags in definition that refer to other
|
||||
tags.
|
||||
Pascal Borreli
|
||||
* [a2b29b4] Fixed lots of typos in config files and documentation.
|
||||
hamilton5
|
||||
* [7ede1e8] Update dovecot filter config.
|
||||
Romain Riviere
|
||||
* [0ac8746] Enhance named-refused filter for views.
|
||||
|
||||
Special Kudos also go to Fabian Wenk, Arturo 'Buanzo' Busleiman, Tom
|
||||
Hendrikx and other TBN heroes supporting users on fail2ban-users
|
||||
mailing list and IRC.
|
||||
|
||||
ver. 0.8.8 (2012/12/06) - stable
|
||||
----------
|
||||
- Fixes:
|
||||
Alan Jenkins
|
||||
* [8c38907] Removed 'POSSIBLE BREAK-IN ATTEMPT' from sshd filter to avoid
|
||||
banning due to misconfigured DNS. Close gh-64
|
||||
banning due to misconfigured DNS. Closes gh-64
|
||||
Yaroslav Halchenko
|
||||
* [83109bc] IMPORTANT: escape the content of <matches> (if used in
|
||||
custom action files) since its value could contain arbitrary
|
||||
symbols. Thanks for discovery go to the NBS System security
|
||||
team
|
||||
* [0935566,5becaf8] Various python 2.4 and 2.5 compatibility fixes. Close gh-83
|
||||
* [0935566,5becaf8] Various python 2.4 and 2.5 compatibility fixes. Closes gh-83
|
||||
* [b159eab] do not enable pyinotify backend if pyinotify < 0.8.3
|
||||
* [37a2e59] store IP as a base, non-unicode str to avoid spurious messages
|
||||
in the console. Close gh-91
|
||||
in the console. Closes gh-91
|
||||
- New features:
|
||||
David Engeset
|
||||
* [2d672d1,6288ec2] 'unbanip' command for the client + avoidance of touching
|
||||
the log file to take 'banip' or 'unbanip' in effect. Close gh-81, gh-86
|
||||
the log file to take 'banip' or 'unbanip' in effect. Closes gh-81, gh-86
|
||||
Yaroslav Halchenko
|
||||
- Enhancements:
|
||||
* [2d66f31] replaced uninformative "Invalid command" message with warning log
|
||||
|
|
69
DEVELOP
69
DEVELOP
|
@ -21,6 +21,19 @@ would like to add to Fail2Ban, the best way to do so it to use the GitHub Pull
|
|||
Request feature. You can find more details on the Fail2Ban wiki
|
||||
(http://www.fail2ban.org/wiki/index.php/Get_Involved)
|
||||
|
||||
Pull Requests
|
||||
=============
|
||||
|
||||
When submitting pull requests on GitHub we ask you to:
|
||||
* Clearly describe the problem you're solving;
|
||||
* Don't introduce regressions that will make it hard for systems adminstrators
|
||||
to update;
|
||||
* If adding a major feature rebase your changes on master and get to a single commit;
|
||||
* Include test cases (see below);
|
||||
* Include sample logs (if relevant);
|
||||
* Include a change to the relevant section of the ChangeLog; and
|
||||
* Include yourself in THANKS if not already there.
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
|
@ -249,10 +262,53 @@ Takes care about executing start/check/ban/unban/stop commands
|
|||
Releasing
|
||||
=========
|
||||
|
||||
# Check distribution patches and see if they can be included
|
||||
|
||||
* https://apps.fedoraproject.org/packages/fail2ban/sources
|
||||
* http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/net-analyzer/fail2ban/
|
||||
* http://svnweb.freebsd.org/ports/head/security/py-fail2ban/
|
||||
* https://build.opensuse.org/package/show?package=fail2ban&project=openSUSE%3AFactory
|
||||
* http://sophie.zarb.org/sources/fail2ban (Mageia)
|
||||
* https://trac.macports.org/browser/trunk/dports/security/fail2ban
|
||||
|
||||
# Check distribution outstanding bugs
|
||||
|
||||
* https://github.com/fail2ban/fail2ban/issues?sort=updated&state=open
|
||||
* http://bugs.debian.org/cgi-bin/pkgreport.cgi?dist=unstable;package=fail2ban
|
||||
* http://bugs.sabayon.org/buglist.cgi?quicksearch=net-analyzer%2Ffail2ban
|
||||
* 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
|
||||
|
||||
# Provide a release sample to distributors
|
||||
|
||||
* Debian: Yaroslav Halchenko <debian@onerussian.com>
|
||||
http://packages.qa.debian.org/f/fail2ban.html
|
||||
* FreeBSD: Christoph Theis theis@gmx.at>, Nick Hilliard <nick@foobar.org>
|
||||
http://svnweb.freebsd.org/ports/head/security/py-fail2ban/Makefile?view=markup
|
||||
* Fedora: Axel Thimm <Axel.Thimm@atrpms.net>
|
||||
https://apps.fedoraproject.org/packages/fail2ban
|
||||
* Gentoo: netmon@gentoo.org
|
||||
http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/net-analyzer/fail2ban/metadata.xml?view=markup
|
||||
* openSUSE: Stephan Kulow <coolo@suse.com>
|
||||
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
|
||||
|
||||
# Wait for feedback from distributors
|
||||
|
||||
# Ensure the version is correct in ./common/version.py
|
||||
|
||||
# Add/finalize the corresponding entry in the ChangeLog
|
||||
|
||||
To generate a list of committers use e.g.
|
||||
|
||||
git shortlog -sn 0.8.8.. | 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 )
|
||||
|
@ -275,4 +331,15 @@ Releasing
|
|||
|
||||
# Email users and development list of release
|
||||
|
||||
TODO notifying distributors etc.
|
||||
# notify distributors
|
||||
|
||||
Post Release
|
||||
============
|
||||
|
||||
Add the following to the top of the ChangeLog
|
||||
|
||||
ver. 0.8.9 (2013/XX/XXX) - wanna-be-stable
|
||||
- Fixes
|
||||
- New Features
|
||||
- Enhancements
|
||||
|
||||
|
|
3
MANIFEST
3
MANIFEST
|
@ -1,4 +1,4 @@
|
|||
README
|
||||
README.md
|
||||
ChangeLog
|
||||
TODO
|
||||
THANKS
|
||||
|
@ -139,6 +139,7 @@ files/macosx-initd
|
|||
files/solaris-fail2ban.xml
|
||||
files/solaris-svc-fail2ban
|
||||
files/suse-initd
|
||||
files/fail2ban-logrotate
|
||||
files/cacti/fail2ban_stats.sh
|
||||
files/cacti/cacti_host_template_fail2ban.xml
|
||||
files/cacti/README
|
||||
|
|
95
README
95
README
|
@ -1,95 +0,0 @@
|
|||
__ _ _ ___ _
|
||||
/ _|__ _(_) |_ ) |__ __ _ _ _
|
||||
| _/ _` | | |/ /| '_ \/ _` | ' \
|
||||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||
|
||||
================================================================================
|
||||
Fail2Ban (version 0.8.8) 2012/07/31
|
||||
================================================================================
|
||||
|
||||
Fail2Ban scans log files like /var/log/pwdfail and bans IP that makes too many
|
||||
password failures. It updates firewall rules to reject the IP address. These
|
||||
rules can be defined by the user. Fail2Ban can read multiple log files such as
|
||||
sshd or Apache web server ones.
|
||||
|
||||
This README is a quick introduction to Fail2ban. More documentation, FAQ, HOWTOs
|
||||
are available on the project website: http://www.fail2ban.org
|
||||
|
||||
Installation:
|
||||
-------------
|
||||
|
||||
Required:
|
||||
>=python-2.3 (http://www.python.org)
|
||||
|
||||
Optional:
|
||||
pyinotify:
|
||||
>=linux-2.6.13
|
||||
>=python-2.4
|
||||
>=pyinotify-0.8.3 (https://github.com/seb-m/pyinotify)
|
||||
Gamin:
|
||||
>=gamin-0.0.21 (http://www.gnome.org/~veillard/gamin)
|
||||
|
||||
To install, just do:
|
||||
|
||||
> tar xvfj fail2ban-0.8.8.tar.bz2
|
||||
> cd fail2ban-0.8.8
|
||||
> python setup.py install
|
||||
|
||||
This will install Fail2Ban into /usr/share/fail2ban. The executable scripts are
|
||||
placed into /usr/bin.
|
||||
|
||||
It is possible that Fail2ban is already packaged for your distribution. In this
|
||||
case, you should use it.
|
||||
|
||||
Fail2Ban should be correctly installed now. Just type:
|
||||
|
||||
> fail2ban-client -h
|
||||
|
||||
to see if everything is alright. You should always use fail2ban-client and never
|
||||
call fail2ban-server directly.
|
||||
|
||||
Configuration:
|
||||
--------------
|
||||
|
||||
You can configure Fail2ban using the files in /etc/fail2ban. It is possible to
|
||||
configure the server using commands sent to it by fail2ban-client. The available
|
||||
commands are described in the man page of fail2ban-client. Please refer to it or
|
||||
to the website: http://www.fail2ban.org
|
||||
|
||||
Contact:
|
||||
--------
|
||||
|
||||
Website: http://www.fail2ban.org
|
||||
|
||||
You need some new features, you found bugs: visit
|
||||
https://github.com/fail2ban/fail2ban/issues
|
||||
and if your issue is not yet known -- file a bug report.
|
||||
|
||||
If you would like to troubleshoot or discuss: join the mailing list
|
||||
https://lists.sourceforge.net/lists/listinfo/fail2ban-users
|
||||
|
||||
If you just appreciate this program: send kudos to the original author
|
||||
(Cyril Jaquier: <cyril.jaquier@fail2ban.org>) or the mailing list
|
||||
https://lists.sourceforge.net/lists/listinfo/fail2ban-users
|
||||
|
||||
|
||||
Thanks:
|
||||
-------
|
||||
|
||||
See THANKS file.
|
||||
|
||||
License:
|
||||
--------
|
||||
|
||||
Fail2Ban is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Fail2Ban is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
Fail2Ban; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110, USA
|
|
@ -0,0 +1,141 @@
|
|||
# vim:tw=80:ft=txt
|
||||
|
||||
README FOR SOLARIS INSTALLATIONS
|
||||
|
||||
By Roy Sigurd Karlsbakk <roy@karlsbakk.net>
|
||||
|
||||
ABOUT
|
||||
|
||||
This readme is meant for those wanting to install fail2ban on Solaris 10,
|
||||
OpenSolaris, OpenIndiana etc. To some degree it may as well be useful for
|
||||
users of older Solaris versions and Nexenta, but don't rely on it.
|
||||
|
||||
READ ME FIRST
|
||||
|
||||
If I use the term Solaris, I am talking about any Solaris dialect, that is, the
|
||||
official Sun/Oracle ones or derivates. If I describe an OS as
|
||||
"OpenSolaris-based", it means it's either OpenSolaris, OpenIndiana or one of the
|
||||
other, but /not/ the Nexenta family, since this only uses the OpenSolaris/
|
||||
IllumOS kernel and not the userland. If I say Solaris 10, I mean Solaris 10 and
|
||||
perhaps, if you're lucky and have some good gods on your side, it may also apply
|
||||
to Solaris 9 or even 8 and hopefully in the new Solaris 11 whenever that may be
|
||||
released. Quoted lines of code, settings et cetera are indented with two spaces.
|
||||
This does _not_ mean you should use that indentation, especially in config files
|
||||
where they can be harmful. Optional settings are prefixed with OPT: while
|
||||
required settings are prefixed with REQ:. If no prefix is found, regard it as a
|
||||
required setting.
|
||||
|
||||
INSTALLATION ON SOLARIS
|
||||
|
||||
The installation is straight forward on Solaris as well as on linux/bsd/etc.
|
||||
./setup.py install installs the general packages in /usr/bin on OpenSolaris-
|
||||
based distros or (at least on this box) under /usr/sfw/bin on Solaris 10. In
|
||||
the files/ directory you will find the file solaris-fail2ban.xml containing the
|
||||
Solaris service. To install this, run the following command as root (or with
|
||||
sudo):
|
||||
|
||||
svccfg import files/solaris-fail2ban.xml
|
||||
|
||||
This should normally without giving an error. If you get an error, deal with it,
|
||||
and please post any relevant info (or fixes?) to the fail2ban mailing list.
|
||||
Next install the service handler - copy the script in and allow it to be executed:
|
||||
|
||||
cp files/solaris-svc-fail2ban /lib/svc/method/svc-fail2ban
|
||||
chmod +x /lib/svc/method/svc-fail2ban
|
||||
|
||||
CONFIGURE SYSLOG
|
||||
|
||||
For some reason, a default Solaris installation does not log ssh login attempts,
|
||||
and since fail2ban works by monitoring logs, enabling this logging is rather
|
||||
important for it to work. To enable this, edit /etc/syslog.conf and add a line
|
||||
at the end:
|
||||
|
||||
auth.info /var/adm/auth.log
|
||||
|
||||
Save the file and exit, and run
|
||||
|
||||
touch /var/adm/auth.log
|
||||
|
||||
The Solaris system logger will _not_ create a non-existing file. Now, restart
|
||||
the system logger.
|
||||
|
||||
svcadm restart system-log
|
||||
|
||||
Try to ssh into localhost with ssh asdf@localhost and enter an invalid password.
|
||||
Make sure this is logged in the above file. When done, you may configure
|
||||
fail2ban.
|
||||
|
||||
FAIL2BAN CONFIGURATION
|
||||
|
||||
OPT: Create /etc/fail2ban/fail2ban.local containing:
|
||||
|
||||
# Fail2Ban main configuration file
|
||||
#
|
||||
# Comments: use '#' for comment lines and ';' for inline comments
|
||||
#
|
||||
# Changes: in most of the cases you should not modify this
|
||||
# file, but provide customizations in fail2ban.local file, e.g.:
|
||||
#
|
||||
# [Definition]
|
||||
# loglevel = 4
|
||||
#
|
||||
[Definition]
|
||||
|
||||
# Option: logtarget
|
||||
# Notes.: Set the log target. This could be a file, SYSLOG, STDERR or STDOUT.
|
||||
# Only one log target can be specified.
|
||||
# If you change logtarget from the default value and you are
|
||||
# using logrotate -- also adjust or disable rotation in the
|
||||
# corresponding configuration file
|
||||
# (e.g. /etc/logrotate.d/fail2ban on Debian systems)
|
||||
# Values: STDOUT STDERR SYSLOG file Default: /var/log/fail2ban.log
|
||||
#
|
||||
logtarget = /var/adm/fail2ban.log
|
||||
|
||||
|
||||
REQ: Create /etc/fail2ban/jail.local containing:
|
||||
|
||||
[ssh-tcpwrapper]
|
||||
|
||||
enabled = true
|
||||
filter = sshd
|
||||
action = hostsdeny
|
||||
sendmail-whois[name=SSH, dest=you@example.com]
|
||||
ignoreregex = for myuser from
|
||||
logpath = /var/adm/auth.log
|
||||
|
||||
Set the sendmail dest address to something useful or drop the line to stop it spamming you.
|
||||
Set 'myuser' to your username to avoid banning yourself or drop it.
|
||||
|
||||
START (OR RESTART) FAIL2BAN
|
||||
|
||||
Enable the fail2ban service with
|
||||
|
||||
svcadm enable fail2ban
|
||||
|
||||
When done, check that all services are running well
|
||||
|
||||
svcs -xv
|
||||
|
||||
GOTCHAS AND FIXMES
|
||||
|
||||
* It seems the installation may be starting fail2ban automatically. If this is
|
||||
done, fail2ban will not start, but no errors will be returned from svcs
|
||||
(above). Check if it's running with 'ps -ef | grep fail2ban' and manually kill
|
||||
the PID if it is. Re-enable fail2ban and try again
|
||||
|
||||
svcadm disable fail2ban
|
||||
svcadm enable fail2ban
|
||||
|
||||
* If svcs -xv says that fail2ban failed to start or svcs says it's in maintenance mode
|
||||
chcek /var/svc/log/network-fail2ban:default.log for clues.
|
||||
Check permissions on /var/adm, /var/adm/auth.log /var/adm/fail2ban.log and /var/run/fail2ban
|
||||
You may need to:
|
||||
|
||||
sudo mkdir /var/run/fail2ban
|
||||
|
||||
* Fail2ban adds lines like these to /etc/hosts.deny:
|
||||
|
||||
ALL: 1.2.3.4
|
||||
|
||||
wouldn't it be better to just block sshd?
|
|
@ -0,0 +1,100 @@
|
|||
__ _ _ ___ _
|
||||
/ _|__ _(_) |_ ) |__ __ _ _ _
|
||||
| _/ _` | | |/ /| '_ \/ _` | ' \
|
||||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||
v0.8.8 2012/07/31
|
||||
|
||||
## Fail2Ban: ban hosts that cause multiple authentication errors
|
||||
|
||||
Fail2Ban scans log files like /var/log/pwdfail and bans IP that makes too many
|
||||
password failures. It updates firewall rules to reject the IP address. These
|
||||
rules can be defined by the user. Fail2Ban can read multiple log files such as
|
||||
sshd or Apache web server ones.
|
||||
|
||||
This README is a quick introduction to Fail2ban. More documentation, FAQ, HOWTOs
|
||||
are available in fail2ban(1) manpage and on the website http://www.fail2ban.org
|
||||
|
||||
Installation:
|
||||
-------------
|
||||
|
||||
**It is possible that Fail2ban is already packaged for your distribution. In
|
||||
this case, you should use it instead.**
|
||||
|
||||
Required:
|
||||
- [Python >= 2.4](http://www.python.org)
|
||||
|
||||
Optional:
|
||||
- [pyinotify >= 0.8.3](https://github.com/seb-m/pyinotify)
|
||||
- Linux >= 2.6.13
|
||||
- [gamin >= 0.0.21](http://www.gnome.org/~veillard/gamin)
|
||||
|
||||
To install, just do:
|
||||
|
||||
tar xvfj fail2ban-0.8.8.tar.bz2
|
||||
cd fail2ban-0.8.8
|
||||
python setup.py install
|
||||
|
||||
This will install Fail2Ban into /usr/share/fail2ban. The executable scripts are
|
||||
placed into /usr/bin, and configuration under /etc/fail2ban.
|
||||
|
||||
Fail2Ban should be correctly installed now. Just type:
|
||||
|
||||
fail2ban-client -h
|
||||
|
||||
to see if everything is alright. You should always use fail2ban-client and
|
||||
never call fail2ban-server directly.
|
||||
|
||||
Configuration:
|
||||
--------------
|
||||
|
||||
You can configure Fail2Ban using the files in /etc/fail2ban. It is possible to
|
||||
configure the server using commands sent to it by fail2ban-client. The
|
||||
available commands are described in the fail2ban-client(1) manpage. Also see
|
||||
fail2ban(1) manpage for further references and find even more documentation on
|
||||
the website: http://www.fail2ban.org
|
||||
|
||||
Code status:
|
||||
------------
|
||||
|
||||
* [![tests status](https://secure.travis-ci.org/fail2ban/fail2ban.png)](https://travis-ci.org/fail2ban/fail2ban) travis-ci.org (master branch)
|
||||
|
||||
* [![Coverage Status](https://coveralls.io/repos/fail2ban/fail2ban/badge.png?branch=master)](https://coveralls.io/r/fail2ban/fail2ban)
|
||||
|
||||
Contact:
|
||||
--------
|
||||
|
||||
### You need some new features, you found bugs?
|
||||
visit [Issues](https://github.com/fail2ban/fail2ban/issues)
|
||||
and if your issue is not yet known -- file a bug report.
|
||||
|
||||
### You would like to troubleshoot or discuss?
|
||||
join the [mailing list](https://lists.sourceforge.net/lists/listinfo/fail2ban-users)
|
||||
|
||||
### You would like to contribute (new filters/actions/code/documentation)?
|
||||
send a pull request
|
||||
|
||||
### You just appreciate this program:
|
||||
send kudos to the original author ([Cyril Jaquier](mailto: Cyril Jaquier <cyril.jaquier@fail2ban.org>)
|
||||
or better to the [mailing list](https://lists.sourceforge.net/lists/listinfo/fail2ban-users)
|
||||
since Fail2Ban is "community-driven" for years now.
|
||||
|
||||
Thanks:
|
||||
-------
|
||||
|
||||
See [THANKS](https://github.com/fail2ban/fail2ban/blob/master/THANKS) file.
|
||||
|
||||
License:
|
||||
--------
|
||||
|
||||
Fail2Ban is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Fail2Ban is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
Fail2Ban; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110, USA
|
1
THANKS
1
THANKS
|
@ -16,6 +16,7 @@ Daniel B. Cid
|
|||
Daniel Black
|
||||
David Nutter
|
||||
Eric Gerbier
|
||||
Enrico Labedzki
|
||||
Guillaume Delvit
|
||||
Hanno 'Rince' Wagner
|
||||
Iain Lea
|
||||
|
|
2
TODO
2
TODO
|
@ -13,6 +13,8 @@ Legend:
|
|||
# partially done
|
||||
* done
|
||||
|
||||
- more detailed explaination in DEVELOP for new developers (eg. howto build this HEX numbers in ChangeLog)
|
||||
|
||||
- Run tests though all filters/examples files - (see sshd example file) as unit
|
||||
test
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
|
|
|
@ -56,10 +56,10 @@ class Beautifier:
|
|||
msg = "Jail started"
|
||||
elif inC[0] == "stop":
|
||||
if len(inC) == 1:
|
||||
if response == None:
|
||||
if response is None:
|
||||
msg = "Shutdown successful"
|
||||
else:
|
||||
if response == None:
|
||||
if response is None:
|
||||
msg = "Jail stopped"
|
||||
elif inC[0] == "add":
|
||||
msg = "Added jail " + response
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
# Author: Yaroslav Halchenko
|
||||
# Modified: Cyril Jaquier
|
||||
# $Revision$
|
||||
|
||||
__author__ = 'Yaroslav Halhenko'
|
||||
__revision__ = '$Revision$'
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
# Modified by: Yaroslav Halchenko (SafeConfigParserWithIncludes)
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
|
@ -46,15 +45,15 @@ class ConfigReader(SafeConfigParserWithIncludes):
|
|||
def setBaseDir(self, basedir):
|
||||
if basedir is None:
|
||||
basedir = ConfigReader.DEFAULT_BASEDIR # stock system location
|
||||
if not (os.path.exists(basedir) and os.access(basedir, os.R_OK | os.X_OK)):
|
||||
raise ValueError("Base configuration directory %s either does not exist "
|
||||
"or is not accessible" % basedir)
|
||||
self._basedir = basedir.rstrip('/')
|
||||
|
||||
def getBaseDir(self):
|
||||
return self._basedir
|
||||
|
||||
def read(self, filename):
|
||||
if not os.path.exists(self._basedir):
|
||||
raise ValueError("Base configuration directory %s does not exist "
|
||||
% self._basedir)
|
||||
basename = os.path.join(self._basedir, filename)
|
||||
logSys.debug("Reading configs for %s under %s " % (basename, self._basedir))
|
||||
config_files = [ basename + ".conf",
|
||||
|
@ -65,27 +64,20 @@ class ConfigReader(SafeConfigParserWithIncludes):
|
|||
|
||||
# possible further customizations under a .conf.d directory
|
||||
config_dir = basename + '.d'
|
||||
if os.path.exists(config_dir):
|
||||
if os.path.isdir(config_dir) and os.access(config_dir, os.X_OK | os.R_OK):
|
||||
# files must carry .conf suffix as well
|
||||
config_files += sorted(glob.glob('%s/*.conf' % config_dir))
|
||||
else:
|
||||
logSys.warn("%s exists but not a directory or not accessible"
|
||||
% config_dir)
|
||||
config_files += sorted(glob.glob('%s/*.conf' % config_dir))
|
||||
|
||||
# check if files are accessible, warn if any is not accessible
|
||||
# and remove it from the list
|
||||
config_files_accessible = []
|
||||
for f in config_files:
|
||||
if os.access(f, os.R_OK):
|
||||
config_files_accessible.append(f)
|
||||
else:
|
||||
logSys.warn("%s exists but not accessible - skipping" % f)
|
||||
|
||||
if len(config_files_accessible):
|
||||
if len(config_files):
|
||||
# at least one config exists and accessible
|
||||
SafeConfigParserWithIncludes.read(self, config_files_accessible)
|
||||
return True
|
||||
logSys.debug("Reading config files: " + ', '.join(config_files))
|
||||
config_files_read = SafeConfigParserWithIncludes.read(self, config_files)
|
||||
missed = [ cf for cf in config_files if cf not in config_files_read ]
|
||||
if missed:
|
||||
logSys.error("Could not read config files: " + ', '.join(missed))
|
||||
if config_files_read:
|
||||
return True
|
||||
logSys.error("Found no accessible config files for %r under %s" %
|
||||
( filename, self.getBaseDir() ))
|
||||
return False
|
||||
else:
|
||||
logSys.error("Found no accessible config files for %r " % filename
|
||||
+ (["under %s" % self.getBaseDir(),
|
||||
|
@ -113,7 +105,7 @@ class ConfigReader(SafeConfigParserWithIncludes):
|
|||
v = self.getint(sec, option[1])
|
||||
else:
|
||||
v = self.get(sec, option[1])
|
||||
if not pOptions == None and option[1] in pOptions:
|
||||
if not pOptions is None and option[1] in pOptions:
|
||||
continue
|
||||
values[option[1]] = v
|
||||
except NoSectionError, e:
|
||||
|
@ -121,7 +113,7 @@ class ConfigReader(SafeConfigParserWithIncludes):
|
|||
logSys.error(e)
|
||||
values[option[1]] = option[2]
|
||||
except NoOptionError:
|
||||
if not option[2] == None:
|
||||
if not option[2] is None:
|
||||
logSys.warn("'%s' not defined in '%s'. Using default one: %r"
|
||||
% (option[1], sec, option[2]))
|
||||
values[option[1]] = option[2]
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
# Author: Cyril Jaquier
|
||||
# Author: Arturo 'Buanzo' Busleiman
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier, Yaroslav Halchenko"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2012 Yaroslav Halchenko"
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
# configured at DShield), and <lines>/<minreportinterval>/<maxbufferage> (to
|
||||
# configure how often the buffer is flushed).
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
[Definition]
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
@ -40,7 +39,7 @@ actionban = IP=<ip> &&
|
|||
# Tags: See jail.conf(5) man page
|
||||
# Values: CMD
|
||||
#
|
||||
actionunban = IP=<ip> && sed -i.old /ALL:\ $IP/d <file>
|
||||
actionunban = IP=<ip> && sed /ALL:\ $IP/d <file> > <file>.new && mv <file>.new <file>
|
||||
|
||||
[Init]
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
# Author: Nick Munger
|
||||
# Modified by: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
# Modified: Yaroslav O. Halchenko <debian@onerussian.com>
|
||||
# made active on all ports from original iptables.conf
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
# make "fail2ban-<name>-log" chain to log and drop
|
||||
# insert a jump to fail2ban-<name> from -I <chain> if proto/port match
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
# Modified by Yaroslav Halchenko for multiport banning
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
# Copied from iptables.conf and modified by Yaroslav Halchenko
|
||||
# to fullfill the needs of bugreporter dbts#350746.
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
|
||||
#
|
||||
# $Revision: 1 $
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
# Modified-By: Yaroslav Halchenko to include grepping on IP over log files
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
# Another useful configuration value is <getcmd>, if you don't have wget
|
||||
# installed (an example config for curl is given below)
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
[Definition]
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
@ -12,7 +11,7 @@
|
|||
# Values: CMD
|
||||
#
|
||||
actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
||||
Date: `date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
From: Fail2Ban <<sender>>
|
||||
To: <dest>\n
|
||||
Hi,\n
|
||||
|
@ -25,7 +24,7 @@ actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
|||
# Values: CMD
|
||||
#
|
||||
actionstop = printf %%b "Subject: [Fail2Ban] <name>: stopped
|
||||
Date: `date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
From: Fail2Ban <<sender>>
|
||||
To: <dest>\n
|
||||
Hi,\n
|
||||
|
@ -46,7 +45,7 @@ actioncheck =
|
|||
# Values: CMD
|
||||
#
|
||||
actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip>
|
||||
Date: `date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
From: Fail2Ban <<sender>>
|
||||
To: <dest>\n
|
||||
Hi,\n
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
@ -12,7 +11,7 @@
|
|||
# Values: CMD
|
||||
#
|
||||
actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
||||
Date: `date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
From: Fail2Ban <<sender>>
|
||||
To: <dest>\n
|
||||
Hi,\n
|
||||
|
@ -25,7 +24,7 @@ actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
|||
# Values: CMD
|
||||
#
|
||||
actionstop = printf %%b "Subject: [Fail2Ban] <name>: stopped
|
||||
Date: `date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
From: Fail2Ban <<sender>>
|
||||
To: <dest>\n
|
||||
Hi,\n
|
||||
|
@ -46,7 +45,7 @@ actioncheck =
|
|||
# Values: CMD
|
||||
#
|
||||
actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip>
|
||||
Date: `date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
From: Fail2Ban <<sender>>
|
||||
To: <dest>\n
|
||||
Hi,\n
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
@ -12,7 +11,7 @@
|
|||
# Values: CMD
|
||||
#
|
||||
actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
||||
Date: `date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
From: Fail2Ban <<sender>>
|
||||
To: <dest>\n
|
||||
Hi,\n
|
||||
|
@ -25,7 +24,7 @@ actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
|||
# Values: CMD
|
||||
#
|
||||
actionstop = printf %%b "Subject: [Fail2Ban] <name>: stopped
|
||||
Date: `date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
From: Fail2Ban <<sender>>
|
||||
To: <dest>\n
|
||||
Hi,\n
|
||||
|
@ -46,7 +45,7 @@ actioncheck =
|
|||
# Values: CMD
|
||||
#
|
||||
actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip>
|
||||
Date: `date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||
From: Fail2Ban <<sender>>
|
||||
To: <dest>\n
|
||||
Hi,\n
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
# The default Shorewall configuration is with "BLACKLISTNEWONLY=Yes" (see
|
||||
# file /etc/shorewall/shorewall.conf). This means that when Fail2ban adds a
|
||||
|
|
|
@ -43,7 +43,7 @@ socket = /var/run/fail2ban/fail2ban.sock
|
|||
# Option: pidfile
|
||||
# Notes.: Set the PID file. This is used to store the process ID of the
|
||||
# fail2ban server.
|
||||
# Values: FILE Default: /var/run/fail2ban/fail2ban.sock
|
||||
# Values: FILE Default: /var/run/fail2ban/fail2ban.pid
|
||||
#
|
||||
pidfile = /var/run/fail2ban/fail2ban.pid
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#
|
||||
# Author: Yaroslav Halchenko
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Yaroslav O. Halchenko <debian@onerussian.com>
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Tim Connors
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Fail2Ban configuration file
|
||||
# for Anti-Spam SMTP Proxy Server also known as ASSP
|
||||
# Honmepage: http://www.magicvillage.de/~Fritz_Borgstedt/assp/0003D91C-8000001C/
|
||||
# ProjektSite: http://sourceforge.net/projects/assp/?source=directory
|
||||
#
|
||||
# Author: Enrico Labedzki (enrico.labedzki@deiwos.de)
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: failregex
|
||||
# Notes.: regex to match the SMTP failure messages in the logfile. The
|
||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
||||
# be used for standard IP/hostname matching and is only an alias for
|
||||
# (?:::f{4,6}:)?(?P<host>\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 = <HOST> max sender authentication errors \(\d{,3}\) exceeded -- %(__assp_actions)s connection - after reply: \d{3} \d{1}\.\d{1}.\d{1} Error: authentication failed: [a-zA-Z0-9]+;$
|
||||
<HOST> SSL negotiation with client failed: SSL accept attempt failed with unknown error.*:unknown protocol;$
|
||||
Blocking <HOST> - too much AUTH errors \(\d{,3}\);$
|
||||
|
||||
|
||||
# Option: ignoreregex
|
||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
||||
# Values: TEXT
|
||||
#
|
||||
ignoreregex =
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Xavier Devlamynck
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#
|
||||
# Author: Yaroslav Halchenko
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[INCLUDES]
|
||||
|
@ -28,6 +27,10 @@ __pid_re = (?:\[\d+\])
|
|||
# EXAMPLES: pam_rhosts_auth, [sshd], pop(pam_unix)
|
||||
__daemon_re = [\[\(]?%(_daemon)s(?:\(\S+\))?[\]\)]?:?
|
||||
|
||||
# extra daemon info
|
||||
# EXAMPLE: [ID 800047 auth.info]
|
||||
__daemon_extra_re = (?:\[ID \d+ \S+\])
|
||||
|
||||
# Combinations of daemon name and PID
|
||||
# EXAMPLES: sshd[31607], pop(pam_unix)[4920]
|
||||
__daemon_combs_re = (?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_re)s?:)
|
||||
|
@ -43,5 +46,5 @@ __hostname = \S+
|
|||
#
|
||||
# [hostname] [vserver tag] daemon_id spaces
|
||||
# this can be optional (for instance if we match named native log files)
|
||||
__prefix_line = \s*(?:%(__hostname)s )?(?:%(__kernel_prefix)s )?(?:@vserver_\S+ )?%(__daemon_combs_re)s?\s*
|
||||
__prefix_line = \s*(?:%(__hostname)s )?(?:%(__kernel_prefix)s )?(?:@vserver_\S+ )?%(__daemon_combs_re)s?\s%(__daemon_extra_re)s?\s*
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
# Author: Christoph Haas
|
||||
# Modified by: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Jan Wagner <waja@cyconet.org>
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Martin Waschbuesch
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
# Author: Francis Russell
|
||||
# Zak B. Elep
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
# More information: http://bugs.debian.org/546913
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Kevin Zembower (copied from wsftpd.conf)
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# Fail2Ban configuration file for unsuccesfull MySQL authentication attempts
|
||||
#
|
||||
# Authors: Artur Penttinen
|
||||
# Yaroslav O. Halchenko
|
||||
#
|
||||
|
||||
[INCLUDES]
|
||||
|
||||
# Read common prefixes. If any customizations available -- read them from
|
||||
# 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 "<HOST>" can
|
||||
# be used for standard IP/hostname matching and is only an alias for
|
||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
||||
# Values: TEXT
|
||||
# 130322 11:26:54 [Warning] Access denied for user 'root'@'127.0.0.1' (using password: YES)
|
||||
failregex = Access denied for user '\w+'@'<HOST>' (to database '[^']*'|\(using password: (YES|NO)\))*\s*$
|
||||
|
||||
# Option: ignoreregex
|
||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
||||
# Values: TEXT
|
||||
#
|
||||
ignoreregex =
|
|
@ -4,7 +4,6 @@
|
|||
#
|
||||
# Author: Yaroslav Halchenko
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
@ -26,7 +25,7 @@ __line_prefix=(?:\s\S+ %(__daemon_combs_re)s\s+)?
|
|||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT
|
||||
#
|
||||
failregex = %(__line_prefix)sclient <HOST>#.+: query(?: \(cache\))? '.*' denied\s*$
|
||||
failregex = %(__line_prefix)sclient <HOST>#\S+: (view (internal|external): )?query(?: \(cache\))? '.*' denied\s*$
|
||||
|
||||
# Option: ignoreregex
|
||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Yaroslav Halchenko
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Yaroslav Halchenko
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
# Author: Cyril Jaquier
|
||||
# Modified: Yaroslav Halchenko for pure-ftpd
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Yaroslav Halchenko
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Jan Wagner <waja@cyconet.org>
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,6 +2,13 @@
|
|||
#
|
||||
# Author: Yaroslav Halchenko
|
||||
#
|
||||
# The regex here also relates to a exploit:
|
||||
#
|
||||
# http://www.securityfocus.com/bid/17958/exploit
|
||||
# The example code here shows the pushing of the exploit straight after
|
||||
# reading the server version. This is where the client version string normally
|
||||
# pushed. As such the server will read this unparsible information as
|
||||
# "Did not receive identification string".
|
||||
|
||||
[INCLUDES]
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[INCLUDES]
|
||||
|
@ -23,14 +22,16 @@ _daemon = sshd
|
|||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
||||
# Values: TEXT
|
||||
#
|
||||
failregex = ^%(__prefix_line)s(?:error: PAM: )?Authentication failure for .* from <HOST>\s*$
|
||||
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from <HOST>( via \S+)?\s*$
|
||||
^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
|
||||
^%(__prefix_line)sFailed (?:password|publickey) for .* from <HOST>(?: port \d*)?(?: ssh\d*)?\s*$
|
||||
^%(__prefix_line)sFailed \S+ for .* from <HOST>(?: port \d*)?(?: ssh\d*)?\s*$
|
||||
^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$
|
||||
^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$
|
||||
^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$
|
||||
^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$
|
||||
^%(__prefix_line)sUser .+ from <HOST> not allowed because not in any group\s*$
|
||||
^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$
|
||||
^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$
|
||||
^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$
|
||||
|
||||
# Option: ignoreregex
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
# Author: Cyril Jaquier
|
||||
# Rule by : Delvit Guillaume
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Yaroslav Halchenko
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#
|
||||
# Author: Guido Bozzetto
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -46,10 +46,10 @@ maxretry = 3
|
|||
backend = auto
|
||||
|
||||
# "usedns" specifies if jails should trust hostnames in logs,
|
||||
# warn when reverse DNS lookups are performed, or ignore all hostnames in logs
|
||||
# warn when DNS lookups are performed, or ignore all hostnames in logs
|
||||
#
|
||||
# yes: if a hostname is encountered, a reverse DNS lookup will be performed.
|
||||
# warn: if a hostname is encountered, a reverse DNS lookup will be performed,
|
||||
# yes: if a hostname is encountered, a DNS lookup will be performed.
|
||||
# warn: if a hostname is encountered, a DNS lookup will be performed,
|
||||
# but it will be logged as a warning.
|
||||
# no: if a hostname is encountered, will not be used for banning,
|
||||
# but it will be logged as info.
|
||||
|
@ -89,6 +89,13 @@ action = iptables[name=sasl, port=smtp, protocol=tcp]
|
|||
sendmail-whois[name=sasl, dest=you@example.com]
|
||||
logpath = /var/log/mail.log
|
||||
|
||||
# ASSP SMTP Proxy Jail
|
||||
[assp]
|
||||
enabled = false
|
||||
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".
|
||||
|
||||
|
@ -345,6 +352,19 @@ 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
|
||||
[mysqld-iptables]
|
||||
|
||||
enabled = false
|
||||
filter = mysqld-auth
|
||||
action = iptables[name=mysql, port=3306, protocol=tcp]
|
||||
sendmail-whois[name=MySQL, dest=root, sender=fail2ban@example.com]
|
||||
logpath = /var/log/mysqld.log
|
||||
maxretry = 5
|
||||
|
||||
|
||||
# Jail for more extended banning of persistent abusers
|
||||
# !!! WARNING !!!
|
||||
# Make sure that your loglevel specified in fail2ban.conf/.local
|
||||
|
|
|
@ -63,7 +63,7 @@ class Fail2banClient:
|
|||
self.__conf["interactive"] = False
|
||||
self.__conf["socket"] = None
|
||||
self.__conf["pidfile"] = None
|
||||
|
||||
|
||||
def dispVersion(self):
|
||||
print "Fail2Ban v" + version
|
||||
print
|
||||
|
@ -73,7 +73,7 @@ class Fail2banClient:
|
|||
print
|
||||
print "Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>."
|
||||
print "Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>."
|
||||
|
||||
|
||||
def dispUsage(self):
|
||||
""" Prints Fail2Ban command line options and exits
|
||||
"""
|
||||
|
@ -95,17 +95,17 @@ class Fail2banClient:
|
|||
print " -V, --version print the version"
|
||||
print
|
||||
print "Command:"
|
||||
|
||||
|
||||
# Prints the protocol
|
||||
printFormatted()
|
||||
|
||||
|
||||
print
|
||||
print "Report bugs to https://github.com/fail2ban/fail2ban/issues"
|
||||
|
||||
|
||||
def dispInteractive(self):
|
||||
print "Fail2Ban v" + version + " reads log file that contains password failure report"
|
||||
print "and bans the corresponding IP addresses using firewall rules."
|
||||
print
|
||||
print
|
||||
|
||||
def __sigTERMhandler(self, signum, frame):
|
||||
# Print a new line because we probably come from wait
|
||||
|
@ -139,10 +139,10 @@ class Fail2banClient:
|
|||
elif opt[0] in ["-V", "--version"]:
|
||||
self.dispVersion()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def __ping(self):
|
||||
return self.__processCmd([["ping"]], False)
|
||||
|
||||
|
||||
def __processCmd(self, cmd, showRet = True):
|
||||
beautifier = Beautifier()
|
||||
for c in cmd:
|
||||
|
@ -167,7 +167,7 @@ class Fail2banClient:
|
|||
logSys.error(e)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
##
|
||||
# Process a command line.
|
||||
#
|
||||
|
@ -241,13 +241,13 @@ class Fail2banClient:
|
|||
return False
|
||||
else:
|
||||
return self.__processCmd([cmd])
|
||||
|
||||
|
||||
|
||||
|
||||
##
|
||||
# Start Fail2Ban server.
|
||||
#
|
||||
# Start the Fail2ban server in daemon mode.
|
||||
|
||||
|
||||
def __startServerAsync(self, socket, pidfile, force = False):
|
||||
# Forks the current process.
|
||||
pid = os.fork()
|
||||
|
@ -278,7 +278,7 @@ class Fail2banClient:
|
|||
except OSError:
|
||||
logSys.error("Could not start %s" % self.SERVER)
|
||||
os.exit(-1)
|
||||
|
||||
|
||||
def __waitOnServer(self):
|
||||
# Wait for the server to start
|
||||
cnt = 0
|
||||
|
@ -306,16 +306,16 @@ class Fail2banClient:
|
|||
cnt += 1
|
||||
if self.__conf["verbose"] > 1:
|
||||
sys.stdout.write('\n')
|
||||
|
||||
|
||||
|
||||
|
||||
def start(self, argv):
|
||||
# Command line options
|
||||
self.__argv = argv
|
||||
|
||||
|
||||
# Install signal handlers
|
||||
signal.signal(signal.SIGTERM, self.__sigTERMhandler)
|
||||
signal.signal(signal.SIGINT, self.__sigTERMhandler)
|
||||
|
||||
|
||||
# Reads the command line options.
|
||||
try:
|
||||
cmdOpts = 'hc:s:p:xdviqV'
|
||||
|
@ -324,9 +324,9 @@ class Fail2banClient:
|
|||
except getopt.GetoptError:
|
||||
self.dispUsage()
|
||||
return False
|
||||
|
||||
|
||||
self.__getCmdLineOptions(optList)
|
||||
|
||||
|
||||
verbose = self.__conf["verbose"]
|
||||
if verbose <= 0:
|
||||
logSys.setLevel(logging.ERROR)
|
||||
|
@ -346,13 +346,13 @@ class Fail2banClient:
|
|||
|
||||
# Set the configuration path
|
||||
self.__configurator.setBaseDir(self.__conf["conf"])
|
||||
|
||||
|
||||
# Set socket path
|
||||
self.__configurator.readEarly()
|
||||
conf = self.__configurator.getEarlyOptions()
|
||||
if self.__conf["socket"] == None:
|
||||
if self.__conf["socket"] is None:
|
||||
self.__conf["socket"] = conf["socket"]
|
||||
if self.__conf["pidfile"] == None:
|
||||
if self.__conf["pidfile"] is None:
|
||||
self.__conf["pidfile"] = conf["pidfile"]
|
||||
logSys.info("Using socket file " + self.__conf["socket"])
|
||||
|
||||
|
@ -360,7 +360,7 @@ class Fail2banClient:
|
|||
ret = self.__readConfig()
|
||||
self.dumpConfig(self.__stream)
|
||||
return ret
|
||||
|
||||
|
||||
# Interactive mode
|
||||
if self.__conf["interactive"]:
|
||||
try:
|
||||
|
@ -401,14 +401,14 @@ class Fail2banClient:
|
|||
self.__configurator.convertToProtocol()
|
||||
self.__stream = self.__configurator.getConfigStream()
|
||||
return ret
|
||||
|
||||
|
||||
def __readJailConfig(self, jail):
|
||||
self.__configurator.readAll()
|
||||
ret = self.__configurator.getOptions(jail)
|
||||
self.__configurator.convertToProtocol()
|
||||
self.__stream = self.__configurator.getConfigStream()
|
||||
return ret
|
||||
|
||||
|
||||
#@staticmethod
|
||||
def dumpConfig(cmd):
|
||||
for c in cmd:
|
||||
|
|
|
@ -50,24 +50,24 @@ class RegexStat:
|
|||
def __str__(self):
|
||||
return "%s(%r) %d failed: %s" \
|
||||
% (self.__class__, self.__failregex, self.__stats, self.__ipList)
|
||||
|
||||
|
||||
def inc(self):
|
||||
self.__stats += 1
|
||||
|
||||
|
||||
def getStats(self):
|
||||
return self.__stats
|
||||
|
||||
def getFailRegex(self):
|
||||
return self.__failregex
|
||||
|
||||
|
||||
def appendIP(self, value):
|
||||
self.__ipList.extend(value)
|
||||
|
||||
|
||||
def getIPList(self):
|
||||
return self.__ipList
|
||||
|
||||
class Fail2banRegex:
|
||||
|
||||
|
||||
test = None
|
||||
|
||||
CONFIG_DEFAULTS = {'configpath' : "/etc/fail2ban/"}
|
||||
|
@ -87,7 +87,7 @@ class Fail2banRegex:
|
|||
self.__logging_level = self.__verbose and logging.DEBUG or logging.WARN
|
||||
logging.getLogger("fail2ban").addHandler(self.__hdlr)
|
||||
logging.getLogger("fail2ban").setLevel(logging.ERROR)
|
||||
|
||||
|
||||
#@staticmethod
|
||||
def dispVersion():
|
||||
print "Fail2Ban v" + version
|
||||
|
@ -99,7 +99,7 @@ class Fail2banRegex:
|
|||
print "Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>."
|
||||
print "Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>."
|
||||
dispVersion = staticmethod(dispVersion)
|
||||
|
||||
|
||||
#@staticmethod
|
||||
def dispUsage():
|
||||
print "Usage: "+sys.argv[0]+" [OPTIONS] <LOG> <REGEX> [IGNOREREGEX]"
|
||||
|
@ -128,7 +128,7 @@ class Fail2banRegex:
|
|||
print
|
||||
print "Report bugs to https://github.com/fail2ban/fail2ban/issues"
|
||||
dispUsage = staticmethod(dispUsage)
|
||||
|
||||
|
||||
def getCmdLineOptions(self, optList):
|
||||
""" Gets the command line options
|
||||
"""
|
||||
|
@ -204,7 +204,7 @@ class Fail2banRegex:
|
|||
print "Use regex line : " + stripReg
|
||||
self.__failregex = [RegexStat(value)]
|
||||
return True
|
||||
|
||||
|
||||
def testIgnoreRegex(self, line):
|
||||
found = False
|
||||
for regex in self.__ignoreregex:
|
||||
|
@ -221,7 +221,7 @@ class Fail2banRegex:
|
|||
finally:
|
||||
self.__filter.delIgnoreRegex(0)
|
||||
logging.getLogger("fail2ban").setLevel(self.__logging_level)
|
||||
|
||||
|
||||
def testRegex(self, line):
|
||||
found = False
|
||||
for regex in self.__ignoreregex:
|
||||
|
@ -251,7 +251,7 @@ class Fail2banRegex:
|
|||
logging.getLogger("fail2ban").setLevel(logging.CRITICAL)
|
||||
for regex in self.__ignoreregex:
|
||||
self.__filter.delIgnoreRegex(0)
|
||||
|
||||
|
||||
def printStats(self):
|
||||
print
|
||||
print "Results"
|
||||
|
@ -300,20 +300,20 @@ class Fail2banRegex:
|
|||
print " %s (%s)%s" % (
|
||||
ip[0], timeString, ip[2] and " (already matched)" or "")
|
||||
print
|
||||
|
||||
|
||||
print "Date template hits:"
|
||||
for template in self.__filter.dateDetector.getTemplates():
|
||||
if self.__verbose or template.getHits():
|
||||
print `template.getHits()` + " hit(s): " + template.getName()
|
||||
print
|
||||
|
||||
|
||||
print "Success, the total number of match is " + str(total)
|
||||
print
|
||||
print "However, look at the above section 'Running tests' which could contain important"
|
||||
print "information."
|
||||
return True
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fail2banRegex = Fail2banRegex()
|
||||
# Reads the command line options.
|
||||
|
|
|
@ -46,7 +46,7 @@ logSys = logging.getLogger("fail2ban")
|
|||
# Its first goal was to protect a SSH server.
|
||||
|
||||
class Fail2banServer:
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.__server = None
|
||||
self.__argv = None
|
||||
|
@ -55,7 +55,7 @@ class Fail2banServer:
|
|||
self.__conf["force"] = False
|
||||
self.__conf["socket"] = "/var/run/fail2ban/fail2ban.sock"
|
||||
self.__conf["pidfile"] = "/var/run/fail2ban/fail2ban.pid"
|
||||
|
||||
|
||||
def dispVersion(self):
|
||||
print "Fail2Ban v" + version
|
||||
print
|
||||
|
@ -65,7 +65,7 @@ class Fail2banServer:
|
|||
print
|
||||
print "Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>."
|
||||
print "Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>."
|
||||
|
||||
|
||||
def dispUsage(self):
|
||||
""" Prints Fail2Ban command line options and exits
|
||||
"""
|
||||
|
@ -88,7 +88,7 @@ class Fail2banServer:
|
|||
print " -V, --version print the version"
|
||||
print
|
||||
print "Report bugs to https://github.com/fail2ban/fail2ban/issues"
|
||||
|
||||
|
||||
def __getCmdLineOptions(self, optList):
|
||||
""" Gets the command line options
|
||||
"""
|
||||
|
@ -109,11 +109,11 @@ class Fail2banServer:
|
|||
if opt[0] in ["-V", "--version"]:
|
||||
self.dispVersion()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def start(self, argv):
|
||||
# Command line options
|
||||
self.__argv = argv
|
||||
|
||||
|
||||
# Reads the command line options.
|
||||
try:
|
||||
cmdOpts = 'bfs:p:xhV'
|
||||
|
@ -122,9 +122,9 @@ class Fail2banServer:
|
|||
except getopt.GetoptError:
|
||||
self.dispUsage()
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
self.__getCmdLineOptions(optList)
|
||||
|
||||
|
||||
try:
|
||||
self.__server = Server(self.__conf["background"])
|
||||
self.__server.start(self.__conf["socket"],
|
||||
|
@ -135,7 +135,7 @@ class Fail2banServer:
|
|||
logSys.exception(e)
|
||||
self.__server.quit()
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
server = Fail2banServer()
|
||||
if server.start(sys.argv):
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
FAIL2BAN="fail2ban-client"
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#
|
||||
# Gentoo:
|
||||
# http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/net-analyzer/fail2ban/files/fail2ban-logrotate?view=markup
|
||||
#
|
||||
# Debian:
|
||||
# https://github.com/fail2ban/fail2ban/blob/debian/debian/fail2ban.logrotate
|
||||
#
|
||||
# Fedora view:
|
||||
# http://pkgs.fedoraproject.org/cgit/fail2ban.git/tree/fail2ban-logrotate
|
||||
|
||||
/var/log/fail2ban.log {
|
||||
rotate 7
|
||||
missingok
|
||||
compress
|
||||
postrotate
|
||||
/usr/bin/fail2ban-client set logtarget /var/log/fail2ban.log 1>/dev/null || true
|
||||
endscript
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
D /var/run/fail2ban 0755 root root -
|
|
@ -0,0 +1,14 @@
|
|||
[Unit]
|
||||
Description=Fail2ban Service
|
||||
After=syslog.target network.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
ExecStart=/usr/bin/fail2ban-client -x start
|
||||
ExecStop=/usr/bin/fail2ban-client stop
|
||||
ExecReload=/usr/bin/fail2ban-client reload
|
||||
PIDFile=/var/run/fail2ban/fail2ban.pid
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -17,7 +17,6 @@
|
|||
#
|
||||
# Author: Sireyessire, Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
extra_started_commands="reload showlog"
|
||||
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
Description
|
||||
-----------
|
||||
This plugin checks if the fail2ban server is running and how many IPs are currently banned.
|
||||
You can use this plugin to monitor all the jails or just a specific jail.
|
||||
|
||||
|
||||
How to use
|
||||
----------
|
||||
Just have to run the following command:
|
||||
$ ./check_fail2ban --help
|
||||
|
||||
If you need to use this script with NRPE you just have to do the
|
||||
following steps:
|
||||
|
||||
1 allow your user to run the script with the sudo rights. Just add
|
||||
something like that in your /etc/sudoers (use visudo) :
|
||||
nagios ALL=(ALL) NOPASSWD: /<path-to>/check_fail2ban
|
||||
|
||||
2 then just add this kind of line in your NRPE config file :
|
||||
command[check_fail2ban]=/usr/bin/sudo /<path-to>/check_fail2ban
|
||||
|
||||
3 don't forget to restart your NRPE daemon
|
||||
|
||||
/!\ be careful to let no one able to update the check_fail2ban ;)
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Notes (from f2ban.txt)
|
||||
-----
|
||||
It seems that Fail2ban is currently not working, please login and check
|
||||
|
||||
HELP:
|
||||
|
||||
1.) stop the Service
|
||||
/etc/init.d/fail2ban stop
|
||||
|
||||
2.) delete the socket if available
|
||||
rm /tmp/fail2ban.sock
|
||||
|
||||
3.) start the Service
|
||||
/etc/init.d/fail2ban start
|
||||
|
||||
4.) check if fail2ban is working
|
||||
fail2ban-client ping
|
||||
Answer should be "pong"
|
||||
|
||||
5.) if the answer is not "pong" run away or CRY FOR HELP ;-)
|
||||
|
||||
|
||||
Help
|
||||
----
|
||||
|
||||
Usage: /<path-to>/check_fail2ban [-p] [-D "CHECK FAIL2BAN ACTIVITY"] [-v] [-c 2] [-w 1] [-s /<path-to>/socket] [-P /usr/bin/fail2ban-client]
|
||||
|
||||
Options:
|
||||
-h, --help
|
||||
Print detailed help screen
|
||||
-V, --version
|
||||
Print version information
|
||||
-D, --display=STRING
|
||||
To modify the output display
|
||||
default is "CHECK FAIL2BAN ACTIVITY"
|
||||
-P, --path-fail2ban_client=STRING
|
||||
Specify the path to the tw_cli binary
|
||||
default value is /usr/bin/fail2ban-client
|
||||
-c, --critical=INT
|
||||
Specify a critical threshold
|
||||
default is 2
|
||||
-w, --warning=INT
|
||||
Specify a warning threshold
|
||||
default is 1
|
||||
-s, --socket=STRING
|
||||
Specify a socket path
|
||||
default is unset
|
||||
-p, --perfdata
|
||||
If you want to activate the perfdata output
|
||||
-v, --verbose
|
||||
Show details for command-line debugging (Nagios may truncate the output)
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
# for a specific jail
|
||||
$ ./check_fail2ban --verbose -p -j ssh -w 1 -c 5 -P /usr/bin/fail2ban-client
|
||||
DEBUG : fail2ban_client_path: /usr/bin/fail2ban-client
|
||||
DEBUG : /usr/bin/fail2ban-client exists and is executable
|
||||
DEBUG : final fail2ban command: /usr/bin/fail2ban-client
|
||||
DEBUG : warning threshold : 1, critical threshold : 5
|
||||
DEBUG : it seems the connection with the fail2ban server is ok
|
||||
CHECK FAIL2BAN ACTIVITY - OK - 0 current banned IP(s) for the specific jail ssh | currentBannedIP=0
|
||||
|
||||
# for all the current jails
|
||||
$ ./check_fail2ban --verbose -p -w 1 -c 5 -P /usr/bin/fail2ban-client
|
||||
DEBUG : fail2ban_client_path: /usr/bin/fail2ban-client
|
||||
DEBUG : /usr/bin/fail2ban-client exists and is executable
|
||||
DEBUG : final fail2ban command: /usr/bin/fail2ban-client
|
||||
DEBUG : warning threshold : 1, critical threshold : 5
|
||||
DEBUG : it seems the connection with the fail2ban server is ok
|
||||
DEBUG : jails list: apache, ssh-ddos, ssh
|
||||
DEBUG : the jail apache has currently 0 banned IPs
|
||||
DEBUG : the jail ssh-ddos has currently 0 banned IPs
|
||||
DEBUG : the jail ssh has currently 0 banned IPs
|
||||
CHECK FAIL2BAN ACTIVITY - OK - 3 detected jails with 0 current banned IP(s) | currentBannedIP=0
|
|
@ -1,105 +1,346 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/perl
|
||||
|
||||
# -------------------------------------------------------
|
||||
# -=- <check_fail2ban> -=-
|
||||
# -------------------------------------------------------
|
||||
#
|
||||
# Usage: ./check_fail2ban
|
||||
###############################################################################################
|
||||
# Description:
|
||||
# This plugin will check the status of Fail2ban.
|
||||
# Description : This plugin checks if the fail2ban server is running
|
||||
# and how many IPs are currently banned.
|
||||
#
|
||||
#
|
||||
# Created: 2008-10-25 (Sebastian Mueller)
|
||||
# inspired by the work of Sebastian Mueller - http://www.elchtest.eu
|
||||
#
|
||||
#
|
||||
# Changes: 2008-10-26 fixed some issues (Sebastian Mueller)
|
||||
# Changes: 2009-01-25 add the second check, when server is not replying and the
|
||||
# process is hang-up (Sebastian Mueller)
|
||||
# Version : 0.1
|
||||
# -------------------------------------------------------
|
||||
# In :
|
||||
# - see the How to use section
|
||||
#
|
||||
# please visit my website http://www.elchtest.eu or my personal WIKI http://wiki.elchtest.eu
|
||||
# Out :
|
||||
# - only print on the standard output
|
||||
#
|
||||
################################################################################################
|
||||
# if you have any questions, send a mail to linux@krabbe-offline.de
|
||||
# Features :
|
||||
# - perfdata output
|
||||
# - works with only a specific jail
|
||||
#
|
||||
# this script is for my personal use. read the script before running/using it!!!
|
||||
# Fix Me/Todo :
|
||||
# - too many things ;) but let me know what do you think about it
|
||||
#
|
||||
# ####################################################################
|
||||
|
||||
# ####################################################################
|
||||
# GPL v2
|
||||
# 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.
|
||||
#
|
||||
# YOU HAVE BEEN WARNED. THIS MAY DESTROY YOUR MACHINE. I ACCEPT NO RESPONSIBILITY.
|
||||
###############################################################################################
|
||||
# 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
# ####################################################################
|
||||
|
||||
# ####################################################################
|
||||
# How to use :
|
||||
# ------------
|
||||
#
|
||||
# Just have to run the following command:
|
||||
# $ ./check_fail2ban --help
|
||||
#
|
||||
# If you need to use this script with NRPE you just have to do the
|
||||
# following steps:
|
||||
#
|
||||
# 1 allow your user to run the script with the sudo rights. Just add
|
||||
# something like that in your /etc/sudoers (use visudo) :
|
||||
# nagios ALL=(ALL) NOPASSWD: /<path-to>/check_fail2ban
|
||||
#
|
||||
# 2 then just add this kind of line in your NRPE config file :
|
||||
# command[check_fail2ban]=/usr/bin/sudo /<path-to>/check_fail2ban
|
||||
#
|
||||
# 3 don't forget to restart your NRPE daemon
|
||||
#
|
||||
#
|
||||
# /!\ be careful to let no one able to update the check_fail2ban ;)
|
||||
# ------------------------------------------------------------------------------
|
||||
#
|
||||
# ####################################################################
|
||||
|
||||
# ####################################################################
|
||||
# Changelog :
|
||||
# -----------
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
# Date:12/03/2013 Version:0.1 Author:Erwan Ben Souiden
|
||||
# >> creation
|
||||
# ####################################################################
|
||||
|
||||
# ####################################################################
|
||||
# Don't touch anything under this line!
|
||||
# You shall not pass - Gandalf is watching you
|
||||
# ####################################################################
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long qw(:config no_ignore_case);
|
||||
|
||||
# Generic variables
|
||||
# -----------------
|
||||
my $version = '0.1';
|
||||
my $author = 'Erwan Labynocle Ben Souiden';
|
||||
my $a_mail = 'erwan@aleikoum.net';
|
||||
my $script_name = 'check_fail2ban';
|
||||
my $verbose_value = 0;
|
||||
my $version_value = 0;
|
||||
my $more_value = 0;
|
||||
my $help_value = 0;
|
||||
my $perfdata_value = 0;
|
||||
my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4);
|
||||
|
||||
# Plugin default variables
|
||||
# ------------------------
|
||||
my $display = 'CHECK FAIL2BAN ACTIVITY';
|
||||
my ($critical,$warning) = (2,1);
|
||||
my $fail2ban_client_path = '/usr/bin/fail2ban-client';
|
||||
my $fail2ban_socket = '';
|
||||
my $jail_specific = '';
|
||||
|
||||
GetOptions (
|
||||
'P=s' => \ $fail2ban_client_path,
|
||||
'path-fail2ban_client=s' => \ $fail2ban_client_path,
|
||||
'j=s' => \ $jail_specific,
|
||||
'jail=s' => \ $jail_specific,
|
||||
'w=i' => \ $warning,
|
||||
'warning=i' => \ $warning,
|
||||
'socket=s' => \ $fail2ban_socket,
|
||||
'S=s' => \ $fail2ban_socket,
|
||||
'c=i' => \ $critical,
|
||||
'critical=i' => \ $critical,
|
||||
'V' => \ $version_value,
|
||||
'version' => \ $version_value,
|
||||
'h' => \ $help_value,
|
||||
'H' => \ $help_value,
|
||||
'help' => \ $help_value,
|
||||
'display=s' => \ $display,
|
||||
'D=s' => \ $display,
|
||||
'perfdata' => \ $perfdata_value,
|
||||
'p' => \ $perfdata_value,
|
||||
'v' => \ $verbose_value,
|
||||
'verbose' => \ $verbose_value
|
||||
);
|
||||
|
||||
print_usage() if ($help_value);
|
||||
print_version() if ($version_value);
|
||||
|
||||
|
||||
SECOND_CHECK=0
|
||||
STATE_OK=0
|
||||
STATE_CRITICAL=2
|
||||
|
||||
######################################################################
|
||||
# Read the Status from fail2ban-client
|
||||
######################################################################
|
||||
check_processes_fail2ban()
|
||||
{
|
||||
|
||||
F2B=`sudo -u root fail2ban-client ping | awk -F " " '{print $3}'`
|
||||
exit_fail2ban=0
|
||||
|
||||
if [[ $F2B = "pong" ]]; then
|
||||
exit_fail2ban=$STATE_OK
|
||||
else
|
||||
exit_fail2ban=$STATE_CRITICAL
|
||||
fi
|
||||
# Syntax check of your specified options
|
||||
# --------------------------------------
|
||||
|
||||
print "DEBUG : fail2ban_client_path: $fail2ban_client_path\n" if ($verbose_value);
|
||||
if (($fail2ban_client_path eq "")) {
|
||||
print $display.'- one or more following arguments are missing: fail2ban_client_path'."\n";
|
||||
exit $ERRORS{"UNKNOWN"};
|
||||
}
|
||||
######################################################################
|
||||
# first check in the Background, PID will be killed when no response
|
||||
# after 10 seconds, might be possible, otherwise the script will be
|
||||
# present in your memory all the time
|
||||
######################################################################
|
||||
|
||||
check_processes_fail2ban &
|
||||
pid=$!
|
||||
if(! -x $fail2ban_client_path) {
|
||||
print $display.' - '.$fail2ban_client_path.' is not executable by you'."\n";
|
||||
exit $ERRORS{"UNKNOWN"};
|
||||
}
|
||||
print "DEBUG : $fail2ban_client_path exists and is executable\n" if ($verbose_value);
|
||||
|
||||
typeset -i i=0
|
||||
while ps $pid >/dev/null
|
||||
do
|
||||
sleep 1
|
||||
i=$i+1
|
||||
if [ $i -ge 10 ]
|
||||
then
|
||||
kill $pid
|
||||
SECOND_CHECK=1
|
||||
exit_fail2ban=$STATE_CRITICAL
|
||||
break
|
||||
fi
|
||||
done
|
||||
my $fail2ban_cmd = $fail2ban_client_path;
|
||||
$fail2ban_cmd .= " -s $fail2ban_socket" if ($fail2ban_socket);
|
||||
|
||||
######################################################################
|
||||
# when the Server response (does not mean the FAIL2BAN is working)
|
||||
# in the first step, then it will run again and test the Service
|
||||
# and provide the real status
|
||||
######################################################################
|
||||
print "DEBUG : final fail2ban command: $fail2ban_cmd\n" if ($verbose_value);
|
||||
|
||||
print "DEBUG : warning threshold : $warning, critical threshold : $critical\n" if ($verbose_value);
|
||||
if (($critical < 0) or ($warning < 0) or ($critical < $warning)) {
|
||||
print $display.' - the thresholds must be integers and the critical threshold higher or equal than the warning threshold'."\n";
|
||||
exit $ERRORS{"UNKNOWN"};
|
||||
}
|
||||
|
||||
# Core script
|
||||
# -----------
|
||||
my ($how_many_jail,$how_many_banned,$return_print,$plugstate) = (0,0,"","OK");
|
||||
|
||||
|
||||
if [ $SECOND_CHECK -eq 0 ]; then
|
||||
check_processes_fail2ban
|
||||
elif [ $SECOND_CHECK -eq 1 ]; then
|
||||
exit_fail2ban=$STATE_CRITICAL
|
||||
fi
|
||||
### Test the connection to the fail2ban server
|
||||
my @command_output = `$fail2ban_cmd ping`;
|
||||
my $return_code = $?;
|
||||
if ($return_code) {
|
||||
print $display.'CRITICAL - non-zero exit code during testing fail2ban-client ping, check if the server is running and if you have the good permissions';
|
||||
exit $ERRORS{"CRITICAL"};
|
||||
}
|
||||
else {
|
||||
print "DEBUG : it seems the connection with the fail2ban server is ok\n" if ($verbose_value);
|
||||
}
|
||||
|
||||
|
||||
### Only if you specify one jail
|
||||
if ($jail_specific) {
|
||||
my $current_ban_number = currently_ban("$fail2ban_cmd","$jail_specific");
|
||||
if ($current_ban_number == -1) {
|
||||
print $display.' - CRITICAL - impossible to retrieve info about the jail '.$jail_specific;
|
||||
exit $ERRORS{"CRITICAL"};
|
||||
}
|
||||
else {
|
||||
$how_many_banned = int($current_ban_number);
|
||||
$return_print = $how_many_banned.' current banned IP(s) for the specific jail '.$jail_specific;
|
||||
}
|
||||
}
|
||||
### To analyze all the jail
|
||||
else {
|
||||
# Retrieve the jails list
|
||||
my @jail_list = obtain_jail_list("$fail2ban_cmd");
|
||||
if ($jail_list[0] eq "-1") {
|
||||
print $display.' - CRITICAL - impossible to retrieve the jail list'."\n";
|
||||
exit $ERRORS{"CRITICAL"};
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Main Menu
|
||||
######################################################################
|
||||
foreach (@jail_list) {
|
||||
$how_many_jail ++;
|
||||
|
||||
my $jail_name = $_;
|
||||
$jail_name =~ tr/ //ds;
|
||||
|
||||
my $current_ban_number = currently_ban("$fail2ban_cmd","$jail_name");
|
||||
if ($current_ban_number == -1) {
|
||||
print "DEBUG : problem to parse the current banned IPs for jail $jail_name\n" if ($verbose_value);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
$return_print = $how_many_jail.' detected jails with '.$how_many_banned.' current banned IP(s)';
|
||||
}
|
||||
|
||||
### Final
|
||||
$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);
|
||||
|
||||
print $return_print;
|
||||
exit $ERRORS{"$plugstate"};
|
||||
|
||||
|
||||
final_exit=$exit_fail2ban
|
||||
if [ $final_exit -eq 0 ]; then
|
||||
echo "SYSTEM OK - Fail2ban is working normally"
|
||||
exitstatus=$STATE_OK
|
||||
elif [ $final_exit -ne "0" ]; then
|
||||
echo "SYSTEM WARNING - Fail2Ban is not working"
|
||||
######################################################################
|
||||
# If don't have a Nagios Server for monitoring, remove the comment and
|
||||
# add your Mail Address. You can check it with a Cron Job once an hour.
|
||||
# put a txt file on your server and describe how to fix the issue, this
|
||||
# could be attached to the mail.
|
||||
######################################################################
|
||||
# mutt -s "FAIL2BAN NOT WORKING" your@example.com < /home/f2ban.txt
|
||||
# ####################################################################
|
||||
# function 1 : display the help
|
||||
# -----------------------------
|
||||
sub print_usage {
|
||||
print <<EOT;
|
||||
$script_name version $version by $author
|
||||
|
||||
exitstatus=$STATE_CRITICAL
|
||||
fi
|
||||
exit $exitstatus
|
||||
This plugin checks if the fail2ban server is running and how many IPs are currently banned.
|
||||
You can use this plugin to monitor all the jails or just a specific jail.
|
||||
|
||||
Usage: /<path-to>/$script_name [-p] [-D "$display"] [-v] [-c 2] [-w 1] [-s /<path-to>/socket] [-P /usr/bin/fail2ban-client]
|
||||
|
||||
Options:
|
||||
-h, --help
|
||||
Print detailed help screen
|
||||
-V, --version
|
||||
Print version information
|
||||
-D, --display=STRING
|
||||
To modify the output display
|
||||
default is "CHECK FAIL2BAN ACTIVITY"
|
||||
-P, --path-fail2ban_client=STRING
|
||||
Specify the path to the tw_cli binary
|
||||
default value is /usr/bin/fail2ban-client
|
||||
-c, --critical=INT
|
||||
Specify a critical threshold
|
||||
default is 2
|
||||
-w, --warning=INT
|
||||
Specify a warning threshold
|
||||
default is 1
|
||||
-s, --socket=STRING
|
||||
Specify a socket path
|
||||
default is unset
|
||||
-p, --perfdata
|
||||
If you want to activate the perfdata output
|
||||
-v, --verbose
|
||||
Show details for command-line debugging (Nagios may truncate the output)
|
||||
|
||||
Send email to $a_mail if you have questions
|
||||
regarding use of this software. To submit patches or suggest improvements,
|
||||
send email to $a_mail
|
||||
This plugin has been created by $author
|
||||
|
||||
Hope you will enjoy it ;)
|
||||
|
||||
Remember :
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
EOT
|
||||
exit $ERRORS{"UNKNOWN"};
|
||||
}
|
||||
|
||||
# function 2 : display version information
|
||||
# ----------------------------------------
|
||||
sub print_version {
|
||||
print <<EOT;
|
||||
$script_name version $version
|
||||
EOT
|
||||
exit $ERRORS{"UNKNOWN"};
|
||||
}
|
||||
|
||||
# function 3 : return the jail list
|
||||
# ---------------------------------
|
||||
sub obtain_jail_list {
|
||||
my ($fail2ban_client_path) = @_;
|
||||
|
||||
my @command_output = `$fail2ban_client_path status`;
|
||||
my $return_code = $?;
|
||||
if ($return_code) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
my @jail_list;
|
||||
foreach (@command_output) {
|
||||
if ($_=~/^.*Jail list:\t+(.*)/) {
|
||||
print "DEBUG : jails list: $1\n" if ($verbose_value);
|
||||
@jail_list = split(/,/, $1);
|
||||
}
|
||||
}
|
||||
|
||||
return @jail_list;
|
||||
}
|
||||
|
||||
# function 4 : return how many IP are currently ban for a given jail
|
||||
# ------------------------------------------------------------------
|
||||
sub currently_ban {
|
||||
my ($fail2ban_client_path,$jail_name) = @_;
|
||||
|
||||
my @command_output = `$fail2ban_client_path status $jail_name`;
|
||||
my $return_code = $?;
|
||||
if ($return_code) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
foreach (@command_output) {
|
||||
if ($_=~/^.*Currently banned:\t+(.*)/) {
|
||||
my $current_count = $1;
|
||||
$current_count =~ tr/ //ds;
|
||||
return $current_count;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
It seems that Fail2ban is currently not working, please login and check
|
||||
|
||||
HELP:
|
||||
|
||||
1.) stop the Service
|
||||
/etc/init.d/fail2ban stop
|
||||
|
||||
2.) delete the socket if available
|
||||
rm /tmp/fail2ban.sock
|
||||
|
||||
3.) start the Service
|
||||
/etc/init.d/fail2ban start
|
||||
|
||||
4.) check if fail2ban is working
|
||||
fail2ban-client ping
|
||||
Answer should be "pong"
|
||||
|
||||
5.) if the answer is not "pong" run away or CRY FOR HELP ;-)
|
|
@ -17,8 +17,26 @@ fi
|
|||
|
||||
ENV="/usr/bin/env -i LANG=C PATH=/usr/local/bin:/usr/bin:/bin:/opt/sfw/bin:/usr/sfw/bin"
|
||||
|
||||
# get socket/pid conf and check dir exists
|
||||
# sock and pid default dirs are currently the same
|
||||
# mkdir if it doesn't exist
|
||||
SOCK_FILE=$(sed "/^\#/d" "$F2B_CONF" | grep "socket" | tail -1 | cut -d "=" -f2-)
|
||||
SOCK_DIR=$(dirname $SOCK_FILE)
|
||||
if [ -n "$SOCK_DIR" ]; then
|
||||
if [ ! -d "$SOCK_DIR" ]; then
|
||||
mkdir "$SOCK_DIR" || exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
start)
|
||||
# remove any lingering sockets
|
||||
# don't quote the var for the -e test
|
||||
if [ -n "$SOCK_FILE" ]; then
|
||||
if [ -e $SOCK_FILE ]; then
|
||||
rm -f $SOCK_FILE || exit 1
|
||||
fi
|
||||
fi
|
||||
[ -f /etc/fail2ban.conf ] || touch /etc/fail2ban.conf
|
||||
echo "Starting fail2ban-server with $F2B_CONF"
|
||||
eval $ENV /usr/local/bin/fail2ban-client start &
|
||||
|
|
|
@ -92,7 +92,7 @@ Commands specified in the [Definition] section are executed through a system she
|
|||
return 0, otherwise error would be logged. Moreover if \fBactioncheck\fR exits with non-0 status, it is taken as indication that firewall status has changed and fail2ban needs to reinitialize itself (i.e. issue \fBactionstop\fR and \fBactionstart\fR commands).
|
||||
|
||||
Tags are enclosed in <>. All the elements of [Init] are tags that are replaced in all action commands. Tags can be added by the
|
||||
\fBfail2ban-client\fR using the setctag command.
|
||||
\fBfail2ban-client\fR using the setctag command. \fB<br>\fR is a tag that is always a new line (\\n).
|
||||
|
||||
More than a single command is allowed to be specified. Each command needs to be on a separate line and indented with whitespaces without blank lines. The following example defines
|
||||
two commands to be executed.
|
||||
|
|
|
@ -19,10 +19,7 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
|
|
@ -17,18 +17,12 @@
|
|||
# along with Fail2Ban; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__author__ = "Cyril Jaquier and Fail2Ban Contributors"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2012 Yaroslav Halchenko"
|
||||
__license__ = "GPL"
|
||||
|
||||
import logging, os
|
||||
import threading
|
||||
import threading, re
|
||||
#from subprocess import call
|
||||
|
||||
# Gets the instance of the logger.
|
||||
|
@ -143,6 +137,10 @@ class Action:
|
|||
# @return True if the command succeeded
|
||||
|
||||
def execActionStart(self):
|
||||
if self.__cInfo:
|
||||
if not Action.substituteRecursiveTags(self.__cInfo):
|
||||
logSys.error("Cinfo/definitions contain self referencing definitions and cannot be resolved")
|
||||
return False
|
||||
startCmd = Action.replaceTag(self.__actionStart, self.__cInfo)
|
||||
return Action.executeCmd(startCmd)
|
||||
|
||||
|
@ -242,6 +240,38 @@ class Action:
|
|||
stopCmd = Action.replaceTag(self.__actionStop, self.__cInfo)
|
||||
return Action.executeCmd(stopCmd)
|
||||
|
||||
##
|
||||
# Sort out tag definitions within other tags
|
||||
#
|
||||
# so: becomes:
|
||||
# a = 3 a = 3
|
||||
# b = <a>_3 b = 3_3
|
||||
# @param tags, a dictionary
|
||||
# @returns tags altered or False if there is a recursive definition
|
||||
#@staticmethod
|
||||
def substituteRecursiveTags(tags):
|
||||
t = re.compile(r'<([^ >]+)>')
|
||||
for tag, value in tags.iteritems():
|
||||
value = str(value)
|
||||
m = t.search(value)
|
||||
while m:
|
||||
if m.group(1) == tag:
|
||||
# recursive definitions are bad
|
||||
return False
|
||||
else:
|
||||
if tags.has_key(m.group(1)):
|
||||
value = value[0:m.start()] + tags[m.group(1)] + value[m.end():]
|
||||
m = t.search(value, m.start())
|
||||
else:
|
||||
# Missing tags are ok so we just continue on searching.
|
||||
# cInfo can contain aInfo elements like <HOST> and valid shell
|
||||
# constructs like <STDIN>.
|
||||
m = t.search(value, m.start() + 1)
|
||||
tags[tag] = value
|
||||
return tags
|
||||
substituteRecursiveTags = staticmethod(substituteRecursiveTags)
|
||||
|
||||
#@staticmethod
|
||||
def escapeTag(tag):
|
||||
for c in '\\#&;`|*?~<>^()[]{}$\n\'"':
|
||||
if c in tag:
|
||||
|
@ -297,16 +327,14 @@ class Action:
|
|||
if not Action.executeCmd(checkCmd):
|
||||
logSys.error("Invariant check failed. Trying to restore a sane" +
|
||||
" environment")
|
||||
stopCmd = Action.replaceTag(self.__actionStop, self.__cInfo)
|
||||
Action.executeCmd(stopCmd)
|
||||
startCmd = Action.replaceTag(self.__actionStart, self.__cInfo)
|
||||
Action.executeCmd(startCmd)
|
||||
self.execActionStop()
|
||||
self.execActionStart()
|
||||
if not Action.executeCmd(checkCmd):
|
||||
logSys.fatal("Unable to restore environment")
|
||||
return False
|
||||
|
||||
# Replace tags
|
||||
if not aInfo == None:
|
||||
if not aInfo is None:
|
||||
realCmd = Action.replaceTag(cmd, aInfo)
|
||||
else:
|
||||
realCmd = cmd
|
||||
|
|
|
@ -19,11 +19,8 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
|
|
@ -19,17 +19,14 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
from pickle import dumps, loads, HIGHEST_PROTOCOL
|
||||
from common import helpers
|
||||
import asyncore, asynchat, socket, os, logging, sys, traceback
|
||||
import asyncore, asynchat, socket, os, logging, sys, traceback, fcntl
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.server")
|
||||
|
@ -107,6 +104,7 @@ class AsyncServer(asyncore.dispatcher):
|
|||
except TypeError:
|
||||
logSys.warning("Type error")
|
||||
return
|
||||
AsyncServer.__markCloseOnExec(conn)
|
||||
# Creates an instance of the handler class to handle the
|
||||
# request/response on the incoming connection.
|
||||
RequestHandler(conn, self.__transmitter)
|
||||
|
@ -134,6 +132,7 @@ class AsyncServer(asyncore.dispatcher):
|
|||
self.bind(sock)
|
||||
except Exception:
|
||||
raise AsyncServerException("Unable to bind socket %s" % self.__sock)
|
||||
AsyncServer.__markCloseOnExec(self.socket)
|
||||
self.listen(1)
|
||||
# Sets the init flag.
|
||||
self.__init = True
|
||||
|
@ -159,6 +158,18 @@ class AsyncServer(asyncore.dispatcher):
|
|||
os.remove(self.__sock)
|
||||
logSys.debug("Socket shutdown")
|
||||
|
||||
##
|
||||
# Marks socket as close-on-exec to avoid leaking file descriptors when
|
||||
# running actions involving command execution.
|
||||
|
||||
# @param sock: socket file.
|
||||
|
||||
#@staticmethod
|
||||
def __markCloseOnExec(sock):
|
||||
fd = sock.fileno()
|
||||
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFD, flags|fcntl.FD_CLOEXEC)
|
||||
__markCloseOnExec = staticmethod(__markCloseOnExec)
|
||||
|
||||
##
|
||||
# AsyncServerException is used to wrap communication exceptions.
|
||||
|
|
|
@ -19,11 +19,8 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
@ -148,7 +145,7 @@ class BanManager:
|
|||
def addBanTicket(self, ticket):
|
||||
try:
|
||||
self.__lock.acquire()
|
||||
if not self.__inBanList(ticket):
|
||||
if not self._inBanList(ticket):
|
||||
self.__banList.append(ticket)
|
||||
self.__banTotal += 1
|
||||
return True
|
||||
|
@ -177,7 +174,7 @@ class BanManager:
|
|||
# @param ticket the ticket
|
||||
# @return True if a ticket already exists
|
||||
|
||||
def __inBanList(self, ticket):
|
||||
def _inBanList(self, ticket):
|
||||
for i in self.__banList:
|
||||
if ticket.getIP() == i.getIP():
|
||||
return True
|
||||
|
|
|
@ -17,13 +17,7 @@
|
|||
# along with Fail2Ban; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__author__ = "Cyril Jaquier and Fail2Ban Contributors"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
@ -155,6 +149,18 @@ class DateDetector:
|
|||
template.setRegex("^<\d{2}/\d{2}/\d{2}@\d{2}:\d{2}:\d{2}>")
|
||||
template.setPattern("<%m/%d/%y@%H:%M:%S>")
|
||||
self._appendTemplate(template)
|
||||
# MySQL: 130322 11:46:11
|
||||
template = DateStrptime()
|
||||
template.setName("MonthDayYear Hour:Minute:Second")
|
||||
template.setRegex("^\d{2}\d{2}\d{2} +\d{1,2}:\d{2}:\d{2}")
|
||||
template.setPattern("%y%m%d %H:%M:%S")
|
||||
self._appendTemplate(template)
|
||||
# ASSP: Apr-27-13 02:33:06
|
||||
template = DateStrptime()
|
||||
template.setName("Month-Day-Year Hour:Minute:Second")
|
||||
template.setRegex("^[a-zA-Z]{3}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}")
|
||||
template.setPattern("%b-%d-%y %H:%M:%S")
|
||||
self._appendTemplate(template)
|
||||
finally:
|
||||
self.__lock.release()
|
||||
|
||||
|
@ -191,10 +197,7 @@ class DateDetector:
|
|||
|
||||
def getUnixTime(self, line):
|
||||
date = self.getTime(line)
|
||||
if date == None:
|
||||
return None
|
||||
else:
|
||||
return time.mktime(date)
|
||||
return date and time.mktime(date)
|
||||
|
||||
##
|
||||
# Sort the template lists using the hits score. This method is not called
|
||||
|
|
|
@ -19,11 +19,8 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
@ -65,7 +62,7 @@ class DateTemplate:
|
|||
|
||||
def matchDate(self, line):
|
||||
dateMatch = self.__cRegex.search(line)
|
||||
if not dateMatch == None:
|
||||
if not dateMatch is None:
|
||||
self.__hits += 1
|
||||
return dateMatch
|
||||
|
||||
|
@ -218,3 +215,4 @@ class DateISO8601(DateTemplate):
|
|||
value = dateMatch.group()
|
||||
date = list(iso8601.parse_date(value).timetuple())
|
||||
return date
|
||||
|
||||
|
|
|
@ -19,11 +19,8 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
|
|
@ -19,11 +19,8 @@
|
|||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
|
|
@ -17,13 +17,7 @@
|
|||
# along with Fail2Ban; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
@ -125,7 +119,7 @@ class FailRegex(Regex):
|
|||
|
||||
def getHost(self):
|
||||
host = self._matchCache.group("host")
|
||||
if host == None:
|
||||
if host is None:
|
||||
# Gets a few information.
|
||||
s = self._matchCache.string
|
||||
r = self._matchCache.re
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue