Compare commits
21
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de27944089 | ||
|
|
00d022f9cf | ||
|
|
f07a494f9c | ||
|
|
d1b0f6bc68 | ||
|
|
055d59a026 | ||
|
|
adc17f5062 | ||
|
|
12a3e23a0d | ||
|
|
e39084902b | ||
|
|
93d9a34d8b | ||
|
|
a8b53fc05f | ||
|
|
a2a1bd170d | ||
|
|
a2a5cdb329 | ||
|
|
624f357cf5 | ||
|
|
c12f6be991 | ||
|
|
ce1ef568b1 | ||
|
|
553d9dfc79 | ||
|
|
4153272dfd | ||
|
|
3878e9de84 | ||
|
|
4dd4e76568 | ||
|
|
6e27a9d4dd | ||
|
|
9f5bbd82cb |
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>fail2ban-unstable</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.python.pydev.PyDevBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.python.pydev.pythonNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,3 +0,0 @@
|
||||
#Wed Sep 20 22:14:25 GMT 2006
|
||||
eclipse.preferences.version=1
|
||||
encoding//server/datestrptime.py=UTF-8
|
||||
@@ -1,260 +0,0 @@
|
||||
__ _ _ ___ _
|
||||
/ _|__ _(_) |_ ) |__ __ _ _ _
|
||||
| _/ _` | | |/ /| '_ \/ _` | ' \
|
||||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||
|
||||
=============================================================
|
||||
Fail2Ban (version 0.7.4) 2006/11/01
|
||||
=============================================================
|
||||
|
||||
ver. 0.7.4 (2006/11/01) - beta
|
||||
----------
|
||||
- Improved configuration files. Thanks to Yaroslav Halchenko
|
||||
- Added man page for "fail2ban-regex"
|
||||
- Moved ban/unban messages from "info" level to "warn"
|
||||
- Added "-s" option to specify the socket path and "socket"
|
||||
option in "fail2ban.conf"
|
||||
- Added "backend" option in "jail.conf"
|
||||
- Added more filters/actions and jail samples. Thanks to Nick
|
||||
Munger, Christoph Haas
|
||||
- Improved testing framework
|
||||
- Fixed a bug in the return code handling of the executed
|
||||
commands. Thanks to Yaroslav Halchenko
|
||||
- Signal handling. There is a bug with join() and signal in
|
||||
Python
|
||||
- Better debugging output for "fail2ban-regex"
|
||||
- Added support for more date format
|
||||
- cPickle does not work with Python 2.5. Use pickle instead
|
||||
(performance is not a problem in our case)
|
||||
|
||||
ver. 0.7.3 (2006/09/28) - beta
|
||||
----------
|
||||
- Added man pages. Thanks to Yaroslav Halchenko
|
||||
- Added wildcard support for "logpath"
|
||||
- Added Gamin (file and directory monitoring system) support
|
||||
- (Re)added "ignoreip" option
|
||||
- Added more concurrency protection
|
||||
- First attempt at solving bug #1457620 (locale issue)
|
||||
- Performance improvements
|
||||
- (Re)added permanent banning with banTime < 0
|
||||
- Added DNS support to "ignoreip". Feature Request #1285859
|
||||
|
||||
ver. 0.7.2 (2006/09/10) - beta
|
||||
----------
|
||||
- Refactoring and code cleanup
|
||||
- Improved client output
|
||||
- Added more get/set commands
|
||||
- Added more configuration templates
|
||||
- Removed "logpath" and "maxretry" from filter templates.
|
||||
They must be defined in jail.conf now
|
||||
- Added interactive mode. Use "-i"
|
||||
- Added a date detector. "timeregex" and "timepattern" are no
|
||||
more needed
|
||||
- Added "fail2ban-regex". This is a tool to help finding
|
||||
"failregex"
|
||||
- Improved server communication. Start a new thread for each
|
||||
incoming request. Fail2ban is not really thread-safe yet
|
||||
|
||||
ver. 0.7.1 (2006/08/23) - alpha
|
||||
----------
|
||||
- Fixed daemon mode bug
|
||||
- Added Gentoo init.d script
|
||||
- Fixed path bug when trying to start "fail2ban-server"
|
||||
- Fixed reload command
|
||||
|
||||
ver. 0.7.0 (2006/08/23) - alpha
|
||||
----------
|
||||
- Almost a complete rewrite :) Fail2ban design is really
|
||||
better (IMHO). There is a lot of new features
|
||||
- Client/Server architecture
|
||||
- Multithreading. Each jail has its own threads: one for the
|
||||
log reading and another for the actions
|
||||
- Execute several actions
|
||||
- Split configuration files. They are more readable and easy
|
||||
to use
|
||||
- failregex uses group (<host>) now. This feature was already
|
||||
present in the Debian package
|
||||
- lots of things...
|
||||
|
||||
ver. 0.6.1 (2006/03/16) - stable
|
||||
----------
|
||||
- Added permanent banning. Set banTime to a negative value to
|
||||
enable this feature (-1 is perfect). Thanks to Mannone
|
||||
- Fixed locale bug. Thanks to Fernando José
|
||||
- Fixed crash when time format does not match data
|
||||
- Propagated patch from Debian to fix fail2ban search path
|
||||
addition to the path search list: now it is added first.
|
||||
Thanks to Nick Craig-Wood
|
||||
- Added SMTP authentification for mail notification. Thanks
|
||||
to Markus Hoffmann
|
||||
- Removed debug mode as it is confusing for people
|
||||
- Added parsing of timestamp in TAI64N format (#1275325).
|
||||
Thanks to Mark Edgington
|
||||
- Added patch #1382936 (Default formatted syslog logging).
|
||||
Thanks to Patrick B�rjesson
|
||||
- Removed 192.168.0.0/16 from ignoreip. Attacks could also
|
||||
come from the local network.
|
||||
- Robust startup: if iptables module does not get fully
|
||||
initialized after startup of fail2ban, fail2ban will do
|
||||
"maxreinit" attempts to initialize its own firewall. It
|
||||
will sleep between attempts for "polltime" number of
|
||||
seconds (closes Debian: #334272). Thanks to Yaroslav
|
||||
Halchenko
|
||||
- Added "interpolations" in fail2ban.conf. This is provided
|
||||
by the ConfigParser module. Old configuration files still
|
||||
work. Thanks to Yaroslav Halchenko
|
||||
- Added initial support for hosts.deny and shorewall. Need
|
||||
more testing. Please test. Thanks to kojiro from Gentoo
|
||||
forum for hosts.deny support
|
||||
- Added support for vsftpd. Thanks to zugeschmiert
|
||||
|
||||
ver. 0.6.0 (2005/11/20) - stable
|
||||
----------
|
||||
- Propagated patches introduced by Debian maintainer
|
||||
(Yaroslav Halchenko):
|
||||
* Added an option to report local time (including timezone)
|
||||
or GMT in mail notification.
|
||||
|
||||
ver. 0.5.5 (2005/10/26) - beta
|
||||
----------
|
||||
- Propagated patches introduced by Debian maintainer
|
||||
(Yaroslav Halchenko):
|
||||
* Introduced fwcheck option to verify consistency of the
|
||||
chains. Implemented automatic restart of fail2ban main
|
||||
function in case check of fwban or fwunban command failed
|
||||
(closes: #329163, #331695). (Introduced patch was further
|
||||
adjusted by upstream author).
|
||||
* Added -f command line parameter for [findtime].
|
||||
* Added a cleanup of firewall rules on emergency shutdown
|
||||
when unknown exception is catched.
|
||||
* Fail2ban should not crash now if a wrong file name is
|
||||
specified in config.
|
||||
* reordered code a bit so that log targets are setup right
|
||||
after background and then only loglevel (verbose, debug)
|
||||
is processed, so the warning could be seen in the logs
|
||||
* Added a keyword <section> in parsing of the subject and
|
||||
the body of an email sent out by fail2ban (closes:
|
||||
#330311)
|
||||
|
||||
ver. 0.5.4 (2005/09/13) - beta
|
||||
----------
|
||||
- Fixed bug #1286222.
|
||||
- Propagated patches introduced by Debian maintainer
|
||||
(Yaroslav Halchenko):
|
||||
* Fixed handling of SYSLOG logging target. Now it can log
|
||||
to any SYSLOG target and facility as directed by the
|
||||
config
|
||||
* Format of SYSLOG entries fixed to look closer to standard
|
||||
* Fixed errata in config/gentoo-confd
|
||||
* Introduced findtime configuration variable to control the
|
||||
lifetime of caught "failed" log entries
|
||||
|
||||
ver. 0.5.3 (2005/09/08) - beta
|
||||
----------
|
||||
- Fixed a bug when overriding "maxfailures" or "bantime".
|
||||
Thanks to Yaroslav Halchenko
|
||||
- Added more debug output if an error occurs when sending
|
||||
mail. Thanks to Stephen Gildea
|
||||
- Renamed "maxretry" to "maxfailures" and changed default
|
||||
value to 5. Thanks to Stephen Gildea
|
||||
- Hopefully fixed bug #1256075
|
||||
- Fixed bug #1262345
|
||||
- Fixed exception handling in PIDLock
|
||||
- Removed warning when using "-V" or "-h" with no config
|
||||
file. Thanks to Yaroslav Halchenko
|
||||
- Removed "-i eth0" from config file. Thanks to Yaroslav
|
||||
Halchenko
|
||||
|
||||
ver. 0.5.2 (2005/08/06) - beta
|
||||
----------
|
||||
- Better PID lock file handling. Should close #1239562
|
||||
- Added man pages
|
||||
- Removed log4py dependency. Use logging module instead
|
||||
- "maxretry" and "bantime" can be overridden in each section
|
||||
- Fixed bug #1246278 (excessive memory usage)
|
||||
- Fixed crash on wrong option value in configuration file
|
||||
- Changed custom chains to lowercase
|
||||
|
||||
ver. 0.5.1 (2005/07/23) - beta
|
||||
----------
|
||||
- Fixed bugs #1241756, #1239557
|
||||
- Added log targets in configuration file. Removed -l option
|
||||
- Changed iptables rules in order to create a separated chain
|
||||
for each section
|
||||
- Fixed static banList in firewall.py
|
||||
- Added an initd script for Debian. Thanks to Yaroslav
|
||||
Halchenko
|
||||
- Check for obsolete files after install
|
||||
|
||||
ver. 0.5.0 (2005/07/12) - beta
|
||||
----------
|
||||
- Added support for CIDR mask in ignoreip
|
||||
- Added mail notification support
|
||||
- Fixed bug #1234699
|
||||
- Added tags replacement in rules definition. Should allow a
|
||||
clean solution for Feature Request #1229479
|
||||
- Removed "interface" and "firewall" options
|
||||
- Added start and end commands in the configuration file.
|
||||
Thanks to Yaroslav Halchenko
|
||||
- Added firewall rules definition in the configuration file
|
||||
- Cleaned fail2ban.py
|
||||
- Added an initd script for RedHat/Fedora. Thanks to Andrey
|
||||
G. Grozin
|
||||
|
||||
ver. 0.4.1 (2005/06/30) - stable
|
||||
----------
|
||||
- Fixed textToDNS method which generated wrong matches for
|
||||
"rhost=12-xyz...". Thanks to Tom Pike
|
||||
- fail2ban.conf modified for readability. Thanks to Iain Lea
|
||||
- Added an initd script for Gentoo
|
||||
- Changed default PID lock file location from /tmp to
|
||||
/var/run
|
||||
|
||||
ver. 0.4.0 (2005/04/24) - stable
|
||||
----------
|
||||
- Fixed textToDNS which did not recognize strings like
|
||||
"12-345-67-890.abcd.mnopqr.xyz"
|
||||
|
||||
ver. 0.3.1 (2005/03/31) - beta
|
||||
----------
|
||||
- Corrected level of messages
|
||||
- Added DNS lookup support
|
||||
- Improved parsing speed. Only parse the new log messages
|
||||
- Added a second verbose level (-vv)
|
||||
|
||||
ver. 0.3.0 (2005/02/24) - beta
|
||||
----------
|
||||
- Re-writting of parts of the code in order to handle several
|
||||
log files with different rules
|
||||
- Removed sshd.py because it is no more needed
|
||||
- Fixed a bug when exiting with IP in the ban list
|
||||
- Added PID lock file
|
||||
- Improved some parts of the code
|
||||
- Added ipfw-start-rule option (thanks to Robert Edeker)
|
||||
- Added -k option which kills a currently running Fail2Ban
|
||||
|
||||
ver. 0.1.2 (2004/11/21) - beta
|
||||
----------
|
||||
- Add ipfw and ipfwadm support. The rules are taken from
|
||||
BlockIt. Thanks to Robert Edeker
|
||||
- Add -e option which allows to set the interface. Thanks to
|
||||
Robert Edeker who reminded me this
|
||||
- Small code cleaning
|
||||
|
||||
ver. 0.1.1 (2004/10/23) - beta
|
||||
----------
|
||||
- Add SIGTERM handler in order to exit nicely when in daemon
|
||||
mode
|
||||
- Add -r option which allows to set the maximum number of
|
||||
login failures
|
||||
- Remove the Metalog class as the log file are not so syslog
|
||||
daemon specific
|
||||
- Rewrite log reader to be service centered. Sshd support
|
||||
added. Match "Failed password" and "Illegal user"
|
||||
- Add /etc/fail2ban.conf configuration support
|
||||
- Code documentation
|
||||
|
||||
|
||||
ver. 0.1.0 (2004/10/12) - alpha
|
||||
----------
|
||||
- Initial release
|
||||
@@ -1,83 +0,0 @@
|
||||
README
|
||||
CHANGELOG
|
||||
TODO
|
||||
fail2ban-client
|
||||
fail2ban-server
|
||||
fail2ban-testcases
|
||||
fail2ban-regex
|
||||
client/configreader.py
|
||||
client/jailreader.py
|
||||
client/fail2banreader.py
|
||||
client/jailsreader.py
|
||||
client/beautifier.py
|
||||
client/filterreader.py
|
||||
client/actionreader.py
|
||||
client/__init__.py
|
||||
client/configurator.py
|
||||
client/csocket.py
|
||||
server/ssocket.py
|
||||
server/banticket.py
|
||||
server/filter.py
|
||||
server/filtergamin.py
|
||||
server/filterpoll.py
|
||||
server/server.py
|
||||
server/datestrptime.py
|
||||
server/failticket.py
|
||||
server/actions.py
|
||||
server/datetai64n.py
|
||||
server/faildata.py
|
||||
server/failmanager.py
|
||||
server/datedetector.py
|
||||
server/jailthread.py
|
||||
server/transmitter.py
|
||||
server/action.py
|
||||
server/ticket.py
|
||||
server/jail.py
|
||||
server/jails.py
|
||||
server/__init__.py
|
||||
server/dateepoch.py
|
||||
server/banmanager.py
|
||||
server/datetemplate.py
|
||||
server/mytime.py
|
||||
testcases/banmanagertestcase.py
|
||||
testcases/failmanagertestcase.py
|
||||
testcases/clientreadertestcase.py
|
||||
testcases/filtertestcase.py
|
||||
testcases/__init__.py
|
||||
testcases/datedetectortestcase.py
|
||||
testcases/actiontestcase.py
|
||||
testcases/servertestcase.py
|
||||
testcases/files/testcase01.log
|
||||
testcases/files/testcase02.log
|
||||
testcases/files/testcase03.log
|
||||
testcases/files/testcase04.log
|
||||
setup.py
|
||||
setup.cfg
|
||||
version.py
|
||||
config/jail.conf
|
||||
config/filter.d/postfix.conf
|
||||
config/filter.d/vsftpd.conf
|
||||
config/filter.d/apache-auth.conf
|
||||
config/filter.d/apache-noscript.conf
|
||||
config/filter.d/qmail.conf
|
||||
config/filter.d/couriersmtp.conf
|
||||
config/filter.d/courierlogin.conf
|
||||
config/filter.d/sshd.conf
|
||||
config/filter.d/proftpd.conf
|
||||
config/filter.d/sasl.conf
|
||||
config/action.d/iptables.conf
|
||||
config/action.d/ipfw.conf
|
||||
config/action.d/mail-whois.conf
|
||||
config/action.d/mail.conf
|
||||
config/action.d/hostsdeny.conf
|
||||
config/action.d/shorewall.conf
|
||||
config/fail2ban.conf
|
||||
man/fail2ban-client.1
|
||||
man/fail2ban-client.h2m
|
||||
man/fail2ban-server.1
|
||||
man/fail2ban-server.h2m
|
||||
man/fail2ban-regex.1
|
||||
man/fail2ban-regex.h2m
|
||||
man/generate-man
|
||||
files/gentoo-initd
|
||||
files/redhat-initd
|
||||
@@ -1,121 +0,0 @@
|
||||
__ _ _ ___ _
|
||||
/ _|__ _(_) |_ ) |__ __ _ _ _
|
||||
| _/ _` | | |/ /| '_ \/ _` | ' \
|
||||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||
|
||||
=============================================================
|
||||
Fail2Ban (version 0.7.4) 2006/11/01
|
||||
=============================================================
|
||||
|
||||
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.
|
||||
|
||||
Documentation, FAQ, HOWTOs are available on the project
|
||||
website: http://fail2ban.sourceforge.net
|
||||
|
||||
Installation:
|
||||
-------------
|
||||
|
||||
Required:
|
||||
>=python-2.4 (http://www.python.org)
|
||||
|
||||
Optional:
|
||||
>=gamin-0.0.21 (http://www.gnome.org/~veillard/gamin)
|
||||
|
||||
To install, just do:
|
||||
|
||||
> tar xvfj fail2ban-0.7.4.tar.bz2
|
||||
> cd fail2ban-0.7.4
|
||||
> python setup.py install
|
||||
|
||||
This will install Fail2Ban into /usr/lib/fail2ban. The
|
||||
executable scripts are placed into /usr/bin.
|
||||
|
||||
Gentoo: ebuilds are available on the website.
|
||||
Debian: Fail2Ban is in Debian unstable.
|
||||
RedHat: packages are available on the website.
|
||||
|
||||
Fail2Ban should now be correctly installed. Just type:
|
||||
|
||||
> fail2ban-client -h
|
||||
|
||||
to see if everything is alright.
|
||||
|
||||
Configuration:
|
||||
--------------
|
||||
|
||||
You can configure fail2ban using the files in /etc/fail2ban
|
||||
or using command line. Here are the available command line
|
||||
options (not complete yet):
|
||||
|
||||
Options:
|
||||
-c <DIR> configuration directory
|
||||
-s <FILE> socket path
|
||||
-d dump configuration. For debugging
|
||||
-i interactive mode
|
||||
-v increase verbosity
|
||||
-q decrease verbosity
|
||||
-x force execution of the server
|
||||
-h, --help display this help message
|
||||
-V, --version print the version
|
||||
|
||||
Command:
|
||||
start start the server and the jails
|
||||
reload reload the configuration
|
||||
stop stop all jails and terminate the
|
||||
server
|
||||
status get the current status
|
||||
|
||||
set loglevel <LEVEL> set loglevel to <LEVEL>
|
||||
get loglevel get loglevel
|
||||
set logtarget <TARGET> set log target to <TARGET>
|
||||
get logtarget get log target
|
||||
|
||||
add <JAIL> [BACKEND] create <JAIL> using [BACKEND]
|
||||
set <JAIL> <CMD> set the <CMD> value for <JAIL>
|
||||
get <JAIL> <CMD> get the <CMD> value for <JAIL>
|
||||
start <JAIL> start <JAIL>
|
||||
stop <JAIL> stop <JAIL>. The jail is removed
|
||||
status <JAIL> get the current status of <JAIL>
|
||||
|
||||
Contact:
|
||||
--------
|
||||
|
||||
You need some new features, you found bugs or you just
|
||||
appreciate this program, you can contact me at :
|
||||
|
||||
Website: http://fail2ban.sourceforge.net
|
||||
|
||||
Cyril Jaquier: <lostcontrol@users.sourceforge.net>
|
||||
|
||||
Thanks:
|
||||
-------
|
||||
|
||||
Kévin Drapel, Marvin Rouge, Sireyessire, Robert Edeker,
|
||||
Tom Pike, Iain Lea, Andrey G. Grozin, Yaroslav Halchenko,
|
||||
Jonathan Kamens, Stephen Gildea, Markus Hoffmann, Mark
|
||||
Edgington, Patrick Börjesson, kojiro, zugeschmiert, Tyler,
|
||||
Nick Munger, Christoph Haas
|
||||
|
||||
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., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
@@ -1,39 +0,0 @@
|
||||
__ _ _ ___ _
|
||||
/ _|__ _(_) |_ ) |__ __ _ _ _
|
||||
| _/ _` | | |/ /| '_ \/ _` | ' \
|
||||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||
|
||||
=============================================================
|
||||
ToDo $Revision$
|
||||
=============================================================
|
||||
|
||||
Legend:
|
||||
- not yet done
|
||||
? maybe
|
||||
# partially done
|
||||
* done
|
||||
|
||||
- Add gettext support (I8N)
|
||||
|
||||
- Fix the cPickle issue with Python 2.5
|
||||
|
||||
- Multiline log reading
|
||||
|
||||
- Improve communication. (asyncore, asynchat??)
|
||||
|
||||
- Improve execution of action. Why does subprocess.call
|
||||
deadlock with multi-jails?
|
||||
|
||||
# see Feature Request Tracking System at SourceForge.net
|
||||
|
||||
- improve installation process (better prefix support)
|
||||
|
||||
# improve documentation and website for user
|
||||
|
||||
# better return values in function
|
||||
|
||||
? restart automatically the daemon if an exception occurs.
|
||||
|
||||
- do not close socket after a send
|
||||
|
||||
# refactoring in server.py, actions.py, filter.py
|
||||
@@ -1,25 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
@@ -1,90 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import logging
|
||||
from configreader import ConfigReader
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
|
||||
class ActionReader(ConfigReader):
|
||||
|
||||
def __init__(self, action, name):
|
||||
ConfigReader.__init__(self)
|
||||
self.__file = action[0]
|
||||
self.__cInfo = action[1]
|
||||
self.__name = name
|
||||
|
||||
def setFile(self, fileName):
|
||||
self.__file = fileName
|
||||
|
||||
def getFile(self):
|
||||
return self.__file
|
||||
|
||||
def setName(self, name):
|
||||
self.__name = name
|
||||
|
||||
def getName(self):
|
||||
return self.__name
|
||||
|
||||
def read(self):
|
||||
return ConfigReader.read(self, "action.d/" + self.__file)
|
||||
|
||||
def getOptions(self, pOpts):
|
||||
opts = [["string", "actionstart", ""],
|
||||
["string", "actionstop", ""],
|
||||
["string", "actioncheck", ""],
|
||||
["string", "actionban", ""],
|
||||
["string", "actionunban", ""]]
|
||||
self.__opts = ConfigReader.getOptions(self, "Definition", opts, pOpts)
|
||||
|
||||
if self.has_section("Init"):
|
||||
for opt in self.options("Init"):
|
||||
if not self.__cInfo.has_key(opt):
|
||||
self.__cInfo[opt] = self.get("Init", opt)
|
||||
|
||||
def convert(self):
|
||||
head = ["set", self.__name]
|
||||
stream = list()
|
||||
stream.append(head + ["addaction", self.__file])
|
||||
for opt in self.__opts:
|
||||
if opt == "actionstart":
|
||||
stream.append(head + ["actionstart", self.__file, self.__opts[opt]])
|
||||
elif opt == "actionstop":
|
||||
stream.append(head + ["actionstop", self.__file, self.__opts[opt]])
|
||||
elif opt == "actioncheck":
|
||||
stream.append(head + ["actioncheck", self.__file, self.__opts[opt]])
|
||||
elif opt == "actionban":
|
||||
stream.append(head + ["actionban", self.__file, self.__opts[opt]])
|
||||
elif opt == "actionunban":
|
||||
stream.append(head + ["actionunban", self.__file, self.__opts[opt]])
|
||||
# cInfo
|
||||
if self.__cInfo:
|
||||
for p in self.__cInfo:
|
||||
stream.append(head + ["setcinfo", self.__file, p, self.__cInfo[p]])
|
||||
|
||||
return stream
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 288 $
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision: 288 $"
|
||||
__date__ = "$Date: 2006-08-22 23:59:51 +0200 (Tue, 22 Aug 2006) $"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
from server.jails import UnknownJailException
|
||||
from server.jails import DuplicateJailException
|
||||
import logging
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
|
||||
##
|
||||
# Beautify the output of the client.
|
||||
#
|
||||
# Fail2ban server only return unformatted return codes which need to be
|
||||
# converted into user readable messages.
|
||||
|
||||
class Beautifier:
|
||||
|
||||
def __init__(self, cmd = None):
|
||||
self.__inputCmd = cmd
|
||||
|
||||
def setInputCmd(self, cmd):
|
||||
self.__inputCmd = cmd
|
||||
|
||||
def getInputCmd(self):
|
||||
return self.__inputCmd
|
||||
|
||||
def beautify(self, response):
|
||||
logSys.debug("Beautify " + `response` + " with " + `self.__inputCmd`)
|
||||
inC = self.__inputCmd
|
||||
msg = response
|
||||
try:
|
||||
if inC[0] == "ping":
|
||||
msg = "Server replied: " + response
|
||||
elif inC[0] == "start":
|
||||
msg = "Jail started"
|
||||
elif inC[0] == "stop":
|
||||
if len(inC) == 1:
|
||||
if response == None:
|
||||
msg = "Shutdown successful"
|
||||
else:
|
||||
if response == None:
|
||||
msg = "Jail stopped"
|
||||
elif inC[0] == "add":
|
||||
msg = "Added jail " + response
|
||||
elif inC[0:1] == ['status']:
|
||||
if len(inC) > 1:
|
||||
msg = "Status for the jail: " + inC[1] + "\n"
|
||||
msg = msg + "|- " + response[0][0] + "\n"
|
||||
msg = msg + "| |- " + response[0][1][0][0] + ":\t\t" + `response[0][1][0][1]` + "\n"
|
||||
msg = msg + "| `- " + response[0][1][1][0] + ":\t\t" + `response[0][1][1][1]` + "\n"
|
||||
msg = msg + "`- " + response[1][0] + "\n"
|
||||
msg = msg + " |- " + response[1][1][0][0] + ":\t\t" + `response[1][1][0][1]` + "\n"
|
||||
msg = msg + " `- " + response[1][1][1][0] + ":\t\t" + `response[1][1][1][1]`
|
||||
else:
|
||||
msg = "Status\n"
|
||||
msg = msg + "|- " + response[0][0] + ":\t" + `response[0][1]` + "\n"
|
||||
msg = msg + "`- " + response[1][0] + ":\t\t" + response[1][1]
|
||||
elif inC[1] == "logtarget":
|
||||
msg = "Current logging target is:\n"
|
||||
msg = msg + "`- " + response
|
||||
elif inC[1:2] == ['loglevel']:
|
||||
msg = "Current logging level is "
|
||||
if response == 1:
|
||||
msg = msg + "ERROR"
|
||||
elif response == 2:
|
||||
msg = msg + "WARN"
|
||||
elif response == 3:
|
||||
msg = msg + "INFO"
|
||||
elif response == 4:
|
||||
msg = msg + "DEBUG"
|
||||
else:
|
||||
msg = msg + `response`
|
||||
elif inC[2] in ("logpath", "addlogpath", "dellogpath"):
|
||||
if len(response) == 0:
|
||||
msg = "No file is currently monitored"
|
||||
else:
|
||||
msg = "Current monitored log file(s):\n"
|
||||
for path in response[:-1]:
|
||||
msg = msg + "|- " + path + "\n"
|
||||
msg = msg + "`- " + response[len(response)-1]
|
||||
elif inC[2] in ("ignoreip", "addignoreip", "delignoreip"):
|
||||
if len(response) == 0:
|
||||
msg = "No IP address/network is ignored"
|
||||
else:
|
||||
msg = "These IP addresses/networks are ignored:\n"
|
||||
for ip in response[:-1]:
|
||||
msg = msg + "|- " + ip + "\n"
|
||||
msg = msg + "`- " + response[len(response)-1]
|
||||
except Exception:
|
||||
logSys.warn("Beautifier error. Please report the error")
|
||||
logSys.error("Beautify " + `response` + " with " + `self.__inputCmd` +
|
||||
" failed")
|
||||
msg = msg + `response`
|
||||
return msg
|
||||
|
||||
def beautifyError(self, response):
|
||||
logSys.debug("Beautify (error) " + `response` + " with " + `self.__inputCmd`)
|
||||
msg = response
|
||||
if isinstance(response, UnknownJailException):
|
||||
msg = "Sorry but the jail '" + response[0] + "' does not exist"
|
||||
elif isinstance(response, IndexError):
|
||||
msg = "Sorry but the command is invalid"
|
||||
elif isinstance(response, DuplicateJailException):
|
||||
msg = "The jail '" + response[0] + "' already exists"
|
||||
return msg
|
||||
@@ -1,97 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import logging, os
|
||||
from ConfigParser import SafeConfigParser
|
||||
from ConfigParser import NoOptionError, NoSectionError
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
|
||||
class ConfigReader(SafeConfigParser):
|
||||
|
||||
BASE_DIRECTORY = "/etc/fail2ban/"
|
||||
|
||||
def __init__(self):
|
||||
SafeConfigParser.__init__(self)
|
||||
self.__opts = None
|
||||
|
||||
@staticmethod
|
||||
def setBaseDir(folderName):
|
||||
path = folderName.rstrip('/')
|
||||
ConfigReader.BASE_DIRECTORY = path + '/'
|
||||
|
||||
@staticmethod
|
||||
def getBaseDir():
|
||||
return ConfigReader.BASE_DIRECTORY
|
||||
|
||||
def read(self, filename):
|
||||
basename = ConfigReader.BASE_DIRECTORY + filename
|
||||
logSys.debug("Reading " + basename)
|
||||
bConf = basename + ".conf"
|
||||
bLocal = basename + ".local"
|
||||
if os.path.exists(bConf) or os.path.exists(bLocal):
|
||||
SafeConfigParser.read(self, [bConf, bLocal])
|
||||
return True
|
||||
else:
|
||||
logSys.error(bConf + " and " + bLocal + " do not exist")
|
||||
return False
|
||||
|
||||
##
|
||||
# Read the options.
|
||||
#
|
||||
# Read the given option in the configuration file. Default values
|
||||
# are used...
|
||||
# Each optionValues entry is composed of an array with:
|
||||
# 0 -> the type of the option
|
||||
# 1 -> the name of the option
|
||||
# 2 -> the default value for the option
|
||||
def getOptions(self, sec, options, pOptions = None):
|
||||
values = dict()
|
||||
for option in options:
|
||||
try:
|
||||
if option[0] == "bool":
|
||||
v = self.getboolean(sec, option[1])
|
||||
elif option[0] == "int":
|
||||
v = self.getint(sec, option[1])
|
||||
else:
|
||||
v = self.get(sec, option[1])
|
||||
if not pOptions == None and option[1] in pOptions:
|
||||
continue
|
||||
values[option[1]] = v
|
||||
except NoSectionError, e:
|
||||
# No "Definition" section or wrong basedir
|
||||
logSys.error(e)
|
||||
values[option[1]] = option[2]
|
||||
except NoOptionError:
|
||||
if not option[2] == None:
|
||||
logSys.warn("No '" + option[1] + "' defined in '" + sec + "'")
|
||||
values[option[1]] = option[2]
|
||||
except ValueError:
|
||||
logSys.warn("Wrong value for '" + option[1] + "' in '" + sec +
|
||||
"'. Using default one: '" + `option[2]` + "'")
|
||||
values[option[1]] = option[2]
|
||||
return values
|
||||
@@ -1,76 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import logging
|
||||
from configreader import ConfigReader
|
||||
from fail2banreader import Fail2banReader
|
||||
from jailsreader import JailsReader
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
|
||||
class Configurator:
|
||||
|
||||
def __init__(self):
|
||||
self.__settings = dict()
|
||||
self.__streams = dict()
|
||||
self.__fail2ban = Fail2banReader()
|
||||
self.__jails = JailsReader()
|
||||
|
||||
@staticmethod
|
||||
def setBaseDir(folderName):
|
||||
ConfigReader.setBaseDir(folderName)
|
||||
|
||||
@staticmethod
|
||||
def getBaseDir():
|
||||
return ConfigReader.getBaseDir()
|
||||
|
||||
def readEarly(self):
|
||||
self.__fail2ban.read()
|
||||
|
||||
def readAll(self):
|
||||
self.readEarly()
|
||||
self.__jails.read()
|
||||
|
||||
def getEarlyOptions(self):
|
||||
return self.__fail2ban.getEarlyOptions()
|
||||
|
||||
def getAllOptions(self):
|
||||
self.__fail2ban.getOptions()
|
||||
self.__jails.getOptions()
|
||||
|
||||
def convertToProtocol(self):
|
||||
self.__streams["general"] = self.__fail2ban.convert()
|
||||
self.__streams["jails"] = self.__jails.convert()
|
||||
|
||||
def getConfigStream(self):
|
||||
cmds = list()
|
||||
for opt in self.__streams["general"]:
|
||||
cmds.append(opt)
|
||||
for opt in self.__streams["jails"]:
|
||||
cmds.append(opt)
|
||||
return cmds
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
#from cPickle import dumps, loads, HIGHEST_PROTOCOL
|
||||
from pickle import dumps, loads, HIGHEST_PROTOCOL
|
||||
import socket
|
||||
|
||||
class CSocket:
|
||||
|
||||
END_STRING = "<F2B_END_COMMAND>"
|
||||
|
||||
def __init__(self, sock = "/tmp/fail2ban.sock"):
|
||||
# Create an INET, STREAMing socket
|
||||
#self.csock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.__csock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
#self.csock.connect(("localhost", 2222))
|
||||
self.__csock.connect(sock)
|
||||
|
||||
def send(self, msg):
|
||||
# Convert every list member to string
|
||||
obj = dumps(map(str, msg), HIGHEST_PROTOCOL)
|
||||
self.__csock.send(obj + CSocket.END_STRING)
|
||||
ret = self.receive(self.__csock)
|
||||
self.__csock.close()
|
||||
return ret
|
||||
|
||||
@staticmethod
|
||||
def receive(sock):
|
||||
msg = ''
|
||||
while msg.rfind(CSocket.END_STRING) == -1:
|
||||
chunk = sock.recv(6)
|
||||
if chunk == '':
|
||||
raise RuntimeError, "socket connection broken"
|
||||
msg = msg + chunk
|
||||
return loads(msg)
|
||||
@@ -1,58 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import logging
|
||||
from configreader import ConfigReader
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
|
||||
class Fail2banReader(ConfigReader):
|
||||
|
||||
def __init__(self):
|
||||
ConfigReader.__init__(self)
|
||||
|
||||
def read(self):
|
||||
ConfigReader.read(self, "fail2ban")
|
||||
|
||||
def getEarlyOptions(self):
|
||||
opts = [["string", "socket", "/tmp/fail2ban.sock"]]
|
||||
return ConfigReader.getOptions(self, "Definition", opts)
|
||||
|
||||
def getOptions(self):
|
||||
opts = [["int", "loglevel", 1],
|
||||
["string", "logtarget", "STDERR"]]
|
||||
self.__opts = ConfigReader.getOptions(self, "Definition", opts)
|
||||
|
||||
def convert(self):
|
||||
stream = list()
|
||||
for opt in self.__opts:
|
||||
if opt == "loglevel":
|
||||
stream.append(["set", "loglevel", self.__opts[opt]])
|
||||
elif opt == "logtarget":
|
||||
stream.append(["set", "logtarget", self.__opts[opt]])
|
||||
return stream
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import logging
|
||||
from configreader import ConfigReader
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
|
||||
class FilterReader(ConfigReader):
|
||||
|
||||
def __init__(self, fileName, name):
|
||||
ConfigReader.__init__(self)
|
||||
self.__file = fileName
|
||||
self.__name = name
|
||||
|
||||
def setFile(self, fileName):
|
||||
self.__file = fileName
|
||||
|
||||
def getFile(self):
|
||||
return self.__file
|
||||
|
||||
def setName(self, name):
|
||||
self.__name = name
|
||||
|
||||
def getName(self):
|
||||
return self.__name
|
||||
|
||||
def read(self):
|
||||
return ConfigReader.read(self, "filter.d/" + self.__file)
|
||||
|
||||
def getOptions(self, pOpts):
|
||||
opts = [["string", "timeregex", None],
|
||||
["string", "timepattern", None],
|
||||
["string", "failregex", ""]]
|
||||
self.__opts = ConfigReader.getOptions(self, "Definition", opts, pOpts)
|
||||
|
||||
def convert(self):
|
||||
stream = list()
|
||||
for opt in self.__opts:
|
||||
if opt == "timeregex":
|
||||
stream.append(["set", self.__name, "timeregex", self.__opts[opt]])
|
||||
elif opt == "timepattern":
|
||||
stream.append(["set", self.__name, "timepattern", self.__opts[opt]])
|
||||
elif opt == "failregex":
|
||||
stream.append(["set", self.__name, "failregex", self.__opts[opt]])
|
||||
return stream
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import logging, re, glob
|
||||
|
||||
from configreader import ConfigReader
|
||||
from filterreader import FilterReader
|
||||
from actionreader import ActionReader
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
|
||||
class JailReader(ConfigReader):
|
||||
|
||||
actionCRE = re.compile("^((?:\w|-|_|\.)+)(?:\[(.*)\])?$")
|
||||
|
||||
def __init__(self, name):
|
||||
ConfigReader.__init__(self)
|
||||
self.__name = name
|
||||
self.__filter = None
|
||||
self.__actions = list()
|
||||
|
||||
def setName(self, value):
|
||||
self.__name = value
|
||||
|
||||
def getName(self):
|
||||
return self.__name
|
||||
|
||||
def read(self):
|
||||
ConfigReader.read(self, "jail")
|
||||
|
||||
def isEnabled(self):
|
||||
return self.__opts["enabled"]
|
||||
|
||||
def getOptions(self):
|
||||
opts = [["bool", "enabled", "false"],
|
||||
["string", "logpath", "/var/log/messages"],
|
||||
["string", "backend", "auto"],
|
||||
["int", "maxretry", 3],
|
||||
["int", "maxtime", 600],
|
||||
["int", "bantime", 600],
|
||||
["string", "ignoreip", None],
|
||||
["string", "filter", ""],
|
||||
["string", "action", ""]]
|
||||
self.__opts = ConfigReader.getOptions(self, self.__name, opts)
|
||||
|
||||
if self.isEnabled():
|
||||
# Read filter
|
||||
self.__filter = FilterReader(self.__opts["filter"], self.__name)
|
||||
ret = self.__filter.read()
|
||||
if ret:
|
||||
self.__filter.getOptions(self.__opts)
|
||||
else:
|
||||
logSys.error("Unable to read the filter")
|
||||
return False
|
||||
|
||||
# Read action
|
||||
for act in self.__opts["action"].split('\n'):
|
||||
try:
|
||||
splitAct = JailReader.splitAction(act)
|
||||
action = ActionReader(splitAct, self.__name)
|
||||
ret = action.read()
|
||||
if ret:
|
||||
action.getOptions(self.__opts)
|
||||
self.__actions.append(action)
|
||||
else:
|
||||
raise AttributeError("Unable to read action")
|
||||
except AttributeError, e:
|
||||
logSys.error("Error in action definition " + act)
|
||||
logSys.debug(e)
|
||||
return False
|
||||
return True
|
||||
|
||||
def convert(self):
|
||||
stream = []
|
||||
for opt in self.__opts:
|
||||
if opt == "logpath":
|
||||
for path in self.__opts[opt].split("\n"):
|
||||
pathList = glob.glob(path)
|
||||
if len(pathList) == 0:
|
||||
logSys.error("No file found for " + path)
|
||||
for p in pathList:
|
||||
stream.append(["set", self.__name, "addlogpath", p])
|
||||
elif opt == "backend":
|
||||
backend = self.__opts[opt]
|
||||
elif opt == "maxretry":
|
||||
stream.append(["set", self.__name, "maxretry", self.__opts[opt]])
|
||||
elif opt == "ignoreip":
|
||||
for ip in self.__opts[opt].split():
|
||||
stream.append(["set", self.__name, "addignoreip", ip])
|
||||
elif opt == "maxtime":
|
||||
stream.append(["set", self.__name, "maxtime", self.__opts[opt]])
|
||||
elif opt == "bantime":
|
||||
stream.append(["set", self.__name, "bantime", self.__opts[opt]])
|
||||
stream.extend(self.__filter.convert())
|
||||
for action in self.__actions:
|
||||
stream.extend(action.convert())
|
||||
stream.insert(0, ["add", self.__name, backend])
|
||||
return stream
|
||||
|
||||
@staticmethod
|
||||
def splitAction(action):
|
||||
m = JailReader.actionCRE.match(action)
|
||||
d = dict()
|
||||
if not m.group(2) == None:
|
||||
for param in m.group(2).split(','):
|
||||
p = param.split('=')
|
||||
try:
|
||||
d[p[0].strip()] = p[1].strip()
|
||||
except IndexError:
|
||||
logSys.error("Invalid argument %s in '%s'" % (p, m.group(2)))
|
||||
return [m.group(1), d]
|
||||
@@ -1,71 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import logging
|
||||
from configreader import ConfigReader
|
||||
from jailreader import JailReader
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
|
||||
class JailsReader(ConfigReader):
|
||||
|
||||
def __init__(self):
|
||||
ConfigReader.__init__(self)
|
||||
self.__jails = list()
|
||||
|
||||
def read(self):
|
||||
ConfigReader.read(self, "jail")
|
||||
|
||||
def getOptions(self):
|
||||
opts = []
|
||||
self.__opts = ConfigReader.getOptions(self, "Definition", opts)
|
||||
|
||||
for sec in self.sections():
|
||||
jail = JailReader(sec)
|
||||
jail.read()
|
||||
ret = jail.getOptions()
|
||||
if ret:
|
||||
if jail.isEnabled():
|
||||
# We only add enabled jails
|
||||
self.__jails.append(jail)
|
||||
else:
|
||||
logSys.error("Errors in jail '" + sec + "'. Skipping...")
|
||||
|
||||
def convert(self):
|
||||
stream = list()
|
||||
for opt in self.__opts:
|
||||
if opt == "":
|
||||
stream.append([])
|
||||
# Convert jails
|
||||
for jail in self.__jails:
|
||||
stream.extend(jail.convert())
|
||||
# Start jails
|
||||
for jail in self.__jails:
|
||||
stream.append(["start", jail.getName()])
|
||||
|
||||
return stream
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: fwstart
|
||||
# Notes.: command executed once at the start of Fail2Ban.
|
||||
# Values: CMD
|
||||
#
|
||||
actionstart = touch /tmp/fail2ban.dummy
|
||||
echo "<init>" >> /tmp/fail2ban.dummy
|
||||
|
||||
# Option: fwend
|
||||
# Notes.: command executed once at the end of Fail2Ban
|
||||
# Values: CMD
|
||||
#
|
||||
actionstop = rm /tmp/fail2ban.dummy
|
||||
|
||||
# Option: fwcheck
|
||||
# Notes.: command executed once before each fwban command
|
||||
# Values: CMD
|
||||
#
|
||||
actioncheck =
|
||||
|
||||
# Option: fwban
|
||||
# Notes.: command executed when banning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <failures> number of failures
|
||||
# <failtime> unix timestamp of the last failure
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionban = echo "+<ip>" >> /tmp/fail2ban.dummy
|
||||
|
||||
# Option: fwunban
|
||||
# Notes.: command executed when unbanning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# <unbantime> unix timestamp of the unban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionunban = echo "-<ip>" >> /tmp/fail2ban.dummy
|
||||
|
||||
[Init]
|
||||
|
||||
init = 123
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: fwstart
|
||||
# Notes.: command executed once at the start of Fail2Ban.
|
||||
# Values: CMD
|
||||
#
|
||||
actionstart = touch <tmpfile>
|
||||
|
||||
# Option: fwend
|
||||
# Notes.: command executed once at the end of Fail2Ban
|
||||
# Values: CMD
|
||||
#
|
||||
actionstop = rm -f <tmpfile>
|
||||
|
||||
# Option: fwcheck
|
||||
# Notes.: command executed once before each fwban command
|
||||
# Values: CMD
|
||||
#
|
||||
actioncheck =
|
||||
|
||||
# Option: fwban
|
||||
# Notes.: command executed when banning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <failures> number of failures
|
||||
# <failtime> unix timestamp of the last failure
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionban = IP=<ip> &&
|
||||
echo "ALL: $IP" >> <file>
|
||||
|
||||
# Option: fwunban
|
||||
# Notes.: command executed when unbanning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# <unbantime> unix timestamp of the unban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionunban = IP=<ip> &&
|
||||
grep -v "ALL: $IP" <file> > <tmpfile> &&
|
||||
mv <tmpfile> <file>
|
||||
|
||||
[Init]
|
||||
|
||||
# Option: file
|
||||
# Notes.: hosts.deny file path.
|
||||
# Values: STR Default: /etc/hosts.deny
|
||||
#
|
||||
file = /etc/hosts.deny
|
||||
|
||||
# Option: file
|
||||
# Notes.: hosts.deny temporary file path.
|
||||
# Values: STR Default: /etc/hostsdeny.failban
|
||||
#
|
||||
tmpfile = /tmp/hosts.deny.tmp
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Nick Munger
|
||||
# Modified by: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 254 $
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: fwstart
|
||||
# Notes.: command executed once at the start of Fail2Ban.
|
||||
# Values: CMD
|
||||
#
|
||||
actionstart =
|
||||
|
||||
|
||||
# Option: fwend
|
||||
# Notes.: command executed once at the end of Fail2Ban
|
||||
# Values: CMD
|
||||
#
|
||||
actionstop =
|
||||
|
||||
|
||||
# Option: fwcheck
|
||||
# Notes.: command executed once before each fwban command
|
||||
# Values: CMD
|
||||
#
|
||||
actioncheck =
|
||||
|
||||
|
||||
# Option: fwban
|
||||
# Notes.: command executed when banning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <failures> number of failures
|
||||
# <failtime> unix timestamp of the last failure
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionban = ipfw add deny tcp from <ip> to <localhost> <port>
|
||||
|
||||
|
||||
# Option: fwunban
|
||||
# Notes.: command executed when unbanning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# <unbantime> unix timestamp of the unban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionunban = ipfw delete `ipfw list | grep -i <ip> | awk '{print $1;}'`
|
||||
|
||||
[Init]
|
||||
|
||||
# Option: port
|
||||
# Notes.: specifies port to monitor
|
||||
# Values: [ NUM | STRING ]
|
||||
#
|
||||
port = ssh
|
||||
|
||||
# Option: localhost
|
||||
# Notes.: the local IP address of the network interface
|
||||
# Values: IP
|
||||
#
|
||||
localhost = 127.0.0.1
|
||||
@@ -1,70 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: fwstart
|
||||
# Notes.: command executed once at the start of Fail2Ban.
|
||||
# Values: CMD
|
||||
#
|
||||
actionstart = iptables -N fail2ban-<name>
|
||||
iptables -A fail2ban-<name> -j RETURN
|
||||
iptables -I INPUT -p <protocol> --dport <port> -j fail2ban-<name>
|
||||
|
||||
# Option: fwend
|
||||
# Notes.: command executed once at the end of Fail2Ban
|
||||
# Values: CMD
|
||||
#
|
||||
actionstop = iptables -D INPUT -p <protocol> --dport <port> -j fail2ban-<name>
|
||||
iptables -F fail2ban-<name>
|
||||
iptables -X fail2ban-<name>
|
||||
|
||||
# Option: fwcheck
|
||||
# Notes.: command executed once before each fwban command
|
||||
# Values: CMD
|
||||
#
|
||||
actioncheck = iptables -L INPUT | grep -q fail2ban-<name>
|
||||
|
||||
# Option: fwban
|
||||
# Notes.: command executed when banning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <failures> number of failures
|
||||
# <failtime> unix timestamp of the last failure
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
|
||||
|
||||
# Option: fwunban
|
||||
# Notes.: command executed when unbanning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# <unbantime> unix timestamp of the unban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
|
||||
|
||||
[Init]
|
||||
|
||||
# Defaut name of the chain
|
||||
#
|
||||
name = default
|
||||
|
||||
# Option: port
|
||||
# Notes.: specifies port to monitor
|
||||
# Values: [ NUM | STRING ] Default:
|
||||
#
|
||||
port = ssh
|
||||
|
||||
# Option: protocol
|
||||
# Notes.: internally used by config reader for interpolations.
|
||||
# Values: [ tcp | udp | icmp | all ] Default: tcp
|
||||
#
|
||||
protocol = tcp
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 254 $
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: fwstart
|
||||
# Notes.: command executed once at the start of Fail2Ban.
|
||||
# Values: CMD
|
||||
#
|
||||
actionstart = echo -en "Hi,\n
|
||||
The jail <name> has been started successfuly.\n
|
||||
Regards,\n
|
||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: started" <dest>
|
||||
|
||||
# Option: fwend
|
||||
# Notes.: command executed once at the end of Fail2Ban
|
||||
# Values: CMD
|
||||
#
|
||||
actionstop = echo -en "Hi,\n
|
||||
The jail <name> has been stopped.\n
|
||||
Regards,\n
|
||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped" <dest>
|
||||
|
||||
# Option: fwcheck
|
||||
# Notes.: command executed once before each fwban command
|
||||
# Values: CMD
|
||||
#
|
||||
actioncheck =
|
||||
|
||||
# Option: fwban
|
||||
# Notes.: command executed when banning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <failures> number of failures
|
||||
# <failtime> unix timestamp of the last failure
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionban = echo -en "Hi,\n
|
||||
The IP <ip> has just been banned by Fail2Ban after
|
||||
<failures> attempts against <name>.\n\n
|
||||
Here are more information about <ip>:\n
|
||||
`whois <ip>`\n
|
||||
Regards,\n
|
||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip>" <dest>
|
||||
|
||||
# Option: fwunban
|
||||
# Notes.: command executed when unbanning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# <unbantime> unix timestamp of the unban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionunban =
|
||||
|
||||
[Init]
|
||||
|
||||
# Defaut name of the chain
|
||||
#
|
||||
name = default
|
||||
|
||||
# Destinataire of the mail
|
||||
#
|
||||
dest = root
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 254 $
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: fwstart
|
||||
# Notes.: command executed once at the start of Fail2Ban.
|
||||
# Values: CMD
|
||||
#
|
||||
actionstart = echo -en "Hi,\n
|
||||
The jail <name> has been started successfuly.\n
|
||||
Regards,\n
|
||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: started" <dest>
|
||||
|
||||
# Option: fwend
|
||||
# Notes.: command executed once at the end of Fail2Ban
|
||||
# Values: CMD
|
||||
#
|
||||
actionstop = echo -en "Hi,\n
|
||||
The jail <name> has been stopped.\n
|
||||
Regards,\n
|
||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped" <dest>
|
||||
|
||||
# Option: fwcheck
|
||||
# Notes.: command executed once before each fwban command
|
||||
# Values: CMD
|
||||
#
|
||||
actioncheck =
|
||||
|
||||
# Option: fwban
|
||||
# Notes.: command executed when banning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <failures> number of failures
|
||||
# <failtime> unix timestamp of the last failure
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionban = echo -en "Hi,\n
|
||||
The IP <ip> has just been banned by Fail2Ban after
|
||||
<failures> attempts against <name>.\n
|
||||
Regards,\n
|
||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip>" <dest>
|
||||
|
||||
# Option: fwunban
|
||||
# Notes.: command executed when unbanning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# <unbantime> unix timestamp of the unban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionunban =
|
||||
|
||||
[Init]
|
||||
|
||||
# Defaut name of the chain
|
||||
#
|
||||
name = default
|
||||
|
||||
# Destinataire of the mail
|
||||
#
|
||||
dest = root
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 394 $
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: fwstart
|
||||
# Notes.: command executed once at the start of Fail2Ban.
|
||||
# Values: CMD
|
||||
#
|
||||
actionstart =
|
||||
|
||||
# Option: fwend
|
||||
# Notes.: command executed once at the end of Fail2Ban
|
||||
# Values: CMD
|
||||
#
|
||||
actionstop =
|
||||
|
||||
# Option: fwcheck
|
||||
# Notes.: command executed once before each fwban command
|
||||
# Values: CMD
|
||||
#
|
||||
actioncheck =
|
||||
|
||||
# Option: fwban
|
||||
# Notes.: command executed when banning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <failures> number of failures
|
||||
# <failtime> unix timestamp of the last failure
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionban = shorewall reject <ip>
|
||||
|
||||
# Option: fwunban
|
||||
# Notes.: command executed when unbanning an IP. Take care that the
|
||||
# command is executed with Fail2Ban user rights.
|
||||
# Tags: <ip> IP address
|
||||
# <bantime> unix timestamp of the ban time
|
||||
# <unbantime> unix timestamp of the unban time
|
||||
# Values: CMD
|
||||
#
|
||||
actionunban = shorewall allow <ip>
|
||||
@@ -1,32 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: loglevel
|
||||
# Notes.: Set the log level output.
|
||||
# 1 = ERROR
|
||||
# 2 = WARN
|
||||
# 3 = INFO
|
||||
# 4 = DEBUG
|
||||
# Values: NUM Default: 3
|
||||
#
|
||||
loglevel = 3
|
||||
|
||||
# Option: logtarget
|
||||
# Notes.: Set the log target. This could be a file, SYSLOG, STDERR.
|
||||
# Values: STDERR SYSLOG file Default: /var/log/fail2ban.log
|
||||
#
|
||||
logtarget = /var/log/fail2ban.log
|
||||
|
||||
# Option: socket
|
||||
# Notes.: Set the socket file. This is used to communication with the
|
||||
# daemon.
|
||||
# Values: FILE Default: /tmp/fail2ban.sock
|
||||
#
|
||||
socket = /tmp/fail2ban.sock
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: failregex
|
||||
# Notes.: regex to match the password failure messages in the logfile.
|
||||
# Values: TEXT
|
||||
#
|
||||
failregex = [[]client (?P<host>\S*)[]] user .*(?:: authentication failure|not found)
|
||||
@@ -1,14 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 394 $
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: failregex
|
||||
# Notes.: regex to match the password failure messages in the logfile.
|
||||
# Values: TEXT
|
||||
#
|
||||
failregex = [[]client (?P<host>\S*)[]] File does not exist: .*(\.php|\.asp)
|
||||
@@ -1,15 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Christoph Haas
|
||||
# Modified by: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 267 $
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: failregex
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT
|
||||
#
|
||||
failregex = LOGIN FAILED, ip=\[::ffff:(?P<host>\S*)\]$
|
||||
@@ -1,14 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 267 $
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: failregex
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT
|
||||
#
|
||||
failregex = error,relay=(?:::f{4,6}:)?(?P<host>\S*),.*550 User unknown
|
||||
@@ -1,14 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 267 $
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: failregex
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT
|
||||
#
|
||||
failregex = reject: RCPT from (.*)\[(?P<host>\S*)\]: 554
|
||||
@@ -1,14 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Yaroslav Halchenko
|
||||
#
|
||||
# $Revision: 331 $
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: failregex
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT
|
||||
#
|
||||
failregex = USER \S+: no such user found from \S* ?\[(?P<host>\S+)\] to \S+\s*$
|
||||
@@ -1,14 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 267 $
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: failregex
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT
|
||||
#
|
||||
failregex = (?:[\d,.]+[\d,.] rblsmtpd: |421 badiprbl: ip )(?P<host>\S*)
|
||||
@@ -1,14 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Yaroslav Halchenko
|
||||
#
|
||||
# $Revision: 331 $
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: failregex
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT
|
||||
#
|
||||
failregex = : warning: [-._\w]+\[(?P<host>[.\d]+)\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed$
|
||||
@@ -1,15 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: failregex
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT
|
||||
#
|
||||
failregex = (?:(?:Authentication failure|Failed [-/\w+]+) for(?: [iI](?:llegal|nvalid) user)?|[Ii](?:llegal|nvalid) user|ROOT LOGIN REFUSED) .*(?: from|FROM) (?:::f{4,6}:)?(?P<host>\S*)
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# Option: failregex
|
||||
# Notes.: regex to match the password failures messages in the logfile.
|
||||
# Values: TEXT
|
||||
#
|
||||
failregex = vsftpd: \(pam_unix\) authentication failure; .* rhost=(?P<host>\S*)
|
||||
@@ -1,135 +0,0 @@
|
||||
# Fail2Ban configuration file
|
||||
#
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
#
|
||||
|
||||
# The DEFAULT allows a global definition of the options. They can be override
|
||||
# in each jail afterwards.
|
||||
|
||||
[DEFAULT]
|
||||
|
||||
# "ignoreip" can be an IP address, a CIDR mask or a DNS host
|
||||
ignoreip = 127.0.0.1
|
||||
bantime = 600
|
||||
maxretry = 3
|
||||
|
||||
# "backend" specifies the backend used to get files modification. Available
|
||||
# options are "gamin", "polling" and "auto".
|
||||
backend = auto
|
||||
|
||||
|
||||
# This jail corresponds to the standard configuration in Fail2ban 0.6.
|
||||
# The mail-whois action send a notification e-mail with a whois request
|
||||
# in the body.
|
||||
|
||||
[ssh-iptables]
|
||||
|
||||
enabled = false
|
||||
filter = sshd
|
||||
action = iptables[name=SSH, port=ssh, protocol=tcp]
|
||||
mail-whois[name=SSH, dest=yourmail@mail.com]
|
||||
logpath = /var/log/sshd.log
|
||||
maxretry = 5
|
||||
|
||||
[proftpd-iptables]
|
||||
|
||||
enabled = false
|
||||
filter = proftpd
|
||||
action = iptables[name=ProFTPD, port=ftp, protocol=tcp]
|
||||
mail-whois[name=ProFTPD, dest=yourmail@mail.com]
|
||||
logpath = /var/log/proftpd/proftpd.log
|
||||
maxretry = 6
|
||||
|
||||
# This jail forces the backend to "polling".
|
||||
|
||||
[sasl-iptables]
|
||||
|
||||
enabled = false
|
||||
filter = sasl
|
||||
backend = polling
|
||||
action = iptables[name=sasl, port=smtp, protocol=tcp]
|
||||
mail-whois[name=sasl, dest=yourmail@mail.com]
|
||||
logpath = /var/log/mail.log
|
||||
|
||||
# This one behaves like the previous and sends a report when the jail
|
||||
# is stopped.
|
||||
|
||||
[ssh-iptables-report]
|
||||
|
||||
enabled = false
|
||||
filter = sshd
|
||||
action = iptables[name=SSH, port=ssh, protocol=tcp]
|
||||
mail-whois[name=SSH, dest=yourmail@mail.com]
|
||||
mail-report[dest=yourmail@mail.com]
|
||||
logpath = /var/log/sshd.log
|
||||
maxretry = 5
|
||||
|
||||
# Here we use TCP-Wrappers instead of Netfilter/Iptables.
|
||||
|
||||
[ssh-tcpwrapper]
|
||||
|
||||
enabled = false
|
||||
filter = sshd
|
||||
action = hostsdeny
|
||||
mail-whois[name=SSH, dest=yourmail@mail.com]
|
||||
logpath = /var/log/sshd.log
|
||||
|
||||
# This jail demonstrates the use of wildcards in "logpath".
|
||||
# Moreover, it is possible to give other files on a new line.
|
||||
|
||||
[apache-tcpwrapper]
|
||||
|
||||
enabled = false
|
||||
filter = apache-auth
|
||||
action = hostsdeny
|
||||
logpath = /var/log/apache*/*access.log
|
||||
/home/www/myhomepage/access.log
|
||||
maxretry = 6
|
||||
|
||||
# The hosts.deny path can be defined with the "file" argument if it is
|
||||
# not in /etc.
|
||||
|
||||
[postfix-tcpwrapper]
|
||||
|
||||
enabled = false
|
||||
filter = postfix
|
||||
action = hostsdeny[file=/not/a/standard/path/hosts.deny]
|
||||
mail[name=Postfix, dest=yourmail@mail.com]
|
||||
logpath = /var/log/postfix.log
|
||||
bantime = 300
|
||||
|
||||
# Do not ban anybody. Just report information about the remote host.
|
||||
# A notification is sent at most every 600 seconds (bantime).
|
||||
|
||||
[vsftpd-notification]
|
||||
|
||||
enabled = false
|
||||
filter = vsftpd
|
||||
action = mail-whois[name=VSFTPD, dest=yourmail@mail.com]
|
||||
logpath = /var/log/vsftpd.log
|
||||
maxretry = 5
|
||||
bantime = 1800
|
||||
|
||||
# Use shorewall instead of iptables.
|
||||
|
||||
[apache-shorewall]
|
||||
|
||||
enabled = false
|
||||
filter = apache-noscript
|
||||
action = shorewall
|
||||
mail[name=Postfix, dest=yourmail@mail.com]
|
||||
logpath = /var/log/apache2/error_log
|
||||
|
||||
# This jail uses ipfw, the standard firewall on FreeBSD. The "ignoreip"
|
||||
# option is overridden in this jail.
|
||||
|
||||
[ssh-ipfw]
|
||||
|
||||
enabled = false
|
||||
filter = sshd
|
||||
action = ipfw[localhost=192.168.0.1]
|
||||
mail-whois[name=SSH, dest=yourmail@mail.com]
|
||||
logpath = /var/log/auth.log
|
||||
ignoreip = 168.192.0.1
|
||||
-1237
File diff suppressed because it is too large
Load Diff
-341
@@ -1,341 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import sys, string, os, pickle, re, logging
|
||||
import getopt, time, readline, shlex, socket
|
||||
|
||||
# Inserts our own modules path first in the list
|
||||
# fix for bug #343821
|
||||
sys.path.insert(1, "/usr/lib/fail2ban")
|
||||
|
||||
# Now we can import our modules
|
||||
from version import version
|
||||
from client.csocket import CSocket
|
||||
from client.configurator import Configurator
|
||||
from client.beautifier import Beautifier
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client")
|
||||
|
||||
##
|
||||
#
|
||||
# @todo This class needs cleanup.
|
||||
|
||||
class Fail2banClient:
|
||||
|
||||
prompt = "fail2ban> "
|
||||
|
||||
def __init__(self):
|
||||
self.__argv = None
|
||||
self.__stream = None
|
||||
self.__configurator = Configurator()
|
||||
self.__conf = dict()
|
||||
self.__conf["conf"] = "/etc/fail2ban"
|
||||
self.__conf["dump"] = False
|
||||
self.__conf["force"] = False
|
||||
self.__conf["verbose"] = 1
|
||||
self.__conf["interactive"] = False
|
||||
self.__conf["socket"] = None
|
||||
|
||||
def dispVersion(self):
|
||||
print "Fail2Ban v" + version
|
||||
print
|
||||
print "Copyright (c) 2004-2006 Cyril Jaquier"
|
||||
print "Copyright of modifications held by their respective authors."
|
||||
print "Licensed under the GNU General Public License v2 (GPL)."
|
||||
print
|
||||
print "Written by Cyril Jaquier <lostcontrol@users.sourceforge.net>."
|
||||
print "Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>."
|
||||
|
||||
def dispUsage(self):
|
||||
""" Prints Fail2Ban command line options and exits
|
||||
"""
|
||||
print "Usage: "+self.__argv[0]+" [OPTIONS]... <COMMAND>"
|
||||
print
|
||||
print "Fail2Ban v" + version + " reads log file that contains password failure report"
|
||||
print "and bans the corresponding IP addresses using firewall rules."
|
||||
print
|
||||
print "Options:"
|
||||
print " -c <DIR> configuration directory"
|
||||
print " -s <FILE> socket path"
|
||||
print " -d dump configuration. For debugging"
|
||||
print " -i interactive mode"
|
||||
print " -v increase verbosity"
|
||||
print " -q decrease verbosity"
|
||||
print " -x force execution of the server"
|
||||
print " -h, --help display this help message"
|
||||
print " -V, --version print the version"
|
||||
print
|
||||
print "Command:"
|
||||
print " start start the server and the jails"
|
||||
print " reload reload the configuration"
|
||||
print " stop stop all jails and terminate the server"
|
||||
print " status get the current status"
|
||||
print
|
||||
print " set loglevel <LEVEL> set loglevel to <LEVEL>"
|
||||
print " get loglevel get loglevel"
|
||||
print " set logtarget <TARGET> set log target to <TARGET>"
|
||||
print " get logtarget get log target"
|
||||
print
|
||||
print " add <JAIL> [BACKEND] create <JAIL> using [BACKEND]"
|
||||
print " set <JAIL> <CMD> set the <CMD> value for <JAIL>"
|
||||
print " get <JAIL> <CMD> get the <CMD> value for <JAIL>"
|
||||
print " start <JAIL> start <JAIL>"
|
||||
print " stop <JAIL> stop <JAIL>. The jail is removed"
|
||||
print " status <JAIL> get the current status of <JAIL>"
|
||||
print
|
||||
print "Report bugs to <lostcontrol@users.sourceforge.net>"
|
||||
|
||||
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
|
||||
|
||||
def __getCmdLineOptions(self, optList):
|
||||
""" Gets the command line options
|
||||
"""
|
||||
for opt in optList:
|
||||
if opt[0] == "-c":
|
||||
self.__conf["conf"] = opt[1]
|
||||
elif opt[0] == "-s":
|
||||
self.__conf["socket"] = opt[1]
|
||||
elif opt[0] == "-d":
|
||||
self.__conf["dump"] = True
|
||||
elif opt[0] == "-v":
|
||||
self.__conf["verbose"] = self.__conf["verbose"] + 1
|
||||
elif opt[0] == "-q":
|
||||
self.__conf["verbose"] = self.__conf["verbose"] - 1
|
||||
elif opt[0] == "-x":
|
||||
self.__conf["force"] = True
|
||||
elif opt[0] == "-i":
|
||||
self.__conf["interactive"] = True
|
||||
elif opt[0] in ["-h", "--help"]:
|
||||
self.dispUsage()
|
||||
sys.exit(0)
|
||||
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:
|
||||
beautifier.setInputCmd(c)
|
||||
try:
|
||||
client = CSocket(self.__conf["socket"])
|
||||
ret = client.send(c)
|
||||
if ret[0] == 0:
|
||||
logSys.debug("OK : " + `ret[1]`)
|
||||
if showRet:
|
||||
print beautifier.beautify(ret[1])
|
||||
else:
|
||||
logSys.debug("NOK: " + `ret[1].args`)
|
||||
print beautifier.beautifyError(ret[1])
|
||||
return False
|
||||
except socket.error:
|
||||
if showRet:
|
||||
logSys.error("Unable to contact server. Is it running?")
|
||||
return False
|
||||
except Exception, e:
|
||||
if showRet:
|
||||
logSys.error(e)
|
||||
return False
|
||||
return True
|
||||
|
||||
##
|
||||
# Process a command line.
|
||||
#
|
||||
# Process one command line and exit.
|
||||
# @param cmd the command line
|
||||
|
||||
def __processCommand(self, cmd):
|
||||
if len(cmd) == 1 and cmd[0] == "start":
|
||||
if self.__ping():
|
||||
logSys.error("Server already running")
|
||||
return False
|
||||
else:
|
||||
self.__startServerAsync(self.__conf["force"])
|
||||
# Read the config while the server is starting
|
||||
self.__readConfig()
|
||||
try:
|
||||
# Wait for the server to start
|
||||
self.__waitOnServer()
|
||||
# Configure the server
|
||||
self.__processCmd(self.__stream, False)
|
||||
return True
|
||||
except ServerExecutionException:
|
||||
logSys.error("Could not start server. Try -x option")
|
||||
return False
|
||||
elif len(cmd) == 1 and cmd[0] == "reload":
|
||||
if self.__ping():
|
||||
self.__readConfig()
|
||||
self.__processCmd([['stop', 'all']], False)
|
||||
# Configure the server
|
||||
return self.__processCmd(self.__stream, False)
|
||||
else:
|
||||
logSys.error("Could not find server")
|
||||
return False
|
||||
else:
|
||||
return self.__processCmd([cmd])
|
||||
|
||||
|
||||
##
|
||||
# Start Fail2Ban server.
|
||||
#
|
||||
# Start the Fail2ban server in daemon mode.
|
||||
|
||||
def __startServerAsync(self, force = False):
|
||||
args = list()
|
||||
|
||||
args.append("fail2ban-server")
|
||||
args.append("-b")
|
||||
if force:
|
||||
args.append("-x")
|
||||
|
||||
pid = os.fork()
|
||||
if pid == 0:
|
||||
try:
|
||||
# Use the PATH env
|
||||
os.execvp("fail2ban-server", args)
|
||||
except OSError:
|
||||
try:
|
||||
# Use the current directory
|
||||
os.execv("fail2ban-server", args)
|
||||
except OSError:
|
||||
print "Could not find fail2ban-server"
|
||||
os.exit(-1)
|
||||
|
||||
|
||||
def __waitOnServer(self):
|
||||
# Wait for the server to start
|
||||
cnt = 0
|
||||
while not self.__ping():
|
||||
if cnt > 10:
|
||||
raise ServerExecutionException("Failed to start server")
|
||||
time.sleep(0.1)
|
||||
cnt = cnt + 1
|
||||
|
||||
|
||||
def start(self, argv):
|
||||
# Command line options
|
||||
self.__argv = argv
|
||||
|
||||
# Reads the command line options.
|
||||
try:
|
||||
cmdOpts = 'hc:s:xdviqV'
|
||||
cmdLongOpts = ['help', 'version']
|
||||
optList, args = getopt.getopt(self.__argv[1:], cmdOpts, cmdLongOpts)
|
||||
except getopt.GetoptError:
|
||||
self.dispUsage()
|
||||
return False
|
||||
|
||||
self.__getCmdLineOptions(optList)
|
||||
|
||||
verbose = self.__conf["verbose"]
|
||||
if verbose <= 0:
|
||||
logSys.setLevel(logging.ERROR)
|
||||
elif verbose == 1:
|
||||
logSys.setLevel(logging.WARN)
|
||||
elif verbose == 2:
|
||||
logSys.setLevel(logging.INFO)
|
||||
else:
|
||||
logSys.setLevel(logging.DEBUG)
|
||||
# Add the default logging handler
|
||||
stdout = logging.StreamHandler(sys.stdout)
|
||||
# set a format which is simpler for console use
|
||||
formatter = logging.Formatter('%(levelname)-6s %(message)s')
|
||||
# tell the handler to use this format
|
||||
stdout.setFormatter(formatter)
|
||||
logSys.addHandler(stdout)
|
||||
|
||||
# Set the configuration path
|
||||
self.__configurator.setBaseDir(self.__conf["conf"])
|
||||
|
||||
# Set socket path
|
||||
self.__configurator.readEarly()
|
||||
socket = self.__configurator.getEarlyOptions()
|
||||
if self.__conf["socket"] == None:
|
||||
self.__conf["socket"] = socket["socket"]
|
||||
logSys.info("Using socket file " + self.__conf["socket"])
|
||||
|
||||
if self.__conf["dump"]:
|
||||
self.__readConfig()
|
||||
self.dumpConfig(self.__stream)
|
||||
return True
|
||||
|
||||
# Interactive mode
|
||||
if self.__conf["interactive"]:
|
||||
try:
|
||||
ret = True
|
||||
if len(args) > 0:
|
||||
ret = self.__processCommand(args)
|
||||
if ret:
|
||||
readline.parse_and_bind("tab: complete")
|
||||
self.dispInteractive()
|
||||
while True:
|
||||
cmd = raw_input(self.prompt)
|
||||
if cmd == "exit" or cmd == "quit":
|
||||
# Exit
|
||||
return True
|
||||
if not cmd == "":
|
||||
self.__processCommand(shlex.split(cmd))
|
||||
except (EOFError, KeyboardInterrupt):
|
||||
print
|
||||
return True
|
||||
# Single command mode
|
||||
else:
|
||||
if len(args) < 1:
|
||||
self.dispUsage()
|
||||
return False
|
||||
return self.__processCommand(args)
|
||||
|
||||
def __readConfig(self):
|
||||
# Read the configuration
|
||||
self.__configurator.readAll()
|
||||
self.__configurator.getAllOptions()
|
||||
self.__configurator.convertToProtocol()
|
||||
self.__stream = self.__configurator.getConfigStream()
|
||||
|
||||
@staticmethod
|
||||
def dumpConfig(cmd):
|
||||
for c in cmd:
|
||||
print c
|
||||
return True
|
||||
|
||||
|
||||
class ServerExecutionException(Exception):
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
client = Fail2banClient()
|
||||
# Exit with correct return value
|
||||
if client.start(sys.argv):
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(-1)
|
||||
-164
@@ -1,164 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 300 $
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision: 300 $"
|
||||
__date__ = "$Date: 2006-08-23 21:53:09 +0200 (Wed, 23 Aug 2006) $"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import locale, getopt, sys, time, logging, gc
|
||||
|
||||
# Inserts our own modules path first in the list
|
||||
# fix for bug #343821
|
||||
sys.path.insert(1, "/usr/lib/fail2ban")
|
||||
|
||||
from version import version
|
||||
from server.filter import Filter
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.regex")
|
||||
|
||||
class Fail2banRegex:
|
||||
|
||||
def __init__(self):
|
||||
self.__filter = Filter(None)
|
||||
# Setup logging
|
||||
logging.getLogger("fail2ban").handlers = []
|
||||
self.__hdlr = logging.StreamHandler(sys.stdout)
|
||||
# set a format which is simpler for console use
|
||||
formatter = logging.Formatter("%(message)s")
|
||||
# tell the handler to use this format
|
||||
self.__hdlr.setFormatter(formatter)
|
||||
logging.getLogger("fail2ban").addHandler(self.__hdlr)
|
||||
logging.getLogger("fail2ban").setLevel(logging.ERROR)
|
||||
|
||||
def dispVersion(self):
|
||||
print "Fail2Ban v" + version
|
||||
print
|
||||
print "Copyright (c) 2004-2006 Cyril Jaquier"
|
||||
print "Copyright of modifications held by their respective authors."
|
||||
print "Licensed under the GNU General Public License v2 (GPL)."
|
||||
print
|
||||
print "Written by Cyril Jaquier <lostcontrol@users.sourceforge.net>."
|
||||
print "Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>."
|
||||
|
||||
def dispUsage(self):
|
||||
print "Usage: "+sys.argv[0]+" <logline> <failregex>"
|
||||
print
|
||||
print "Fail2Ban v" + version + " reads log file that contains password failure report"
|
||||
print "and bans the corresponding IP addresses using firewall rules."
|
||||
print
|
||||
print "This tools can test and benchmark your regular expressions for the \"failregex\""
|
||||
print "option."
|
||||
print
|
||||
print "Report bugs to <lostcontrol@users.sourceforge.net>"
|
||||
|
||||
def getCmdLineOptions(self, optList):
|
||||
""" Gets the command line options
|
||||
"""
|
||||
for opt in optList:
|
||||
if opt[0] in ["-h", "--help"]:
|
||||
self.dispUsage()
|
||||
sys.exit(0)
|
||||
elif opt[0] in ["-V", "--version"]:
|
||||
self.dispVersion()
|
||||
sys.exit(0)
|
||||
|
||||
def setRegex(self, value):
|
||||
print
|
||||
self.__filter.setFailRegex(value)
|
||||
|
||||
def testRegex(self, line):
|
||||
print
|
||||
try:
|
||||
logging.getLogger("fail2ban").setLevel(logging.DEBUG)
|
||||
ret = self.__filter.findFailure(line)
|
||||
print
|
||||
logging.getLogger("fail2ban").setLevel(logging.CRITICAL)
|
||||
except IndexError:
|
||||
print "Sorry, but no <host> found in regex"
|
||||
return False
|
||||
if len(ret) == 0:
|
||||
print "Sorry, no match"
|
||||
return False
|
||||
else:
|
||||
print "Success, the following data were found:"
|
||||
timeTuple = time.localtime(ret[0][1])
|
||||
print "Date: " + time.strftime("%a %b %d %H:%M:%S %Y", timeTuple)
|
||||
ipList = ""
|
||||
for i in ret:
|
||||
ipList = ipList + " " + i[0]
|
||||
print "IP :" + ipList
|
||||
print
|
||||
print "Date template hits:"
|
||||
for template in self.__filter.dateDetector.getTemplates():
|
||||
print `template.getHits()` + " hit: " + template.getName()
|
||||
print
|
||||
print "Benchmark. Executing 1000..."
|
||||
gc.disable()
|
||||
total = 0
|
||||
maxValue = 0
|
||||
maxPos = 0
|
||||
minValue = 99999999
|
||||
minPos = 0
|
||||
for i in range(1000):
|
||||
start = time.time()
|
||||
ret = self.__filter.findFailure(line)
|
||||
end = time.time()
|
||||
diff = (end - start) * 1000
|
||||
total = total + diff
|
||||
minValue = min(minValue, diff)
|
||||
if minValue == diff:
|
||||
minPos = i
|
||||
maxValue = max(maxValue, diff)
|
||||
if maxValue == diff:
|
||||
maxPos = i
|
||||
gc.enable()
|
||||
print "Performance"
|
||||
print "Avg: " + `total / 1000` + " ms"
|
||||
print "Max: " + `maxValue` + " ms (Run " + `maxPos` + ")"
|
||||
print "Min: " + `minValue` + " ms (Run " + `minPos` + ")"
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
regex = Fail2banRegex()
|
||||
# Reads the command line options.
|
||||
try:
|
||||
cmdOpts = 'hV'
|
||||
cmdLongOpts = ['help', 'version']
|
||||
optList, args = getopt.getopt(sys.argv[1:], cmdOpts, cmdLongOpts)
|
||||
except getopt.GetoptError:
|
||||
regex.dispUsage()
|
||||
sys.exit(-1)
|
||||
# Process command line
|
||||
regex.getCmdLineOptions(optList)
|
||||
# We need exactly 3 parameters
|
||||
if len(sys.argv) <> 3:
|
||||
regex.dispUsage()
|
||||
sys.exit(-1)
|
||||
else:
|
||||
regex.setRegex(sys.argv[2])
|
||||
ret = regex.testRegex(sys.argv[1])
|
||||
if ret:
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(-1)
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import getopt, sys
|
||||
|
||||
# Inserts our own modules path first in the list
|
||||
# fix for bug #343821
|
||||
sys.path.insert(1, "/usr/lib/fail2ban")
|
||||
|
||||
from version import version
|
||||
from server.server import Server
|
||||
|
||||
##
|
||||
# \mainpage Fail2Ban
|
||||
#
|
||||
# \section Introduction
|
||||
#
|
||||
# Fail2ban is designed to protect your server against brute force attacks.
|
||||
# Its first goal was to protect a SSH server.
|
||||
|
||||
class Fail2banServer:
|
||||
|
||||
def __init__(self):
|
||||
self.__server = None
|
||||
self.__argv = None
|
||||
self.__conf = dict()
|
||||
self.__conf["background"] = True
|
||||
self.__conf["force"] = False
|
||||
self.__conf["socket"] = "/tmp/fail2ban.sock"
|
||||
|
||||
def dispVersion(self):
|
||||
print "Fail2Ban v" + version
|
||||
print
|
||||
print "Copyright (c) 2004-2006 Cyril Jaquier"
|
||||
print "Copyright of modifications held by their respective authors."
|
||||
print "Licensed under the GNU General Public License v2 (GPL)."
|
||||
print
|
||||
print "Written by Cyril Jaquier <lostcontrol@users.sourceforge.net>."
|
||||
print "Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>."
|
||||
|
||||
def dispUsage(self):
|
||||
""" Prints Fail2Ban command line options and exits
|
||||
"""
|
||||
print "Usage: "+self.__argv[0]+" [OPTIONS]"
|
||||
print
|
||||
print "Fail2Ban v" + version + " reads log file that contains password failure report"
|
||||
print "and bans the corresponding IP addresses using firewall rules."
|
||||
print
|
||||
print "Only use this command for debugging purpose. Start the server with"
|
||||
print "fail2ban-client instead."
|
||||
print
|
||||
print "Options:"
|
||||
print " -b start in background"
|
||||
print " -f start in foreground"
|
||||
print " -s <FILE> socket path"
|
||||
print " -x force execution of the server"
|
||||
print " -h, --help display this help message"
|
||||
print " -V, --version print the version"
|
||||
print
|
||||
print "Report bugs to <lostcontrol@users.sourceforge.net>"
|
||||
|
||||
def __getCmdLineOptions(self, optList):
|
||||
""" Gets the command line options
|
||||
"""
|
||||
for opt in optList:
|
||||
if opt[0] == "-b":
|
||||
self.__conf["background"] = True
|
||||
if opt[0] == "-f":
|
||||
self.__conf["background"] = False
|
||||
if opt[0] == "-s":
|
||||
self.__conf["socket"] = opt[1]
|
||||
if opt[0] == "-x":
|
||||
self.__conf["force"] = True
|
||||
if opt[0] in ["-h", "--help"]:
|
||||
self.dispUsage()
|
||||
sys.exit(0)
|
||||
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:xhV'
|
||||
cmdLongOpts = ['help', 'version']
|
||||
optList, args = getopt.getopt(self.__argv[1:], cmdOpts, cmdLongOpts)
|
||||
except getopt.GetoptError:
|
||||
self.dispUsage()
|
||||
|
||||
self.__getCmdLineOptions(optList)
|
||||
|
||||
try:
|
||||
self.__server = Server(self.__conf["background"])
|
||||
self.__server.start(self.__conf["socket"], self.__conf["force"])
|
||||
return True
|
||||
except Exception, e:
|
||||
print e
|
||||
self.__server.quit()
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
server = Fail2banServer()
|
||||
if server.start(sys.argv):
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(-1)
|
||||
@@ -1,79 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
|
||||
import unittest, logging, sys
|
||||
|
||||
# Inserts our own modules path first in the list
|
||||
# fix for bug #343821
|
||||
sys.path.insert(1, "/usr/lib/fail2ban")
|
||||
|
||||
from version import version
|
||||
from testcases import banmanagertestcase
|
||||
from testcases import clientreadertestcase
|
||||
from testcases import failmanagertestcase
|
||||
from testcases import filtertestcase
|
||||
from testcases import servertestcase
|
||||
from testcases import datedetectortestcase
|
||||
from testcases import actiontestcase
|
||||
from server.mytime import MyTime
|
||||
|
||||
# Set the time to a fixed, known value
|
||||
# Sun Aug 14 12:00:00 CEST 2005
|
||||
MyTime.setTime(1124013600)
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban")
|
||||
# Add the default logging handler
|
||||
stdout = logging.StreamHandler(sys.stdout)
|
||||
logSys.addHandler(stdout)
|
||||
logSys.setLevel(logging.FATAL)
|
||||
|
||||
print "Fail2ban " + version + " test suite. Please wait..."
|
||||
|
||||
tests = unittest.TestSuite()
|
||||
|
||||
# Filter
|
||||
tests.addTest(unittest.makeSuite(filtertestcase.IgnoreIP))
|
||||
tests.addTest(unittest.makeSuite(filtertestcase.LogFile))
|
||||
tests.addTest(unittest.makeSuite(filtertestcase.GetFailures))
|
||||
# Server
|
||||
#tests.addTest(unittest.makeSuite(servertestcase.StartStop))
|
||||
#tests.addTest(unittest.makeSuite(servertestcase.Transmitter))
|
||||
tests.addTest(unittest.makeSuite(actiontestcase.ExecuteAction))
|
||||
# FailManager
|
||||
tests.addTest(unittest.makeSuite(failmanagertestcase.AddFailure))
|
||||
# BanManager
|
||||
tests.addTest(unittest.makeSuite(banmanagertestcase.AddFailure))
|
||||
# ClientReader
|
||||
tests.addTest(unittest.makeSuite(clientreadertestcase.JailReaderTest))
|
||||
# DateDetector
|
||||
tests.addTest(unittest.makeSuite(datedetectortestcase.DateDetectorTest))
|
||||
|
||||
# Tests runner
|
||||
testRunner = unittest.TextTestRunner()
|
||||
testRunner.run(tests)
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
432096e69a64df45cd8aa49b66e5f473cb8de972
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
9018dec2acaf9038b973d2874ef4848fdcfcfc2e
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
881b05f931fee22ff04637209b4a6d774149fb56
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
7bd8c4dda6b2978e8eaaaad8f428727ac3a36d49
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
151df27656b75c6f83a42857c28b99c9793998f0
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
6e5843a7cebd7b3d92274eb3da391e3e6c166284
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
4d1f6ac73abc134098cce4b80ef682d9c44c2dde
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
c84e58c2b2e51c836804b9c3b6aa85a08ede3136
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
2fbc8d5a7b02c8ab5627119670d41e7dafe22389
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
86b7a61244f6c27ed4e94f18081643988cd1d91f
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
691bb92d39ae67f576588f2f2d40db6ed7ee7135
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
2021bb12e4e71229259325345d5b72bf6e586f19
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
e6efcd92753868d0d2c72bab092e9d56cad108bb
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
539467a8d37d0f36eaab69f319dbded1c9cec9fe
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
164460619940fff77273095d46ae8b040854ec84
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
c0e3a3e494ac5a187e42a6b92b85301e3a386ab2
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
12548aff657cd32fac53e4dae5745c180a87f753
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
4f733aa21111e27cb707cc9e05e820c27e54694b
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
a20d1f8c337d2b90c99f8d708e586e5a1dcedaba
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
caed3e0be38f2896fdce863ee1d81e0f7b949117
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
bd48aba82f2d7e9265e076b37b628b7985da91de
|
||||
@@ -1,52 +0,0 @@
|
||||
#!/sbin/runscript
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# Author: Sireyessire, Cyril Jaquier
|
||||
#
|
||||
# $Revision: 1.2 $
|
||||
|
||||
opts="start stop restart reload showlog"
|
||||
|
||||
FAIL2BAN="/usr/bin/fail2ban-client"
|
||||
|
||||
depend() {
|
||||
need net
|
||||
need logger
|
||||
after iptables
|
||||
}
|
||||
|
||||
start() {
|
||||
ebegin "Starting fail2ban"
|
||||
${FAIL2BAN} start &> /dev/null
|
||||
eend $? "Failed to start fail2ban"
|
||||
}
|
||||
|
||||
stop() {
|
||||
ebegin "Stopping fail2ban"
|
||||
${FAIL2BAN} stop &> /dev/null
|
||||
eend $? "Failed to stop fail2ban"
|
||||
}
|
||||
|
||||
reload() {
|
||||
ebegin "Reloading fail2ban"
|
||||
${FAIL2BAN} reload > /dev/null
|
||||
eend $? "Failed to reload fail2ban"
|
||||
}
|
||||
|
||||
showlog(){
|
||||
less /var/log/fail2ban.log
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# chkconfig: 345 92 08
|
||||
# description: Fail2ban daemon
|
||||
# http://fail2ban.sourceforge.net/wiki/index.php/Main_Page
|
||||
# process name: fail2ban-server
|
||||
#
|
||||
#
|
||||
# Author: Tyler Owen
|
||||
#
|
||||
|
||||
# Source function library.
|
||||
. /etc/init.d/functions
|
||||
|
||||
# Check that the config file exists
|
||||
[ -f /etc/fail2ban/fail2ban.conf ] || exit 0
|
||||
|
||||
FAIL2BAN="/usr/bin/fail2ban-client"
|
||||
|
||||
RETVAL=0
|
||||
|
||||
getpid() {
|
||||
#pid=`ps -ef | grep fail2ban-|grep -v grep|grep -v bash|awk '{print $2}'`
|
||||
pid=`ps -ef | grep fail2ban-|grep -v grep|awk '{print $2}'`
|
||||
}
|
||||
|
||||
start() {
|
||||
echo -n $"Starting fail2ban: "
|
||||
getpid
|
||||
if [ -z "$pid"]; then
|
||||
$FAIL2BAN start > /dev/null
|
||||
RETVAL=$?
|
||||
fi
|
||||
if [ $RETVAL -eq 0 ]; then
|
||||
touch /var/lock/subsys/fail2ban
|
||||
echo_success
|
||||
else
|
||||
echo_failure
|
||||
fi
|
||||
echo
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
stop() {
|
||||
echo -n $"Stopping fail2ban: "
|
||||
getpid
|
||||
RETVAL=$?
|
||||
if [ -n "$pid" ]; then
|
||||
$FAIL2BAN stop > /dev/null
|
||||
fi
|
||||
getpid
|
||||
if [ -z "$pid" ]; then
|
||||
rm -f /var/lock/subsys/fail2ban
|
||||
echo_success
|
||||
else
|
||||
echo_failure
|
||||
fi
|
||||
echo
|
||||
return $RETVAL
|
||||
}
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
status)
|
||||
getpid
|
||||
if [ -n "$pid" ]; then
|
||||
echo "Fail2ban (pid $pid) is running..."
|
||||
else
|
||||
RETVAL=1
|
||||
echo "Fail2ban is stopped"
|
||||
fi
|
||||
;;
|
||||
restart)
|
||||
start
|
||||
stop
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|status|restart}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit $RETVAL
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/bin/bash
|
||||
kill `ps ax|grep fail2ban|grep -v grep|awk '{print $1}'`
|
||||
@@ -1,96 +0,0 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
|
||||
.TH FAIL2BAN-CLIENT "1" "November 2006" "fail2ban-client v0.7.4" "User Commands"
|
||||
.SH NAME
|
||||
fail2ban-client \- configure and control the server
|
||||
.SH SYNOPSIS
|
||||
.B fail2ban-client
|
||||
[\fIOPTIONS\fR]... \fI<COMMAND>\fR
|
||||
.SH DESCRIPTION
|
||||
Fail2Ban v0.7.4 reads log file that contains password failure report
|
||||
and bans the corresponding IP addresses using firewall rules.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-c\fR <DIR>
|
||||
configuration directory
|
||||
.TP
|
||||
\fB\-s\fR <FILE>
|
||||
socket path
|
||||
.TP
|
||||
\fB\-d\fR
|
||||
dump configuration. For debugging
|
||||
.TP
|
||||
\fB\-i\fR
|
||||
interactive mode
|
||||
.TP
|
||||
\fB\-v\fR
|
||||
increase verbosity
|
||||
.TP
|
||||
\fB\-q\fR
|
||||
decrease verbosity
|
||||
.TP
|
||||
\fB\-x\fR
|
||||
force execution of the server
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
display this help message
|
||||
.TP
|
||||
\fB\-V\fR, \fB\-\-version\fR
|
||||
print the version
|
||||
.SH COMMAND
|
||||
.TP
|
||||
start
|
||||
start the server and the jails
|
||||
.TP
|
||||
reload
|
||||
reload the configuration
|
||||
.TP
|
||||
stop
|
||||
stop all jails and terminate the server
|
||||
.TP
|
||||
status
|
||||
get the current status
|
||||
.TP
|
||||
set loglevel <LEVEL>
|
||||
set loglevel to <LEVEL>
|
||||
.TP
|
||||
get loglevel
|
||||
get loglevel
|
||||
.TP
|
||||
set logtarget <TARGET>
|
||||
set log target to <TARGET>
|
||||
.TP
|
||||
get logtarget
|
||||
get log target
|
||||
.TP
|
||||
add <JAIL> [BACKEND]
|
||||
create <JAIL> using [BACKEND]
|
||||
.TP
|
||||
set <JAIL> <CMD>
|
||||
set the <CMD> value for <JAIL>
|
||||
.TP
|
||||
get <JAIL> <CMD>
|
||||
get the <CMD> value for <JAIL>
|
||||
.TP
|
||||
start <JAIL>
|
||||
start <JAIL>
|
||||
.TP
|
||||
stop <JAIL>
|
||||
stop <JAIL>. The jail is removed
|
||||
.TP
|
||||
status <JAIL>
|
||||
get the current status of <JAIL>
|
||||
.SH FILES
|
||||
\fI/etc/fail2ban/*\fR
|
||||
.SH AUTHOR
|
||||
Written by Cyril Jaquier <lostcontrol@users.sourceforge.net>.
|
||||
Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>.
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs to <lostcontrol@users.sourceforge.net>
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2004-2006 Cyril Jaquier
|
||||
.br
|
||||
Copyright of modifications held by their respective authors.
|
||||
Licensed under the GNU General Public License v2 (GPL).
|
||||
.SH "SEE ALSO"
|
||||
.br
|
||||
fail2ban-server(1)
|
||||
@@ -1,12 +0,0 @@
|
||||
Include file for help2man man page
|
||||
$Id: $
|
||||
|
||||
[name]
|
||||
fail2ban-client \- configure and control the server
|
||||
|
||||
[files]
|
||||
\fI/etc/fail2ban/*\fR
|
||||
|
||||
[see also]
|
||||
.br
|
||||
fail2ban-server(1)
|
||||
@@ -1,27 +0,0 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
|
||||
.TH FAIL2BAN-REGEX "1" "November 2006" "fail2ban-regex v0.7.4" "User Commands"
|
||||
.SH NAME
|
||||
fail2ban-regex \- test Fail2ban "failregex" option
|
||||
.SH SYNOPSIS
|
||||
.B fail2ban-regex
|
||||
\fI<logline> <failregex>\fR
|
||||
.SH DESCRIPTION
|
||||
Fail2Ban v0.7.4 reads log file that contains password failure report
|
||||
and bans the corresponding IP addresses using firewall rules.
|
||||
.PP
|
||||
This tools can test and benchmark your regular expressions for the "failregex"
|
||||
option.
|
||||
.SH AUTHOR
|
||||
Written by Cyril Jaquier <lostcontrol@users.sourceforge.net>.
|
||||
Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>.
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs to <lostcontrol@users.sourceforge.net>
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2004-2006 Cyril Jaquier
|
||||
.br
|
||||
Copyright of modifications held by their respective authors.
|
||||
Licensed under the GNU General Public License v2 (GPL).
|
||||
.SH "SEE ALSO"
|
||||
.br
|
||||
fail2ban-client(1)
|
||||
fail2ban-server(1)
|
||||
@@ -1,10 +0,0 @@
|
||||
Include file for help2man man page
|
||||
$Id: $
|
||||
|
||||
[name]
|
||||
fail2ban-regex \- test Fail2ban "failregex" option
|
||||
|
||||
[see also]
|
||||
.br
|
||||
fail2ban-client(1)
|
||||
fail2ban-server(1)
|
||||
@@ -1,45 +0,0 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
|
||||
.TH FAIL2BAN-SERVER "1" "November 2006" "fail2ban-server v0.7.4" "User Commands"
|
||||
.SH NAME
|
||||
fail2ban-server \- start the server
|
||||
.SH SYNOPSIS
|
||||
.B fail2ban-server
|
||||
[\fIOPTIONS\fR]
|
||||
.SH DESCRIPTION
|
||||
Fail2Ban v0.7.4 reads log file that contains password failure report
|
||||
and bans the corresponding IP addresses using firewall rules.
|
||||
.PP
|
||||
Only use this command for debugging purpose. Start the server with
|
||||
fail2ban\-client instead.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-b\fR
|
||||
start in background
|
||||
.TP
|
||||
\fB\-f\fR
|
||||
start in foreground
|
||||
.TP
|
||||
\fB\-s\fR <FILE>
|
||||
socket path
|
||||
.TP
|
||||
\fB\-x\fR
|
||||
force execution of the server
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
display this help message
|
||||
.TP
|
||||
\fB\-V\fR, \fB\-\-version\fR
|
||||
print the version
|
||||
.SH AUTHOR
|
||||
Written by Cyril Jaquier <lostcontrol@users.sourceforge.net>.
|
||||
Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>.
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs to <lostcontrol@users.sourceforge.net>
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2004-2006 Cyril Jaquier
|
||||
.br
|
||||
Copyright of modifications held by their respective authors.
|
||||
Licensed under the GNU General Public License v2 (GPL).
|
||||
.SH "SEE ALSO"
|
||||
.br
|
||||
fail2ban-client(1)
|
||||
@@ -1,9 +0,0 @@
|
||||
Include file for help2man man page
|
||||
$Id: $
|
||||
|
||||
[name]
|
||||
fail2ban-server \- start the server
|
||||
|
||||
[see also]
|
||||
.br
|
||||
fail2ban-client(1)
|
||||
@@ -1,20 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# fail2ban-client
|
||||
echo -n "Generating fail2ban-client "
|
||||
help2man --section=1 --no-info --include=fail2ban-client.h2m --output fail2ban-client.1 ../fail2ban-client
|
||||
echo "[done]"
|
||||
echo -n "Patching fail2ban-client "
|
||||
sed -i -e 's/.SS "Command:"/.SH COMMAND/' fail2ban-client.1
|
||||
echo "[done]"
|
||||
|
||||
# fail2ban-server
|
||||
echo -n "Generating fail2ban-server "
|
||||
help2man --section=1 --no-info --include=fail2ban-server.h2m --output fail2ban-server.1 ../fail2ban-server
|
||||
echo "[done]"
|
||||
|
||||
# fail2ban-regex
|
||||
echo -n "Generating fail2ban-regex "
|
||||
help2man --section=1 --no-info --include=fail2ban-regex.h2m --output fail2ban-regex.1 ../fail2ban-regex
|
||||
echo "[done]"
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
@@ -1,226 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import logging, os
|
||||
#from subprocess import call
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.actions.action")
|
||||
|
||||
##
|
||||
# Execute commands.
|
||||
#
|
||||
# This class reads the failures from the Jail queue and decide if an
|
||||
# action has to be taken. A BanManager take care of the banned IP
|
||||
# addresses.
|
||||
|
||||
class Action:
|
||||
|
||||
def __init__(self, name):
|
||||
self.__name = name
|
||||
self.__cInfo = dict()
|
||||
## Command executed in order to initialize the system.
|
||||
self.__actionStart = ''
|
||||
## Command executed when an IP address gets banned.
|
||||
self.__actionBan = ''
|
||||
## Command executed when an IP address gets removed.
|
||||
self.__actionUnban = ''
|
||||
## Command executed in order to check requirements.
|
||||
self.__actionCheck = ''
|
||||
## Command executed in order to stop the system.
|
||||
self.__actionStop = ''
|
||||
logSys.debug("Created Action")
|
||||
|
||||
def setName(self, name):
|
||||
self.__name = name
|
||||
|
||||
def getName(self):
|
||||
return self.__name
|
||||
|
||||
def setCInfo(self, key, value):
|
||||
self.__cInfo[key] = value
|
||||
|
||||
def getCInfo(self, key):
|
||||
return self.__cInfo[key]
|
||||
|
||||
def delCInfo(self, key):
|
||||
del self.__cInfo[key]
|
||||
|
||||
##
|
||||
# Set the "start" command.
|
||||
#
|
||||
# @param value the command
|
||||
|
||||
def setActionStart(self, value):
|
||||
self.__actionStart = value
|
||||
logSys.info("Set actionStart = %s" % value)
|
||||
|
||||
##
|
||||
# Get the "start" command.
|
||||
#
|
||||
# @return the command
|
||||
|
||||
def getActionStart(self):
|
||||
return self.__actionStart
|
||||
|
||||
def execActionStart(self):
|
||||
startCmd = Action.replaceTag(self.__actionStart, self.__cInfo)
|
||||
return Action.executeCmd(startCmd)
|
||||
|
||||
##
|
||||
# Set the "ban" command.
|
||||
#
|
||||
# @param value the command
|
||||
|
||||
def setActionBan(self, value):
|
||||
self.__actionBan = value
|
||||
logSys.info("Set actionBan = %s" % value)
|
||||
|
||||
##
|
||||
# Get the "ban" command.
|
||||
#
|
||||
# @return the command
|
||||
|
||||
def getActionBan(self):
|
||||
return self.__actionBan
|
||||
|
||||
def execActionBan(self, aInfo):
|
||||
return self.__processCmd(self.__actionBan, aInfo)
|
||||
|
||||
##
|
||||
# Set the "unban" command.
|
||||
#
|
||||
# @param value the command
|
||||
|
||||
def setActionUnban(self, value):
|
||||
self.__actionUnban = value
|
||||
logSys.info("Set actionUnban = %s" % value)
|
||||
|
||||
##
|
||||
# Get the "unban" command.
|
||||
#
|
||||
# @return the command
|
||||
|
||||
def getActionUnban(self):
|
||||
return self.__actionUnban
|
||||
|
||||
def execActionUnban(self, aInfo):
|
||||
return self.__processCmd(self.__actionUnban, aInfo)
|
||||
|
||||
##
|
||||
# Set the "check" command.
|
||||
#
|
||||
# @param value the command
|
||||
|
||||
def setActionCheck(self, value):
|
||||
self.__actionCheck = value
|
||||
logSys.info("Set actionCheck = %s" % value)
|
||||
|
||||
##
|
||||
# Get the "check" command.
|
||||
#
|
||||
# @return the command
|
||||
|
||||
def getActionCheck(self):
|
||||
return self.__actionCheck
|
||||
|
||||
##
|
||||
# Set the "stop" command.
|
||||
#
|
||||
# @param value the command
|
||||
|
||||
def setActionStop(self, value):
|
||||
self.__actionStop = value
|
||||
logSys.info("Set actionStop = %s" % value)
|
||||
|
||||
##
|
||||
# Get the "stop" command.
|
||||
#
|
||||
# @return the command
|
||||
|
||||
def getActionStop(self):
|
||||
return self.__actionStop
|
||||
|
||||
def execActionStop(self):
|
||||
stopCmd = Action.replaceTag(self.__actionStop, self.__cInfo)
|
||||
return Action.executeCmd(stopCmd)
|
||||
|
||||
@staticmethod
|
||||
def replaceTag(query, aInfo):
|
||||
""" Replace tags in query
|
||||
"""
|
||||
string = query
|
||||
for tag in aInfo:
|
||||
string = string.replace('<' + tag + '>', str(aInfo[tag]))
|
||||
# New line
|
||||
string = string.replace("<br>", '\n')
|
||||
return string
|
||||
|
||||
def __processCmd(self, cmd, aInfo = None):
|
||||
""" Executes an OS command.
|
||||
"""
|
||||
if cmd == "":
|
||||
logSys.debug("Nothing to do")
|
||||
return True
|
||||
|
||||
checkCmd = Action.replaceTag(self.__actionCheck, self.__cInfo)
|
||||
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)
|
||||
if not Action.executeCmd(checkCmd):
|
||||
logSys.fatal("Unable to restore environment")
|
||||
return False
|
||||
|
||||
# Replace tags
|
||||
if not aInfo == None:
|
||||
realCmd = Action.replaceTag(cmd, aInfo)
|
||||
else:
|
||||
realCmd = cmd
|
||||
|
||||
# Replace static fields
|
||||
realCmd = Action.replaceTag(realCmd, self.__cInfo)
|
||||
|
||||
return Action.executeCmd(realCmd)
|
||||
|
||||
@staticmethod
|
||||
def executeCmd(realCmd):
|
||||
logSys.debug(realCmd)
|
||||
try:
|
||||
# The following line gives deadlock with multiple jails
|
||||
#retcode = call(realCmd, shell=True)
|
||||
retcode = os.system(realCmd)
|
||||
if retcode == 0:
|
||||
logSys.debug("%s returned successfully" % realCmd)
|
||||
return True
|
||||
else:
|
||||
logSys.error("%s returned %x" % (realCmd, retcode))
|
||||
except OSError, e:
|
||||
logSys.error("%s failed with %s" % (realCmd, e))
|
||||
return False
|
||||
@@ -1,182 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
from banmanager import BanManager
|
||||
from jailthread import JailThread
|
||||
from action import Action
|
||||
from mytime import MyTime
|
||||
import time, logging
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.actions")
|
||||
|
||||
##
|
||||
# Execute commands.
|
||||
#
|
||||
# This class reads the failures from the Jail queue and decide if an
|
||||
# action has to be taken. A BanManager take care of the banned IP
|
||||
# addresses.
|
||||
|
||||
class Actions(JailThread):
|
||||
|
||||
##
|
||||
# Constructor.
|
||||
#
|
||||
# Initialize the filter object with default values.
|
||||
# @param jail the jail object
|
||||
|
||||
def __init__(self, jail):
|
||||
JailThread.__init__(self)
|
||||
## The jail which contains this action.
|
||||
self.jail = jail
|
||||
self.__actions = list()
|
||||
## The ban manager.
|
||||
self.__banManager = BanManager()
|
||||
|
||||
def addAction(self, name):
|
||||
action = Action(name)
|
||||
self.__actions.append(action)
|
||||
|
||||
def delAction(self, name):
|
||||
for action in self.__actions:
|
||||
if action.getName() == name:
|
||||
self.__actions.remove(action)
|
||||
break
|
||||
|
||||
def getAction(self, name):
|
||||
for action in self.__actions:
|
||||
if action.getName() == name:
|
||||
return action
|
||||
raise KeyError
|
||||
|
||||
def getLastAction(self):
|
||||
action = self.__actions.pop()
|
||||
self.__actions.append(action)
|
||||
return action
|
||||
|
||||
##
|
||||
# Set the ban time.
|
||||
#
|
||||
# @param value the time
|
||||
|
||||
def setBanTime(self, value):
|
||||
self.__banManager.setBanTime(value)
|
||||
logSys.info("Set banTime = %s" % value)
|
||||
|
||||
##
|
||||
# Get the ban time.
|
||||
#
|
||||
# @return the time
|
||||
|
||||
def getBanTime(self):
|
||||
return self.__banManager.getBanTime()
|
||||
|
||||
##
|
||||
# Main loop.
|
||||
#
|
||||
# This function is the main loop of the thread. It checks the Jail
|
||||
# queue and executes commands when an IP address is banned.
|
||||
# @return True when the thread exits nicely
|
||||
|
||||
def run(self):
|
||||
for action in self.__actions:
|
||||
action.execActionStart()
|
||||
self.setActive(True)
|
||||
while self.isActive():
|
||||
if not self.getIdle():
|
||||
#logSys.debug(self.jail.getName() + ": action")
|
||||
ret = self.__checkBan()
|
||||
if not ret:
|
||||
self.__checkUnBan()
|
||||
time.sleep(self.getSleepTime())
|
||||
else:
|
||||
time.sleep(self.getSleepTime())
|
||||
self.__flushBan()
|
||||
for action in self.__actions:
|
||||
action.execActionStop()
|
||||
logSys.debug(self.jail.getName() + ": action terminated")
|
||||
return True
|
||||
|
||||
##
|
||||
# Check for IP address to ban.
|
||||
#
|
||||
# Look in the Jail queue for FailTicket. If a ticket is available,
|
||||
# it executes the "ban" command and add a ticket to the BanManager.
|
||||
# @return True if an IP address get banned
|
||||
|
||||
def __checkBan(self):
|
||||
ticket = self.jail.getFailTicket()
|
||||
if ticket != False:
|
||||
aInfo = dict()
|
||||
bTicket = BanManager.createBanTicket(ticket)
|
||||
aInfo["ip"] = bTicket.getIP()
|
||||
aInfo["failures"] = bTicket.getAttempt()
|
||||
logSys.warn("[%s] Ban %s" % (self.jail.getName(), aInfo["ip"]))
|
||||
for action in self.__actions:
|
||||
action.execActionBan(aInfo)
|
||||
self.__banManager.addBanTicket(bTicket)
|
||||
return True
|
||||
return False
|
||||
|
||||
##
|
||||
# Check for IP address to unban.
|
||||
#
|
||||
# Unban IP address which are outdated.
|
||||
|
||||
def __checkUnBan(self):
|
||||
for ticket in self.__banManager.unBanList(MyTime.time()):
|
||||
aInfo = dict()
|
||||
aInfo["ip"] = ticket.getIP()
|
||||
logSys.warn("[%s] Unban %s" % (self.jail.getName(), aInfo["ip"]))
|
||||
for action in self.__actions:
|
||||
action.execActionUnban(aInfo)
|
||||
|
||||
##
|
||||
# Flush the ban list.
|
||||
#
|
||||
# Unban all IP address which are still in the banning list.
|
||||
|
||||
def __flushBan(self):
|
||||
logSys.debug("Flush ban list")
|
||||
for ticket in self.__banManager.flushBanList():
|
||||
aInfo = dict()
|
||||
aInfo["ip"] = ticket.getIP()
|
||||
logSys.warn("[%s] Unban %s" % (self.jail.getName(), aInfo["ip"]))
|
||||
for action in self.__actions:
|
||||
action.execActionUnban(aInfo)
|
||||
|
||||
##
|
||||
# Get the status of the filter.
|
||||
#
|
||||
# Get some informations about the filter state such as the total
|
||||
# number of failures.
|
||||
# @return a list with tuple
|
||||
|
||||
def status(self):
|
||||
ret = [("Currently banned", self.__banManager.size()),
|
||||
("Total banned", self.__banManager.getBanTotal())]
|
||||
return ret
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
from banticket import BanTicket
|
||||
from threading import Lock
|
||||
from mytime import MyTime
|
||||
import logging
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.action")
|
||||
|
||||
##
|
||||
# Banning Manager.
|
||||
#
|
||||
# Manage the banned IP addresses. Convert FailTicket to BanTicket.
|
||||
# This class is mainly used by the Action class.
|
||||
|
||||
class BanManager:
|
||||
|
||||
##
|
||||
# Constructor.
|
||||
#
|
||||
# Initialize members with default values.
|
||||
|
||||
def __init__(self):
|
||||
## Mutex used to protect the ban list.
|
||||
self.__lock = Lock()
|
||||
## The ban list.
|
||||
self.__banList = list()
|
||||
## The amount of time an IP address gets banned.
|
||||
self.__banTime = 600
|
||||
## Total number of banned IP address
|
||||
self.__banTotal = 0
|
||||
|
||||
##
|
||||
# Set the ban time.
|
||||
#
|
||||
# Set the amount of time an IP address get banned.
|
||||
# @param value the time
|
||||
|
||||
def setBanTime(self, value):
|
||||
self.__lock.acquire()
|
||||
self.__banTime = int(value)
|
||||
self.__lock.release()
|
||||
|
||||
##
|
||||
# Get the ban time.
|
||||
#
|
||||
# Get the amount of time an IP address get banned.
|
||||
# @return the time
|
||||
|
||||
def getBanTime(self):
|
||||
try:
|
||||
self.__lock.acquire()
|
||||
return self.__banTime
|
||||
finally:
|
||||
self.__lock.release()
|
||||
|
||||
##
|
||||
# Set the total number of banned address.
|
||||
#
|
||||
# @param value total number
|
||||
|
||||
def setBanTotal(self, value):
|
||||
self.__lock.acquire()
|
||||
self.__banTotal = value
|
||||
self.__lock.release()
|
||||
|
||||
##
|
||||
# Get the total number of banned address.
|
||||
#
|
||||
# @return the total number
|
||||
|
||||
def getBanTotal(self):
|
||||
try:
|
||||
self.__lock.acquire()
|
||||
return self.__banTotal
|
||||
finally:
|
||||
self.__lock.release()
|
||||
|
||||
##
|
||||
# Create a ban ticket.
|
||||
#
|
||||
# Create a BanTicket from a FailTicket. The timestamp of the BanTicket
|
||||
# is the current time. This is a static method.
|
||||
# @param ticket the FailTicket
|
||||
# @return a BanTicket
|
||||
|
||||
@staticmethod
|
||||
def createBanTicket(ticket):
|
||||
ip = ticket.getIP()
|
||||
#lastTime = ticket.getTime()
|
||||
lastTime = MyTime.time()
|
||||
banTicket = BanTicket(ip, lastTime)
|
||||
banTicket.setAttempt(ticket.getAttempt())
|
||||
return banTicket
|
||||
|
||||
##
|
||||
# Add a ban ticket.
|
||||
#
|
||||
# Add a BanTicket instance into the ban list.
|
||||
# @param ticket the ticket
|
||||
# @return True if the IP address is not in the ban list
|
||||
|
||||
def addBanTicket(self, ticket):
|
||||
try:
|
||||
self.__lock.acquire()
|
||||
if not self.__inBanList(ticket):
|
||||
self.__banList.append(ticket)
|
||||
self.__banTotal += 1
|
||||
return True
|
||||
return False
|
||||
finally:
|
||||
self.__lock.release()
|
||||
|
||||
##
|
||||
# Delete a ban ticket.
|
||||
#
|
||||
# Remove a BanTicket from the ban list.
|
||||
# @param ticket the ticket
|
||||
|
||||
def __delBanTicket(self, ticket):
|
||||
self.__banList.remove(ticket)
|
||||
|
||||
##
|
||||
# Get the size of the ban list.
|
||||
#
|
||||
# @return the size
|
||||
|
||||
def size(self):
|
||||
try:
|
||||
self.__lock.acquire()
|
||||
return len(self.__banList)
|
||||
finally:
|
||||
self.__lock.release()
|
||||
|
||||
##
|
||||
# Check if a ticket is in the list.
|
||||
#
|
||||
# Check if a BanTicket with a given IP address is already in the
|
||||
# ban list.
|
||||
# @param ticket the ticket
|
||||
# @return True if a ticket already exists
|
||||
|
||||
def __inBanList(self, ticket):
|
||||
for i in self.__banList:
|
||||
if ticket.getIP() == i.getIP():
|
||||
return True
|
||||
return False
|
||||
|
||||
##
|
||||
# Get the list of IP address to unban.
|
||||
#
|
||||
# Return a list of BanTicket which need to be unbanned.
|
||||
# @param time the time
|
||||
# @return the list of ticket to unban
|
||||
# @todo Check the delete operation
|
||||
|
||||
def unBanList(self, time):
|
||||
try:
|
||||
self.__lock.acquire()
|
||||
uBList = list()
|
||||
# Permanent banning
|
||||
if self.__banTime < 0:
|
||||
return uBList
|
||||
for ticket in self.__banList:
|
||||
if ticket.getTime() < time - self.__banTime:
|
||||
uBList.append(ticket)
|
||||
self.__delBanTicket(ticket)
|
||||
return uBList
|
||||
finally:
|
||||
self.__lock.release()
|
||||
|
||||
##
|
||||
# Flush the ban list.
|
||||
#
|
||||
# Get the ban list and initialize it with an empty one.
|
||||
# @return the complete ban list
|
||||
|
||||
def flushBanList(self):
|
||||
try:
|
||||
self.__lock.acquire()
|
||||
uBList = self.__banList
|
||||
self.__banList = list()
|
||||
return uBList
|
||||
finally:
|
||||
self.__lock.release()
|
||||
@@ -1,50 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision$
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import logging
|
||||
from ticket import Ticket
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban")
|
||||
|
||||
##
|
||||
# Ban Ticket.
|
||||
#
|
||||
# This class extends the Ticket class. It is mainly used by the BanManager.
|
||||
|
||||
class BanTicket(Ticket):
|
||||
|
||||
##
|
||||
# Constructor.
|
||||
#
|
||||
# Call the Ticket (parent) constructor and initialize default
|
||||
# values.
|
||||
# @param ip the IP address
|
||||
# @param time the ban time
|
||||
|
||||
def __init__(self, ip, time):
|
||||
Ticket.__init__(self, ip, time)
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 321 $
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision: 321 $"
|
||||
__date__ = "$Date: 2006-09-04 21:19:58 +0200 (Mon, 04 Sep 2006) $"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import time, logging
|
||||
|
||||
from datetemplate import DateTemplate
|
||||
from datestrptime import DateStrptime
|
||||
from datetai64n import DateTai64n
|
||||
from dateepoch import DateEpoch
|
||||
from threading import Lock
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.filter.datedetector")
|
||||
|
||||
class DateDetector:
|
||||
|
||||
def __init__(self):
|
||||
self.__lock = Lock()
|
||||
self.__templates = list()
|
||||
self.__defTemplate = DateTemplate()
|
||||
|
||||
def addDefaultTemplate(self):
|
||||
# standard
|
||||
template = DateStrptime()
|
||||
template.setName("Month Day Hour:Minute:Second")
|
||||
template.setRegex("^\S{3}\s{1,2}\d{1,2} \d{2}:\d{2}:\d{2}")
|
||||
template.setPattern("%b %d %H:%M:%S")
|
||||
self.__templates.append(template)
|
||||
# asctime
|
||||
template = DateStrptime()
|
||||
template.setName("Weekday Month Day Hour:Minute:Second Year")
|
||||
template.setRegex("\S{3} \S{3} \d{2} \d{2}:\d{2}:\d{2} \d{4}")
|
||||
template.setPattern("%a %b %d %H:%M:%S %Y")
|
||||
self.__templates.append(template)
|
||||
# simple date
|
||||
template = DateStrptime()
|
||||
template.setName("Year/Month/Day Hour:Minute:Second")
|
||||
template.setRegex("\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}")
|
||||
template.setPattern("%Y/%m/%d %H:%M:%S")
|
||||
self.__templates.append(template)
|
||||
# Apache format [31/Oct/2006:09:22:55 -0000]
|
||||
template = DateStrptime()
|
||||
template.setName("Day/Month/Year:Hour:Minute:Second")
|
||||
template.setRegex("\d{2}/\S{3}/\d{4}:\d{2}:\d{2}:\d{2}")
|
||||
template.setPattern("%d/%b/%Y:%H:%M:%S")
|
||||
self.__templates.append(template)
|
||||
# TAI64N
|
||||
template = DateTai64n()
|
||||
template.setName("TAI64N")
|
||||
self.__templates.append(template)
|
||||
# Epoch
|
||||
template = DateEpoch()
|
||||
template.setName("Epoch")
|
||||
self.__templates.append(template)
|
||||
|
||||
def getTemplates(self):
|
||||
return self.__templates
|
||||
|
||||
def setDefaultRegex(self, value):
|
||||
self.__defTemplate.setRegex(value)
|
||||
|
||||
def getDefaultRegex(self):
|
||||
return self.__defTemplate.getRegex()
|
||||
|
||||
def setDefaultPattern(self, value):
|
||||
self.__defTemplate.setPattern(value)
|
||||
|
||||
def getDefaultPattern(self):
|
||||
return self.__defTemplate.getPattern()
|
||||
|
||||
def matchTime(self, line):
|
||||
if self.__defTemplate.isValid():
|
||||
return self.__defTemplate.matchDate(line)
|
||||
else:
|
||||
self.__lock.acquire()
|
||||
for template in self.__templates:
|
||||
match = template.matchDate(line)
|
||||
if not match == None:
|
||||
self.__lock.release()
|
||||
return match
|
||||
self.__lock.release()
|
||||
return None
|
||||
|
||||
def getTime(self, line):
|
||||
if self.__defTemplate.isValid():
|
||||
try:
|
||||
date = self.__defTemplate.getDate(line)
|
||||
return date
|
||||
except ValueError:
|
||||
return None
|
||||
else:
|
||||
self.__lock.acquire()
|
||||
for template in self.__templates:
|
||||
try:
|
||||
date = template.getDate(line)
|
||||
if date == None:
|
||||
continue
|
||||
template.incHits()
|
||||
self.__lock.release()
|
||||
return date
|
||||
except ValueError:
|
||||
pass
|
||||
self.__lock.release()
|
||||
return None
|
||||
|
||||
def getUnixTime(self, line):
|
||||
date = self.getTime(line)
|
||||
if date == None:
|
||||
return None
|
||||
else:
|
||||
return time.mktime(date)
|
||||
|
||||
##
|
||||
# Sort the template lists using the hits score. This method is not called
|
||||
# in this object and thus should be called from time to time.
|
||||
|
||||
def sortTemplate(self):
|
||||
self.__lock.acquire()
|
||||
logSys.debug("Sorting the template list")
|
||||
self.__templates.sort(cmp = lambda x, y: cmp(x.getHits(), y.getHits()),
|
||||
reverse=True)
|
||||
self.__lock.release()
|
||||
@@ -1,44 +0,0 @@
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 321 $
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision: 321 $"
|
||||
__date__ = "$Date: 2006-09-04 21:19:58 +0200 (Mon, 04 Sep 2006) $"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
import time
|
||||
|
||||
from datetemplate import DateTemplate
|
||||
|
||||
class DateEpoch(DateTemplate):
|
||||
|
||||
def __init__(self):
|
||||
DateTemplate.__init__(self)
|
||||
# We already know the format for TAI64N
|
||||
self.setRegex("^\d{10}(\.\d{6})?")
|
||||
|
||||
def getDate(self, line):
|
||||
date = None
|
||||
dateMatch = self.matchDate(line)
|
||||
if dateMatch:
|
||||
# extract part of format which represents seconds since epoch
|
||||
date = list(time.gmtime(float(dateMatch.group())))
|
||||
return date
|
||||
@@ -1,84 +0,0 @@
|
||||
# -*- coding: utf8 -*-
|
||||
# This file is part of Fail2Ban.
|
||||
#
|
||||
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Cyril Jaquier
|
||||
#
|
||||
# $Revision: 321 $
|
||||
|
||||
__author__ = "Cyril Jaquier"
|
||||
__version__ = "$Revision: 321 $"
|
||||
__date__ = "$Date: 2006-09-04 21:19:58 +0200 (Mon, 04 Sep 2006) $"
|
||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||
__license__ = "GPL"
|
||||
|
||||
from mytime import MyTime
|
||||
import time
|
||||
|
||||
from datetemplate import DateTemplate
|
||||
|
||||
##
|
||||
# Use strptime() to parse a date. Our current locale is the 'C'
|
||||
# one because we do not set the locale explicitly. This is POSIX
|
||||
# standard.
|
||||
|
||||
class DateStrptime(DateTemplate):
|
||||
|
||||
TABLE = dict()
|
||||
TABLE["Jan"] = []
|
||||
TABLE["Feb"] = [u"Fév"]
|
||||
TABLE["Mar"] = [u"Mär"]
|
||||
TABLE["Apr"] = ["Avr"]
|
||||
TABLE["May"] = ["Mai"]
|
||||
TABLE["Jun"] = []
|
||||
TABLE["Jul"] = []
|
||||
TABLE["Aug"] = ["Aou"]
|
||||
TABLE["Sep"] = []
|
||||
TABLE["Oct"] = ["Okt"]
|
||||
TABLE["Nov"] = []
|
||||
TABLE["Dec"] = [u"Déc", "Dez"]
|
||||
|
||||
def __init__(self):
|
||||
DateTemplate.__init__(self)
|
||||
|
||||
@staticmethod
|
||||
def convertLocale(date):
|
||||
for t in DateStrptime.TABLE:
|
||||
for m in DateStrptime.TABLE[t]:
|
||||
if date.find(m) >= 0:
|
||||
return date.replace(m, t)
|
||||
return date
|
||||
|
||||
def getDate(self, line):
|
||||
date = None
|
||||
dateMatch = self.matchDate(line)
|
||||
if dateMatch:
|
||||
try:
|
||||
# Try first with 'C' locale
|
||||
date = list(time.strptime(dateMatch.group(), self.getPattern()))
|
||||
except ValueError:
|
||||
# Try to convert date string to 'C' locale
|
||||
conv = self.convertLocale(dateMatch.group())
|
||||
date = list(time.strptime(conv, self.getPattern()))
|
||||
if date[0] < 2000:
|
||||
# There is probably no year field in the logs
|
||||
date[0] = MyTime.gmtime()[0]
|
||||
# Bug fix for #1241756
|
||||
# If the date is greater than the current time, we suppose
|
||||
# that the log is not from this year but from the year before
|
||||
if time.mktime(date) > MyTime.time():
|
||||
date[0] -= 1
|
||||
return date
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user