mirror of https://github.com/fail2ban/fail2ban
Merge commit '0.8.11.pre1-29-gccd2657' into debian
* commit '0.8.11.pre1-29-gccd2657': (363 commits) DOC: minor typos in ChangeLog DOC: adding DEV Notes for for non-greedy matchin within sshd.conf BF: disallow exploiting of non-greedy .* in previous fix by providing too long rhost -- do not impose length limits for user-provided input BF: fixing injection for OpenSSH 6.3 -- making .* before <HOST> non-greedy Changelog for prior changes (gen_buildbots) ENH: condense asterisk regexs for speed BF: missed action in nginx-http-auth ENH: add filter.d/nginx-http-auth. Partially forfills #405 ENH: regenerated config/filter.d/apache-badbots.conf NF: gen_badbots script to (re)generate/update config/filter.d/apache-badbots.conf DOC: keeping Changelog release-phrases uniform, simplified intro, unified DOC: Untabifying and reindenting a bit ChangeLog DOC: few more links for DEVELOP BF: fix dovecot filter for newer failure message. Closes Debian bug #709324 BF: fix to filter.d/wuftp to support pam authentication - Debian bug #665925 Add Fedora git repo of fail2ban package to DEVELOP firewalld-0.3.8 release that support --remove-rules out so documenting this. BF: remove duplication definition secion in webmin-auth DOC: alter release notes a bit more and versions in README.md BF/DOC: fix hopefully final MANIFEST and release instructions ...pull/808/head
commit
128c4c978d
165
ChangeLog
165
ChangeLog
|
@ -4,9 +4,172 @@
|
||||||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
Fail2Ban (version 0.8.10) 2013/06/12
|
Fail2Ban (version 0.8.11.pre1) 2013/10/30
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
|
ver. 0.8.11 (2013/11/XXX) - loves-unittests-and-tight-DoS-free-filter-regexes
|
||||||
|
-----------
|
||||||
|
|
||||||
|
In light of CVE-2013-2178 that triggered our last release we have put
|
||||||
|
a significant effort into tightening all of the regexs of our filters
|
||||||
|
to avoid another similar vulnerability. All filters have been updated
|
||||||
|
and some to catch more login/authentication failures and to support
|
||||||
|
for newer application versions. There are test cases for most log
|
||||||
|
cases of failures now.
|
||||||
|
|
||||||
|
As usual, if you have other examples that demonstrate that a filter is
|
||||||
|
insufficient, or if we have inadvertently introduced a regression,
|
||||||
|
please provide us with example log lines on the github issue tracker
|
||||||
|
http://github.com/fail2ban/fail2ban/issues and NOT on a random blog in
|
||||||
|
some obscure corner of the Internet.
|
||||||
|
|
||||||
|
- IMPORTANT incompatible changes:
|
||||||
|
Filter name changes:
|
||||||
|
* 'lighttpd-fastcgi' filter has been renamed to 'suhosin'
|
||||||
|
* 'sasl' has been renamed to 'postfix-sasl'
|
||||||
|
* 'exim' spam catching failregexes was split out into 'exim-spam'
|
||||||
|
These changes will require changing jail.{conf,local} if any of
|
||||||
|
those filters were used.
|
||||||
|
|
||||||
|
- Fixes:
|
||||||
|
Daniel Black & Marcel Dopita
|
||||||
|
* filter.d/apache-auth -- fixed and apache auth samples provide. Closes gh-286
|
||||||
|
Yaroslav Halchenko
|
||||||
|
* filter.d/common.conf -- make colon after [daemon] optional. Closes gh-267
|
||||||
|
* filter.d/apache-common.conf -- support apache 2.4 more detailed error
|
||||||
|
log format. Closes gh-268
|
||||||
|
* Backends changes detection and parsing. Close gh-223 and gh-103:
|
||||||
|
- Polling backend: detect changes in the files not only based on
|
||||||
|
mtime, but also on the size and inode. It should allow for
|
||||||
|
better detection of changes and log rotations on busy servers,
|
||||||
|
older python 2.4, and file systems with precision of mtime only
|
||||||
|
up to a second (e.g. ext3).
|
||||||
|
- All backends, possible race condition: do not read from a file
|
||||||
|
initially reported empty. Originally could have lead to
|
||||||
|
accounting for detected log lines multiple times.
|
||||||
|
- Do not crash if executing a command in fail2ban-client interactive
|
||||||
|
mode has failed (e.g. due to incorrect syntax). Closes gh-353
|
||||||
|
Daniel Black & Мернов Георгий
|
||||||
|
* filter.d/dovecot.conf -- Fix when no TLS enabled - line doesn't end in ,
|
||||||
|
Daniel Black & Georgiy Mernov & ftoppi & Мернов Георгий
|
||||||
|
* filter.d/exim.conf -- regex hardening and extra failure examples in
|
||||||
|
sample logs
|
||||||
|
* filter.d/named-refused.conf - BIND 9.9.3 regex changes
|
||||||
|
Daniel Black & Sebastian Arcus
|
||||||
|
* filter.d/asterisk -- more regexes
|
||||||
|
Daniel Black
|
||||||
|
* action.d/hostsdeny -- NOTE: new dependancy 'ed'. Switched to use 'ed' across
|
||||||
|
all platforms to ensure permissions are the same before and after a ban.
|
||||||
|
Closes gh-266. hostsdeny supports daemon_list now too.
|
||||||
|
* action.d/bsd-ipfw - action option unsed. Change blocktype to port unreach
|
||||||
|
instead of deny for consistancy.
|
||||||
|
* filter.d/dovecot - added to support different dovecot failure
|
||||||
|
"..disallowed plaintext auth". Closes Debian bug #709324
|
||||||
|
* filter.d/roundcube-auth - timezone offset can be positive or negative
|
||||||
|
* action.d/bsd-ipfw - action option unsed. Fixed to blocktype for
|
||||||
|
consistency. default to port unreach instead of deny
|
||||||
|
* filter.d/dropbear - fix regexs to match standard dropbear and the patched
|
||||||
|
http://www.unchartedbackwaters.co.uk/files/dropbear/dropbear-0.52.patch
|
||||||
|
and add PAM is it in dropbear-2013.60 source code.
|
||||||
|
* filter.d/{asterisk,assp,dovecot,proftpd}.conf -- regex hardening
|
||||||
|
and extra failure examples in sample logs
|
||||||
|
* filter.d/apache-auth - added expressions for mod_authz, mod_auth and
|
||||||
|
mod_auth_digest failures.
|
||||||
|
* filter.d/recidive -- support f2b syslog target and anchor regex at start
|
||||||
|
* filter.d/mysqld-auth.conf - mysql can use syslog
|
||||||
|
* filter.d/sshd - regex enhancements to support openssh-6.3. Closes Debian
|
||||||
|
bug #722970. Thanks Colin Watson for the regex analysis.
|
||||||
|
* filter.d/wuftpd - regex enhancements to support pam and wuftpd. Closes
|
||||||
|
Debian bug #665925
|
||||||
|
Rolf Fokkens
|
||||||
|
* action.d/dshield.conf and complain.conf -- reorder mailx arguments.
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=998020
|
||||||
|
John Doe (ache)
|
||||||
|
* action.d/bsd-ipfw.conf - invert actionstop logic to make exist status 0.
|
||||||
|
Closes gh-343.
|
||||||
|
JP Espinosa (Reviewed by O.Poplawski)
|
||||||
|
* files/redhat-initd - rewritten to use stock init.d functions thus
|
||||||
|
avoiding problems with getpid. Also $network and iptables moved
|
||||||
|
to Should- rc init fields
|
||||||
|
Rick Mellor
|
||||||
|
* filter.d/vsftp - fix capture with tty=ftp
|
||||||
|
|
||||||
|
- New Features:
|
||||||
|
Edgar Hoch
|
||||||
|
* action.d/firewall-cmd-direct-new.conf - action for firewalld
|
||||||
|
from https://bugzilla.redhat.com/show_bug.cgi?id=979622
|
||||||
|
NOTE: requires firewalld-0.3.8+
|
||||||
|
Andy Fragen and Daniel Black
|
||||||
|
* filter.d/osx-ipfw.conf - ipfw action for OSX based on random rule
|
||||||
|
numbers.
|
||||||
|
Anonymous:
|
||||||
|
* action.d/osx-afctl - an action based on afctl for osx
|
||||||
|
Daniel Black & ykimon
|
||||||
|
* filter.d/3proxy.conf -- filter added
|
||||||
|
* fail2ban-regex - now generates http://www.debuggex.com urls for debugging
|
||||||
|
regular expressions with the -D parameter.
|
||||||
|
Daniel Black
|
||||||
|
* filter.d/exim-spam.conf -- a splitout of exim's spam regexes
|
||||||
|
with additions for greater control over filtering spam.
|
||||||
|
* add date expression for apache-2.4 - milliseconds
|
||||||
|
* filter.d/nginx-http-auth -- filter added for http basic authentication
|
||||||
|
failures in nginx. Partially fulfills gh-405.
|
||||||
|
Christophe Carles & Daniel Black
|
||||||
|
* filter.d/perdition.conf -- filter added
|
||||||
|
Mark McKinstry
|
||||||
|
* action.d/apf.conf - add action for Advanced Policy Firewall (apf)
|
||||||
|
Amir Caspi and kjohnsonecl
|
||||||
|
* filter.d/uwimap-auth - filter for uwimap-auth IMAP/POP server
|
||||||
|
Steven Hiscocks and Daniel Black
|
||||||
|
* filter.d/selinux-{common,ssh} -- add SELinux date and ssh filter
|
||||||
|
|
||||||
|
- Enhancements:
|
||||||
|
François Boulogne and Frédéric
|
||||||
|
* filter.d/lighttpd - auth regexs for lighttpd-1.4.31
|
||||||
|
Daniel Black
|
||||||
|
* reorder parsing of jail.conf, jail.d/*.conf, jail.local, jail.d/*.local
|
||||||
|
and likewise for fail2ban.{conf|local|d/*.conf|d/*.local}. Closes gh-392
|
||||||
|
* jail.conf now has asterisk jail - no need for asterisk-tcp and
|
||||||
|
asterisk-udp. Users should replace existing jails with asterisk to
|
||||||
|
reduce duplicate parsing of the asterisk log file.
|
||||||
|
* filter.d/{suhosin,pam-generic,gssftpd,sogo-auth,webmin}- regex anchor at
|
||||||
|
start
|
||||||
|
* filter.d/vsftpd - anchored regex at start. disable old pam format regex
|
||||||
|
* filter.d/pam-generic - added syslog prefix. Disabled support for
|
||||||
|
linux-pam before version 0.99.2.0 (2005)
|
||||||
|
* filter.d/postfix-sasl - renamed from sasl, anchor at start and base on
|
||||||
|
syslog
|
||||||
|
* filter.d/qmail - rewrote regex to anchor at start. Added regex for
|
||||||
|
another "in the wild" patch to rblsmtp.
|
||||||
|
Yaroslav Halchenko
|
||||||
|
* fail2ban-regex -- refactored to provide more details (missing and
|
||||||
|
ignored lines, control over logging, etc) while maintaining look&feel
|
||||||
|
* fail2ban-client -- log to standard error. Closes gh-264
|
||||||
|
* Fail to configure if not a single log file was found for an
|
||||||
|
enabled jail. Closes gh-63
|
||||||
|
* <HOST> is now enforced to end with an alphanumeric
|
||||||
|
* filter.d/roundcube-auth.conf -- anchored version
|
||||||
|
* date matching - for standard asctime formats prefer more detailed
|
||||||
|
first (thus use year if available)
|
||||||
|
* files/gen_badbots was added and filter.d/apache-badbots.conf was
|
||||||
|
regenerated to get updated (although now still an old) list of
|
||||||
|
"bad" bots
|
||||||
|
Alexander Dietrich
|
||||||
|
* action.d/sendmail-common.conf -- added common sendmail settings file
|
||||||
|
and made the sender display name configurable
|
||||||
|
Steven Hiscocks
|
||||||
|
* filter.d/dovecot - Addition of session, time values and possible blank
|
||||||
|
user
|
||||||
|
Zurd and Daniel Black
|
||||||
|
* filter/named-refused - added refused on zone transfer
|
||||||
|
* filter.d/{courier{login,smtp},proftpd,sieve,wuftpd,xinetd} - General
|
||||||
|
regex impovements
|
||||||
|
Zurd
|
||||||
|
* filter.d/postfix - add filter for VRFY failures. Closes gh-322.
|
||||||
|
Orion Poplawski
|
||||||
|
* fail2ban.d/ and jail.d/ directories are added to etc/fail2ban to facilitate
|
||||||
|
their use
|
||||||
|
|
||||||
ver. 0.8.10 (2013/06/12) - wanna-be-secure
|
ver. 0.8.10 (2013/06/12) - wanna-be-secure
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|
519
DEVELOP
519
DEVELOP
|
@ -1,6 +1,6 @@
|
||||||
__ _ _ ___ _
|
__ _ _ ___ _
|
||||||
/ _|__ _(_) |_ ) |__ __ _ _ _
|
/ _|__ _(_) |_ ) |__ __ _ _ _
|
||||||
| _/ _` | | |/ /| '_ \/ _` | ' \
|
| _/ _` | | |/ /| '_ \/ _` | ' \
|
||||||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
|
@ -26,7 +26,7 @@ Pull Requests
|
||||||
|
|
||||||
When submitting pull requests on GitHub we ask you to:
|
When submitting pull requests on GitHub we ask you to:
|
||||||
* Clearly describe the problem you're solving;
|
* Clearly describe the problem you're solving;
|
||||||
* Don't introduce regressions that will make it hard for systems adminstrators
|
* Don't introduce regressions that will make it hard for systems administrators
|
||||||
to update;
|
to update;
|
||||||
* If adding a major feature rebase your changes on master and get to a single commit;
|
* If adding a major feature rebase your changes on master and get to a single commit;
|
||||||
* Include test cases (see below);
|
* Include test cases (see below);
|
||||||
|
@ -37,12 +37,383 @@ When submitting pull requests on GitHub we ask you to:
|
||||||
Filters
|
Filters
|
||||||
=======
|
=======
|
||||||
|
|
||||||
* Include sample logs with 1.2.3.4 used for IP addresses and
|
Filters are tricky. They need to:
|
||||||
example.com/example.org used for DNS names
|
* work with a variety of the versions of the software that generates the logs;
|
||||||
* Ensure ./fail2ban-regex testcases/files/logs/{samplelog} config/filter.d/{filter}.conf
|
* work with the range of logging configuration options available in the
|
||||||
has matches for EVERY regex
|
software;
|
||||||
* Ensure regexs end with a $ and are restrictive as possible. E.g. not .* if
|
* work with multiple operating systems;
|
||||||
[0-9]+ is sufficient
|
* not make assumptions about the log format in excess of the software
|
||||||
|
(e.g. do not assume a username doesn't contain spaces and use \S+ unless
|
||||||
|
you've checked the source code);
|
||||||
|
* account for how future versions of the software will log messages
|
||||||
|
(e.g. guess what would happen to the log message if different authentication
|
||||||
|
types are added);
|
||||||
|
* not be susceptible to DoS vulnerabilities (see Filter Security below); and
|
||||||
|
* match intended log lines only.
|
||||||
|
|
||||||
|
Please follow the steps from Filter Test Cases to Developing Filter Regular
|
||||||
|
Expressions and submit a GitHub pull request (PR) afterwards. If you get stuck,
|
||||||
|
you can push your unfinished changes and still submit a PR -- describe
|
||||||
|
what you have done, what is the hurdle, and we'll attempt to help (PR
|
||||||
|
will be automagically updated with future commits you would push to
|
||||||
|
complete it).
|
||||||
|
|
||||||
|
Filter test cases
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
|
||||||
|
Start by finding the log messages that the application generates related to
|
||||||
|
some form of authentication failure. If you are adding to an existing filter
|
||||||
|
think about whether the log messages are of a similar importance and purpose
|
||||||
|
to the existing filter. If you were a user of Fail2Ban, and did a package
|
||||||
|
update of Fail2Ban that started matching new log messages, would anything
|
||||||
|
unexpected happen? Would the bantime/findtime for the jail be appropriate for
|
||||||
|
the new log messages? If it doesn't, perhaps it needs to be in a separate
|
||||||
|
filter definition, for example like exim filter aims at authentication failures
|
||||||
|
and exim-spam at log messages related to spam.
|
||||||
|
|
||||||
|
Even if it is a new filter you may consider separating the log messages into
|
||||||
|
different filters based on purpose.
|
||||||
|
|
||||||
|
Cause:
|
||||||
|
|
||||||
|
Are some of the log lines a result of the same action? For example, is a PAM
|
||||||
|
failure log message, followed by an application specific failure message the
|
||||||
|
result of the same user/script action? If you add regular expressions for
|
||||||
|
both you would end up with two failures for a single action.
|
||||||
|
Therefore, select the most appropriate log message and document the other log
|
||||||
|
message) with a test case not to match it and a description as to why you chose
|
||||||
|
one over another.
|
||||||
|
|
||||||
|
With the selected log lines consider what action has caused those log
|
||||||
|
messages and whether they could have been generated by accident? Could
|
||||||
|
the log message be occurring due to the first step towards the application
|
||||||
|
asking for authentication? Could the log messages occur often? If some of
|
||||||
|
these are true make a note of this in the jail.conf example that you provide.
|
||||||
|
|
||||||
|
Samples:
|
||||||
|
|
||||||
|
It is important to include log file samples so any future change in the regular
|
||||||
|
expression will still work with the log lines you have identified.
|
||||||
|
|
||||||
|
The sample log messages are provided in a file under testcases/files/logs/
|
||||||
|
named identically as the corresponding filter (but without .conf extension).
|
||||||
|
Each log line should be preceded by a line with failJSON metadata (so the logs
|
||||||
|
lines are tested in the test suite) directly above the log line. If there is
|
||||||
|
any specific information about the log message, such as version or an
|
||||||
|
application configuration option that is needed for the message to occur,
|
||||||
|
include this in a comment (line beginning with #) above the failJSON metadata.
|
||||||
|
|
||||||
|
Log samples should include only one, definitely not more than 3, examples of
|
||||||
|
log messages of the same form. If log messages are different in different
|
||||||
|
versions of the application log messages that show this are encouraged.
|
||||||
|
|
||||||
|
Also attempt to inject an IP into the application (e.g. by specifying
|
||||||
|
it as a username) so that Fail2Ban possibly detects the IP
|
||||||
|
from user input rather than the true origin. See the Filter Security section
|
||||||
|
and the top example in testcases/files/logs/apache-auth as to how to do this.
|
||||||
|
One you have discovered that this is possible, correct the regex so it doesn't
|
||||||
|
match and provide this as a test case with "match": false (see failJSON below).
|
||||||
|
|
||||||
|
If the mechanism to create the log message isn't obvious provide a
|
||||||
|
configuration and/or sample scripts testcases/files/config/{filtername} and
|
||||||
|
reference these in the comments above the log line.
|
||||||
|
|
||||||
|
FailJSON metadata:
|
||||||
|
|
||||||
|
A failJSON metadata is a comment immediately above the log message. It will
|
||||||
|
look like:
|
||||||
|
|
||||||
|
# failJSON: { "time": "2013-06-10T10:10:59", "match": true , "host": "93.184.216.119" }
|
||||||
|
|
||||||
|
Time should match the time of the log message. It is in a specific format of
|
||||||
|
Year-Month-Day'T'Hour:minute:Second. If your log message does not include a
|
||||||
|
year, like the example below, the year should be listed as 2005, if before Sun
|
||||||
|
Aug 14 10am UTC, and 2004 if afterwards. Here is an example failJSON
|
||||||
|
line preceding a sample log line:
|
||||||
|
|
||||||
|
# failJSON: { "time": "2005-03-24T15:25:51", "match": true , "host": "198.51.100.87" }
|
||||||
|
Mar 24 15:25:51 buffalo1 dropbear[4092]: bad password attempt for 'root' from 198.51.100.87:5543
|
||||||
|
|
||||||
|
The "host" in failJSON should contain the IP or domain that should be blocked.
|
||||||
|
|
||||||
|
For long lines that you do not want to be matched (e.g. from log injection
|
||||||
|
attacks) and any log lines to be excluded (see "Cause" section above), set
|
||||||
|
"match": false in the failJSON and describe the reason in the comment above.
|
||||||
|
|
||||||
|
After developing regexes, the following command will test all failJSON metadata
|
||||||
|
against the log lines in all sample log files
|
||||||
|
|
||||||
|
./fail2ban-testcases testSampleRegex
|
||||||
|
|
||||||
|
Developing Filter Regular Expressions
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
Date/Time:
|
||||||
|
|
||||||
|
At the moment, Fail2Ban depends on log lines to have time stamps. That is why
|
||||||
|
before starting to develop failregex, check if your log line format known to
|
||||||
|
Fail2Ban. Copy the time component from the log line and append an IP address to
|
||||||
|
test with following command:
|
||||||
|
|
||||||
|
./fail2ban-regex "2013-09-19 02:46:12 1.2.3.4" "<HOST>"
|
||||||
|
|
||||||
|
Output of such command should contain something like:
|
||||||
|
|
||||||
|
Date template hits:
|
||||||
|
|- [# of hits] date format
|
||||||
|
| [1] Year-Month-Day Hour:Minute:Second
|
||||||
|
|
||||||
|
Ensure that the template description matches time/date elements in your log line
|
||||||
|
time stamp. If there is no matched format then date template needs to be added
|
||||||
|
to server/datedetector.py. Ensure that a new template is added in the order
|
||||||
|
that more specific matches occur first and that there is no confusion between a
|
||||||
|
Day and a Month.
|
||||||
|
|
||||||
|
Filter file:
|
||||||
|
|
||||||
|
The filter is specified in a config/filter.d/{filtername}.conf file. Filter file
|
||||||
|
can have sections INCLUDES (optional) and Definition as follows:
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
|
after = filtername.local
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
failregex = ....
|
||||||
|
|
||||||
|
ignoreregex = ....
|
||||||
|
|
||||||
|
This is also documented in the man page jail.conf (section 5). Other definitions
|
||||||
|
can be added to make failregex's more readable and maintainable to be used
|
||||||
|
through string Interpolations (see http://docs.python.org/2.7/library/configparser.html)
|
||||||
|
|
||||||
|
|
||||||
|
General rules:
|
||||||
|
|
||||||
|
Use "before" if you need to include a common set of rules, like syslog or if
|
||||||
|
there is a common set of regexes for multiple filters.
|
||||||
|
|
||||||
|
Use "after" if you wish to allow the user to overwrite a set of customisations
|
||||||
|
of the current filter. This file doesn't need to exist.
|
||||||
|
|
||||||
|
Try to avoid using ignoreregex mainly for performance reasons. The case when you
|
||||||
|
would use it is if in trying to avoid using it, you end up with an unreadable
|
||||||
|
failregex.
|
||||||
|
|
||||||
|
Syslog:
|
||||||
|
|
||||||
|
If your application logs to syslog you can take advantage of log line prefix
|
||||||
|
definitions present in common.conf. So as a base use:
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
_daemon = app
|
||||||
|
|
||||||
|
failregex = ^%(__prefix_line)s
|
||||||
|
|
||||||
|
In this example common.conf defines __prefix_line which also contains the
|
||||||
|
_daemon name (in syslog terms the service) you have just specified. _daemon
|
||||||
|
can also be a regex.
|
||||||
|
|
||||||
|
For example, to capture following line _daemon should be set to "dovecot"
|
||||||
|
|
||||||
|
Dec 12 11:19:11 dunnart dovecot: pop3-login: Aborted login (tried to use disabled plaintext auth): rip=190.210.136.21, lip=113.212.99.193
|
||||||
|
|
||||||
|
and then ^%(__prefix_line)s would match "Dec 12 11:19:11 dunnart dovecot:
|
||||||
|
". Note it matches the trailing space(s) as well.
|
||||||
|
|
||||||
|
Substitutions (AKA string interpolations):
|
||||||
|
|
||||||
|
We have used string interpolations in above examples. They are useful for
|
||||||
|
making the regexes more readable, reuse generic patterns in multiple failregex
|
||||||
|
lines, and also to refer definition of regex parts to specific filters or even
|
||||||
|
to the user. General principle is that value of a _name variable replaces
|
||||||
|
occurrences of %(_name)s within the same section or anywhere in the config file
|
||||||
|
if defined in [DEFAULT] section.
|
||||||
|
|
||||||
|
Regular Expressions:
|
||||||
|
|
||||||
|
Regular expressions (failregex, ignoreregex) assume that the date/time has been
|
||||||
|
removed from the log line (this is just how fail2ban works internally ATM).
|
||||||
|
|
||||||
|
If the format is like '<date...> error 1.2.3.4 is evil' then you need to match
|
||||||
|
the < at the start so regex should be similar to '^<> <HOST> is evil$' using
|
||||||
|
<HOST> where the IP/domain name appears in the log line.
|
||||||
|
|
||||||
|
The following general rules apply to regular expressions:
|
||||||
|
|
||||||
|
* ensure regexes start with a ^ and are as restrictive as possible. E.g. do not
|
||||||
|
use .* if \d+ is sufficient;
|
||||||
|
* use functionality of Python regexes defined in the standard Python re library
|
||||||
|
http://docs.python.org/2/library/re.html;
|
||||||
|
* make regular expressions readable (as much as possible). E.g.
|
||||||
|
(?:...) represents a non-capturing regex but (...) is more readable, thus
|
||||||
|
preferred.
|
||||||
|
|
||||||
|
If you have only a basic knowledge of regular repressions we advise to read
|
||||||
|
http://docs.python.org/2/library/re.html first. It doesn't take long and would
|
||||||
|
remind you e.g. which characters you need to escape and which you don't.
|
||||||
|
|
||||||
|
Developing/testing a regex:
|
||||||
|
|
||||||
|
You can develop a regex in a file or using command line depending on your
|
||||||
|
preference. You can also use samples you have already created in the test cases
|
||||||
|
or test them one at a time.
|
||||||
|
|
||||||
|
The general tool for testing Fail2Ban regexes is fail2ban-regex. To see how to
|
||||||
|
use it run:
|
||||||
|
|
||||||
|
./fail2ban-regex --help
|
||||||
|
|
||||||
|
Take note of -l heavydebug / -l debug and -v as they might be very useful.
|
||||||
|
|
||||||
|
TIP: Take a look at the source code of the application you are developing
|
||||||
|
failregex for. You may see optional or extra log messages, or parts there
|
||||||
|
of, that need to form part of your regex. It may also reveal how some
|
||||||
|
parts are constrained and different formats depending on configuration or
|
||||||
|
less common usages.
|
||||||
|
|
||||||
|
TIP: For looking through source code - http://sourcecodebrowser.com/ . It has
|
||||||
|
call graphs and can browse different versions.
|
||||||
|
|
||||||
|
TIP: Some applications log spaces at the end. If you are not sure add \s*$ as
|
||||||
|
the end part of the regex.
|
||||||
|
|
||||||
|
If your regex is not matching, http://www.debuggex.com/?flavor=python can help
|
||||||
|
to tune it:
|
||||||
|
|
||||||
|
* use regex from the ./fail2ban-regex output (to ensure all substitutions are
|
||||||
|
done) and replace <HOST> with (?&.ipv4). Make sure that regex type set to
|
||||||
|
Python;
|
||||||
|
* for the test data put your log output with the time removed;
|
||||||
|
- when you have fixed the regex put it back into your filter file.
|
||||||
|
|
||||||
|
Please spread the good word about debuggex - Serge Toarca is kindly continuing
|
||||||
|
its free availability to Open Source developers.
|
||||||
|
|
||||||
|
Finishing up:
|
||||||
|
|
||||||
|
If you've added a new filter, add a new entry in config/jail.conf. The theory
|
||||||
|
here is that a user will create a jail.local with [filtername]\nenable=true to
|
||||||
|
enable your jail.
|
||||||
|
|
||||||
|
So more specifically in the [filter] section in jail.conf:
|
||||||
|
* ensure that you have "enabled = false" (users will enable as needed);
|
||||||
|
* use "filter =" set to your filter name;
|
||||||
|
* use a typical action to disable ports associated with the application;
|
||||||
|
* set "logpath" to the usual location of application log file;
|
||||||
|
* if the default findtime or bantime isn't appropriate to the filter, specify
|
||||||
|
more appropriate choices (possibly with a brief comment line).
|
||||||
|
|
||||||
|
Submit github pull request (See "Pull Requests" above) for
|
||||||
|
github.com/fail2ban/fail2ban containing your great work.
|
||||||
|
|
||||||
|
Filter Security
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Poor filter regular expressions are susceptible to DoS attacks.
|
||||||
|
|
||||||
|
When a remote user has the ability to introduce text that would match filter's
|
||||||
|
failregex, while matching inserted text to the <HOST> part, they have the
|
||||||
|
ability to deny any host they choose.
|
||||||
|
|
||||||
|
So the <HOST> part must be anchored on text generated by the application, and
|
||||||
|
not the user, to a extent sufficient to prevent user inserting the entire text
|
||||||
|
matching this or any other failregex.
|
||||||
|
|
||||||
|
Ideally filter regex should anchor at the beginning and at the end of log line.
|
||||||
|
However as more applications log at the beginning than the end, anchoring the
|
||||||
|
beginning is more important. If the log file used by the application is shared
|
||||||
|
with other applications, like system logs, ensure the other application that use
|
||||||
|
that log file do not log user generated text at the beginning of the line, or,
|
||||||
|
if they do, ensure the regexes of the filter are sufficient to mitigate the risk
|
||||||
|
of insertion.
|
||||||
|
|
||||||
|
|
||||||
|
Examples of poor filters
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
1. Too restrictive
|
||||||
|
|
||||||
|
We find a log message:
|
||||||
|
|
||||||
|
Apr-07-13 07:08:36 Invalid command fial2ban from 1.2.3.4
|
||||||
|
|
||||||
|
We make a failregex
|
||||||
|
|
||||||
|
^Invalid command \S+ from <HOST>
|
||||||
|
|
||||||
|
Now think evil. The user does the command 'blah from 1.2.3.44'
|
||||||
|
|
||||||
|
The program diligently logs:
|
||||||
|
|
||||||
|
Apr-07-13 07:08:36 Invalid command blah from 1.2.3.44 from 1.2.3.4
|
||||||
|
|
||||||
|
And fail2ban matches 1.2.3.44 as the IP that it ban. A DoS attack was successful.
|
||||||
|
|
||||||
|
The fix here is that the command can be anything so .* is appropriate.
|
||||||
|
|
||||||
|
^Invalid command .* from <HOST>
|
||||||
|
|
||||||
|
Here the .* will match until the end of the string. Then realise it has more to
|
||||||
|
match, i.e. "from <HOST>" and go back until it find this. Then it will ban
|
||||||
|
1.2.3.4 correctly. Since the <HOST> is always at the end, end the regex with a $.
|
||||||
|
|
||||||
|
^Invalid command .* from <HOST>$
|
||||||
|
|
||||||
|
Note if we'd just had the expression:
|
||||||
|
|
||||||
|
^Invalid command \S+ from <HOST>$
|
||||||
|
|
||||||
|
Then provided the user put a space in their command they would have never been
|
||||||
|
banned.
|
||||||
|
|
||||||
|
2. Filter regex can match other user injected data
|
||||||
|
|
||||||
|
From the Apache vulnerability CVE-2013-2178
|
||||||
|
( original ref: https://vndh.net/note:fail2ban-089-denial-service ).
|
||||||
|
|
||||||
|
An example bad regex for Apache:
|
||||||
|
|
||||||
|
failregex = [[]client <HOST>[]] user .* not found
|
||||||
|
|
||||||
|
Since the user can do a get request on:
|
||||||
|
|
||||||
|
GET /[client%20192.168.0.1]%20user%20root%20not%20found HTTP/1.0
|
||||||
|
Host: remote.site
|
||||||
|
|
||||||
|
Now the log line will be:
|
||||||
|
|
||||||
|
[Sat Jun 01 02:17:42 2013] [error] [client 192.168.33.1] File does not exist: /srv/http/site/[client 192.168.0.1] user root not found
|
||||||
|
|
||||||
|
As this log line doesn't match other expressions hence it matches the above
|
||||||
|
regex and blocks 192.168.33.1 as a denial of service from the HTTP requester.
|
||||||
|
|
||||||
|
3. Application generates two identical log messages with different meanings
|
||||||
|
|
||||||
|
If the application generates the following two messages under different
|
||||||
|
circumstances:
|
||||||
|
|
||||||
|
client <IP>: authentication failed
|
||||||
|
client <USER>: authentication failed
|
||||||
|
|
||||||
|
|
||||||
|
Then it's obvious that a regex of "^client <HOST>: authentication
|
||||||
|
failed$" will still cause problems if the user can trigger the second
|
||||||
|
log message with a <USER> of 123.1.1.1.
|
||||||
|
|
||||||
|
Here there's nothing to do except request/change the application so it logs
|
||||||
|
messages differently.
|
||||||
|
|
||||||
|
|
||||||
Code Testing
|
Code Testing
|
||||||
============
|
============
|
||||||
|
@ -66,7 +437,7 @@ coverage run fail2ban-testcases
|
||||||
coverage html
|
coverage html
|
||||||
|
|
||||||
Then look at htmlcov/index.html and see how much coverage your test cases
|
Then look at htmlcov/index.html and see how much coverage your test cases
|
||||||
exert over the codebase. Full coverage is a good thing however it may not be
|
exert over the code base. Full coverage is a good thing however it may not be
|
||||||
complete. Try to ensure tests cover as many independent paths through the
|
complete. Try to ensure tests cover as many independent paths through the
|
||||||
code.
|
code.
|
||||||
|
|
||||||
|
@ -136,6 +507,14 @@ Use the following tags in your commit messages:
|
||||||
|
|
||||||
Multiple tags could be joined with +, e.g. "BF+TST:".
|
Multiple tags could be joined with +, e.g. "BF+TST:".
|
||||||
|
|
||||||
|
Use the text "closes #333"/"resolves #333 "/"fixes #333" where 333 represents
|
||||||
|
an issue that is closed. Other text and details in link below.
|
||||||
|
See: https://help.github.com/articles/closing-issues-via-commit-messages
|
||||||
|
|
||||||
|
If merge resulted in conflicts, clarify what changes were done to
|
||||||
|
corresponding files in the 'Conflicts:' section of the merge commit
|
||||||
|
message. See e.g. https://github.com/fail2ban/fail2ban/commit/f5a8a8ac
|
||||||
|
|
||||||
Adding Actions
|
Adding Actions
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
@ -149,7 +528,7 @@ Design
|
||||||
Fail2Ban was initially developed with Python 2.3 (IIRC). It should
|
Fail2Ban was initially developed with Python 2.3 (IIRC). It should
|
||||||
still be compatible with Python 2.4 and such compatibility assurance
|
still be compatible with Python 2.4 and such compatibility assurance
|
||||||
makes code ... old-fashioned in many places (RF-Note). In 0.7 the
|
makes code ... old-fashioned in many places (RF-Note). In 0.7 the
|
||||||
design went through major refactoring into client/server,
|
design went through major re-factoring into client/server,
|
||||||
a-thread-per-jail design which made it a bit difficult to follow.
|
a-thread-per-jail design which made it a bit difficult to follow.
|
||||||
Below you can find a sketchy description of the main components of the
|
Below you can find a sketchy description of the main components of the
|
||||||
system to orient yourself better.
|
system to orient yourself better.
|
||||||
|
@ -260,7 +639,7 @@ one way or another provide
|
||||||
except FailManagerEmpty:
|
except FailManagerEmpty:
|
||||||
self.failManager.cleanup(MyTime.time())
|
self.failManager.cleanup(MyTime.time())
|
||||||
|
|
||||||
thus channeling "ban tickets" from their failManager to the
|
thus channelling "ban tickets" from their failManager to the
|
||||||
corresponding jail.
|
corresponding jail.
|
||||||
|
|
||||||
action.py
|
action.py
|
||||||
|
@ -290,30 +669,45 @@ Releasing
|
||||||
* https://bugzilla.redhat.com/buglist.cgi?query_format=advanced&bug_status=NEW&bug_status=ASSIGNED&component=fail2ban&classification=Red%20Hat&classification=Fedora
|
* https://bugzilla.redhat.com/buglist.cgi?query_format=advanced&bug_status=NEW&bug_status=ASSIGNED&component=fail2ban&classification=Red%20Hat&classification=Fedora
|
||||||
* http://www.freebsd.org/cgi/query-pr-summary.cgi?text=fail2ban
|
* http://www.freebsd.org/cgi/query-pr-summary.cgi?text=fail2ban
|
||||||
|
|
||||||
# Provide a release sample to distributors
|
# Make sure the tests pass
|
||||||
|
|
||||||
* Debian: Yaroslav Halchenko <debian@onerussian.com>
|
./fail2ban-testcases-all
|
||||||
http://packages.qa.debian.org/f/fail2ban.html
|
|
||||||
* FreeBSD: Christoph Theis theis@gmx.at>, Nick Hilliard <nick@foobar.org>
|
|
||||||
http://svnweb.freebsd.org/ports/head/security/py-fail2ban/Makefile?view=markup
|
|
||||||
* Fedora: Axel Thimm <Axel.Thimm@atrpms.net>
|
|
||||||
https://apps.fedoraproject.org/packages/fail2ban
|
|
||||||
* Gentoo: netmon@gentoo.org
|
|
||||||
http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/net-analyzer/fail2ban/metadata.xml?view=markup
|
|
||||||
* openSUSE: Stephan Kulow <coolo@suse.com>
|
|
||||||
https://build.opensuse.org/package/users?package=fail2ban&project=openSUSE%3AFactory
|
|
||||||
* Mac Ports: @Malbrouck on github (gh-49)
|
|
||||||
https://trac.macports.org/browser/trunk/dports/security/fail2ban/Portfile
|
|
||||||
|
|
||||||
# Wait for feedback from distributors
|
# Ensure the version is correct
|
||||||
|
|
||||||
# Ensure the version is correct in ./common/version.py
|
in:
|
||||||
|
* ./common/version.py
|
||||||
|
* top of ChangeLog
|
||||||
|
* README.md
|
||||||
|
|
||||||
|
# Ensure the MANIFEST is complete
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
python setup.py sdist
|
||||||
|
|
||||||
|
Look for errors like:
|
||||||
|
'testcases/files/logs/mysqld.log' not a regular file -- skipping
|
||||||
|
|
||||||
|
Which indicates that testcases/files/logs/mysqld.log has been moved or is a directory
|
||||||
|
|
||||||
|
tar -C /tmp -jxf dist/fail2ban-0.8.11.tar.bz2
|
||||||
|
|
||||||
|
# clean up current direcory
|
||||||
|
|
||||||
|
diff -rul --exclude \*.pyc . /tmp/fail2ban-0.8.11/
|
||||||
|
|
||||||
|
# Only differences should be files that you don't want distributed.
|
||||||
|
|
||||||
|
# Ensure the tests work from the tarball
|
||||||
|
|
||||||
|
cd /tmp/fail2ban-0.8.11/ && ./fail2ban-testcases-all
|
||||||
|
|
||||||
# Add/finalize the corresponding entry in the ChangeLog
|
# Add/finalize the corresponding entry in the ChangeLog
|
||||||
|
|
||||||
To generate a list of committers use e.g.
|
To generate a list of committers use e.g.
|
||||||
|
|
||||||
git shortlog -sn 0.8.8.. | sed -e 's,^[ 0-9\t]*,,g' | tr '\n' '\|' | sed -e 's:|:, :g'
|
git shortlog -sn 0.8.10.. | sed -e 's,^[ 0-9\t]*,,g' | tr '\n' '\|' | sed -e 's:|:, :g'
|
||||||
|
|
||||||
Ensure the top of the ChangeLog has the right version and current date.
|
Ensure the top of the ChangeLog has the right version and current date.
|
||||||
|
|
||||||
|
@ -322,23 +716,59 @@ Releasing
|
||||||
# Update man pages
|
# Update man pages
|
||||||
|
|
||||||
(cd man ; ./generate-man )
|
(cd man ; ./generate-man )
|
||||||
git commit -m 'update man pages for release' man/*
|
git commit -m 'DOC/ENH: update man pages for release' man/*
|
||||||
|
|
||||||
# Make sure the tests pass
|
# Prepare source and rpm binary distributions
|
||||||
|
|
||||||
./fail2ban-testcases-all
|
|
||||||
|
|
||||||
# Prepare/upload source and rpm binary distributions
|
|
||||||
|
|
||||||
python setup.py check
|
|
||||||
python setup.py sdist
|
python setup.py sdist
|
||||||
python setup.py bdist_rpm
|
python setup.py bdist_rpm
|
||||||
python setup.py upload
|
python setup.py upload
|
||||||
|
|
||||||
# Run the following and update the wiki with output:
|
# Provide a release sample to distributors
|
||||||
|
|
||||||
|
* Debian: Yaroslav Halchenko <debian@onerussian.com>
|
||||||
|
http://packages.qa.debian.org/f/fail2ban.html
|
||||||
|
* FreeBSD: Christoph Theis theis@gmx.at>, Nick Hilliard <nick@foobar.org>
|
||||||
|
http://svnweb.freebsd.org/ports/head/security/py-fail2ban/Makefile?view=markup
|
||||||
|
http://www.freebsd.org/cgi/query-pr-summary.cgi?text=fail2ban
|
||||||
|
* Fedora: Axel Thimm <Axel.Thimm@atrpms.net>
|
||||||
|
https://apps.fedoraproject.org/packages/fail2ban
|
||||||
|
http://pkgs.fedoraproject.org/cgit/fail2ban.git
|
||||||
|
https://admin.fedoraproject.org/pkgdb/acls/bugs/fail2ban
|
||||||
|
* Gentoo: netmon@gentoo.org
|
||||||
|
http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/net-analyzer/fail2ban/metadata.xml?view=markup
|
||||||
|
https://bugs.gentoo.org/buglist.cgi?quicksearch=fail2ban
|
||||||
|
* openSUSE: Stephan Kulow <coolo@suse.com>
|
||||||
|
https://build.opensuse.org/package/show/openSUSE:Factory/fail2ban
|
||||||
|
* Mac Ports: @Malbrouck on github (gh-49)
|
||||||
|
https://trac.macports.org/browser/trunk/dports/security/fail2ban/Portfile
|
||||||
|
* Mageia:
|
||||||
|
https://bugs.mageia.org/buglist.cgi?quicksearch=fail2ban
|
||||||
|
An potentially to the fail2ban-users directory.
|
||||||
|
|
||||||
|
# Wait for feedback from distributors
|
||||||
|
|
||||||
|
# Prepare a release notice https://github.com/fail2ban/fail2ban/releases/new
|
||||||
|
|
||||||
|
Upload the source/binaries from the dist directory and tag the release using the URL
|
||||||
|
|
||||||
|
# Upload source/binaries to sourceforge http://sourceforge.net/projects/fail2ban/
|
||||||
|
|
||||||
|
# Run the following and update the wiki with output:
|
||||||
python -c 'import common.protocol; common.protocol.printWiki()'
|
python -c 'import common.protocol; common.protocol.printWiki()'
|
||||||
|
|
||||||
|
page: http://www.fail2ban.org/wiki/index.php/Commands
|
||||||
|
|
||||||
|
* Update:
|
||||||
|
http://www.fail2ban.org/wiki/index.php/Downloads
|
||||||
|
http://www.fail2ban.org/wiki/index.php/ChangeLog
|
||||||
|
http://www.fail2ban.org/wiki/index.php/Requirements (Check requirement)
|
||||||
|
http://www.fail2ban.org/wiki/index.php/Main_Page (Add to News)
|
||||||
|
http://www.fail2ban.org/wiki/index.php/Features
|
||||||
|
|
||||||
|
* See if any filters are upgraded:
|
||||||
|
http://www.fail2ban.org/wiki/index.php/Special:AllPages
|
||||||
|
|
||||||
# Email users and development list of release
|
# Email users and development list of release
|
||||||
|
|
||||||
# notify distributors
|
# notify distributors
|
||||||
|
@ -348,10 +778,17 @@ Post Release
|
||||||
|
|
||||||
Add the following to the top of the ChangeLog
|
Add the following to the top of the ChangeLog
|
||||||
|
|
||||||
ver. 0.8.11 (2013/XX/XXX) - wanna-be-stable
|
ver. 0.8.12 (2013/XX/XXX) - wanna-be-released
|
||||||
- Fixes
|
-----------
|
||||||
- New Features
|
|
||||||
- Enhancements
|
- Fixes:
|
||||||
|
|
||||||
|
- New Features:
|
||||||
|
|
||||||
|
- Enhancements:
|
||||||
|
|
||||||
|
Alter the git shortlog command in the previous section to refer to the just
|
||||||
|
released version.
|
||||||
|
|
||||||
and adjust common/version.py to carry .dev suffix to signal
|
and adjust common/version.py to carry .dev suffix to signal
|
||||||
a version under development.
|
a version under development.
|
||||||
|
|
81
MANIFEST
81
MANIFEST
|
@ -5,11 +5,14 @@ TODO
|
||||||
THANKS
|
THANKS
|
||||||
COPYING
|
COPYING
|
||||||
DEVELOP
|
DEVELOP
|
||||||
doc/run-rootless.txt
|
|
||||||
fail2ban-client
|
fail2ban-client
|
||||||
fail2ban-server
|
fail2ban-server
|
||||||
fail2ban-testcases
|
fail2ban-testcases
|
||||||
fail2ban-regex
|
fail2ban-regex
|
||||||
|
fail2ban-testcases-all
|
||||||
|
setup.py
|
||||||
|
setup.cfg
|
||||||
|
kill-server
|
||||||
client/configreader.py
|
client/configreader.py
|
||||||
client/configparserinc.py
|
client/configparserinc.py
|
||||||
client/jailreader.py
|
client/jailreader.py
|
||||||
|
@ -43,6 +46,8 @@ server/banmanager.py
|
||||||
server/datetemplate.py
|
server/datetemplate.py
|
||||||
server/mytime.py
|
server/mytime.py
|
||||||
server/failregex.py
|
server/failregex.py
|
||||||
|
testcases/actionstestcase.py
|
||||||
|
testcases/dummyjail.py
|
||||||
testcases/files/testcase-usedns.log
|
testcases/files/testcase-usedns.log
|
||||||
testcases/files/logs/bsd/syslog-plain.txt
|
testcases/files/logs/bsd/syslog-plain.txt
|
||||||
testcases/files/logs/bsd/syslog-v.txt
|
testcases/files/logs/bsd/syslog-v.txt
|
||||||
|
@ -52,21 +57,61 @@ testcases/files/logs/assp
|
||||||
testcases/files/logs/asterisk
|
testcases/files/logs/asterisk
|
||||||
testcases/files/logs/dovecot
|
testcases/files/logs/dovecot
|
||||||
testcases/files/logs/exim
|
testcases/files/logs/exim
|
||||||
testcases/files/logs/lighttpd
|
testcases/files/logs/suhosin
|
||||||
testcases/files/logs/mysqld.log
|
testcases/files/logs/mysqld-auth
|
||||||
testcases/files/logs/named-refused
|
testcases/files/logs/named-refused
|
||||||
testcases/files/logs/pam-generic
|
testcases/files/logs/pam-generic
|
||||||
testcases/files/logs/postfix
|
testcases/files/logs/postfix
|
||||||
testcases/files/logs/proftpd
|
testcases/files/logs/proftpd
|
||||||
testcases/files/logs/pure-ftpd
|
testcases/files/logs/pure-ftpd
|
||||||
testcases/files/logs/roundcube-auth
|
testcases/files/logs/roundcube-auth
|
||||||
testcases/files/logs/sasl
|
testcases/files/logs/postfix-sasl
|
||||||
testcases/files/logs/sogo-auth
|
testcases/files/logs/sogo-auth
|
||||||
testcases/files/logs/sshd
|
testcases/files/logs/sshd
|
||||||
testcases/files/logs/sshd-ddos
|
testcases/files/logs/sshd-ddos
|
||||||
testcases/files/logs/vsftpd
|
testcases/files/logs/vsftpd
|
||||||
testcases/files/logs/webmin-auth
|
testcases/files/logs/webmin-auth
|
||||||
testcases/files/logs/wu-ftpd
|
testcases/files/logs/wuftpd
|
||||||
|
testcases/files/logs/3proxy
|
||||||
|
testcases/files/logs/apache-auth
|
||||||
|
testcases/files/logs/apache-badbots
|
||||||
|
testcases/files/logs/apache-nohome
|
||||||
|
testcases/files/logs/apache-noscript
|
||||||
|
testcases/files/logs/courierlogin
|
||||||
|
testcases/files/logs/couriersmtp
|
||||||
|
testcases/files/logs/cyrus-imap
|
||||||
|
testcases/files/logs/dropbear
|
||||||
|
testcases/files/logs/exim-spam
|
||||||
|
testcases/files/logs/gssftpd
|
||||||
|
testcases/files/logs/lighttpd-auth
|
||||||
|
testcases/files/logs/mysqld-auth
|
||||||
|
testcases/files/logs/perdition
|
||||||
|
testcases/files/logs/php-url-fopen
|
||||||
|
testcases/files/logs/qmail
|
||||||
|
testcases/files/logs/recidive
|
||||||
|
testcases/files/logs/sieve
|
||||||
|
testcases/files/logs/selinux-ssh
|
||||||
|
testcases/files/logs/suhosin
|
||||||
|
testcases/files/logs/uwimap-auth
|
||||||
|
testcases/files/logs/wuftpd
|
||||||
|
testcases/files/logs/xinetd-fail
|
||||||
|
testcases/files/config/apache-auth/digest/.htaccess
|
||||||
|
testcases/files/config/apache-auth/digest/.htpasswd
|
||||||
|
testcases/files/config/apache-auth/digest_time/.htaccess
|
||||||
|
testcases/files/config/apache-auth/digest_time/.htpasswd
|
||||||
|
testcases/files/config/apache-auth/basic/authz_owner/.htaccess
|
||||||
|
testcases/files/config/apache-auth/basic/authz_owner/cant_get_me.html
|
||||||
|
testcases/files/config/apache-auth/basic/authz_owner/.htpasswd
|
||||||
|
testcases/files/config/apache-auth/basic/file/.htaccess
|
||||||
|
testcases/files/config/apache-auth/basic/file/.htpasswd
|
||||||
|
testcases/files/config/apache-auth/digest.py
|
||||||
|
testcases/files/config/apache-auth/digest_wrongrelm/.htaccess
|
||||||
|
testcases/files/config/apache-auth/digest_wrongrelm/.htpasswd
|
||||||
|
testcases/files/config/apache-auth/digest_anon/.htaccess
|
||||||
|
testcases/files/config/apache-auth/digest_anon/.htpasswd
|
||||||
|
testcases/files/config/apache-auth/README
|
||||||
|
testcases/files/config/apache-auth/noentry/.htaccess
|
||||||
|
testcases/samplestestcase.py
|
||||||
testcases/banmanagertestcase.py
|
testcases/banmanagertestcase.py
|
||||||
testcases/failmanagertestcase.py
|
testcases/failmanagertestcase.py
|
||||||
testcases/clientreadertestcase.py
|
testcases/clientreadertestcase.py
|
||||||
|
@ -82,8 +127,6 @@ testcases/files/testcase03.log
|
||||||
testcases/files/testcase04.log
|
testcases/files/testcase04.log
|
||||||
testcases/misctestcase.py
|
testcases/misctestcase.py
|
||||||
testcases/utils.py
|
testcases/utils.py
|
||||||
setup.py
|
|
||||||
setup.cfg
|
|
||||||
common/__init__.py
|
common/__init__.py
|
||||||
common/exceptions.py
|
common/exceptions.py
|
||||||
common/helpers.py
|
common/helpers.py
|
||||||
|
@ -101,7 +144,7 @@ config/filter.d/couriersmtp.conf
|
||||||
config/filter.d/cyrus-imap.conf
|
config/filter.d/cyrus-imap.conf
|
||||||
config/filter.d/exim.conf
|
config/filter.d/exim.conf
|
||||||
config/filter.d/gssftpd.conf
|
config/filter.d/gssftpd.conf
|
||||||
config/filter.d/lighttpd-fastcgi.conf
|
config/filter.d/suhosin.conf
|
||||||
config/filter.d/named-refused.conf
|
config/filter.d/named-refused.conf
|
||||||
config/filter.d/postfix.conf
|
config/filter.d/postfix.conf
|
||||||
config/filter.d/proftpd.conf
|
config/filter.d/proftpd.conf
|
||||||
|
@ -109,7 +152,7 @@ config/filter.d/pure-ftpd.conf
|
||||||
config/filter.d/qmail.conf
|
config/filter.d/qmail.conf
|
||||||
config/filter.d/pam-generic.conf
|
config/filter.d/pam-generic.conf
|
||||||
config/filter.d/php-url-fopen.conf
|
config/filter.d/php-url-fopen.conf
|
||||||
config/filter.d/sasl.conf
|
config/filter.d/postfix-sasl.conf
|
||||||
config/filter.d/sieve.conf
|
config/filter.d/sieve.conf
|
||||||
config/filter.d/sshd.conf
|
config/filter.d/sshd.conf
|
||||||
config/filter.d/sshd-ddos.conf
|
config/filter.d/sshd-ddos.conf
|
||||||
|
@ -124,10 +167,24 @@ config/filter.d/lighttpd-auth.conf
|
||||||
config/filter.d/recidive.conf
|
config/filter.d/recidive.conf
|
||||||
config/filter.d/roundcube-auth.conf
|
config/filter.d/roundcube-auth.conf
|
||||||
config/filter.d/assp.conf
|
config/filter.d/assp.conf
|
||||||
config/filter.d/mysqld-auth.conf
|
|
||||||
config/filter.d/sogo-auth.conf
|
config/filter.d/sogo-auth.conf
|
||||||
|
config/filter.d/mysqld-auth.conf
|
||||||
|
config/filter.d/selinux-common.conf
|
||||||
|
config/filter.d/selinux-ssh.conf
|
||||||
|
config/filter.d/3proxy.conf
|
||||||
|
config/filter.d/apache-common.conf
|
||||||
|
config/filter.d/exim-common.conf
|
||||||
|
config/filter.d/exim-spam.conf
|
||||||
|
config/filter.d/perdition.conf
|
||||||
|
config/filter.d/uwimap-auth.conf
|
||||||
|
config/action.d/apf.conf
|
||||||
|
config/action.d/osx-afctl.conf
|
||||||
|
config/action.d/osx-ipfw.conf
|
||||||
|
config/action.d/sendmail-common.conf
|
||||||
config/action.d/bsd-ipfw.conf
|
config/action.d/bsd-ipfw.conf
|
||||||
config/action.d/dummy.conf
|
config/action.d/dummy.conf
|
||||||
|
config/action.d/firewall-cmd-direct-new.conf
|
||||||
|
config/action.d/iptables-ipset-proto6-allports.conf
|
||||||
config/action.d/iptables-blocktype.conf
|
config/action.d/iptables-blocktype.conf
|
||||||
config/action.d/iptables-ipset-proto4.conf
|
config/action.d/iptables-ipset-proto4.conf
|
||||||
config/action.d/iptables-ipset-proto6.conf
|
config/action.d/iptables-ipset-proto6.conf
|
||||||
|
@ -155,6 +212,7 @@ config/action.d/sendmail-whois.conf
|
||||||
config/action.d/sendmail-whois-lines.conf
|
config/action.d/sendmail-whois-lines.conf
|
||||||
config/action.d/shorewall.conf
|
config/action.d/shorewall.conf
|
||||||
config/fail2ban.conf
|
config/fail2ban.conf
|
||||||
|
doc/run-rootless.txt
|
||||||
man/fail2ban-client.1
|
man/fail2ban-client.1
|
||||||
man/fail2ban.1
|
man/fail2ban.1
|
||||||
man/jail.conf.5
|
man/jail.conf.5
|
||||||
|
@ -176,9 +234,8 @@ files/cacti/fail2ban_stats.sh
|
||||||
files/cacti/cacti_host_template_fail2ban.xml
|
files/cacti/cacti_host_template_fail2ban.xml
|
||||||
files/cacti/README
|
files/cacti/README
|
||||||
files/nagios/check_fail2ban
|
files/nagios/check_fail2ban
|
||||||
files/nagios/f2ban.txt
|
files/nagios/README
|
||||||
files/bash-completion
|
files/bash-completion
|
||||||
files/fail2ban-tmpfiles.conf
|
files/fail2ban-tmpfiles.conf
|
||||||
files/fail2ban.service
|
files/fail2ban.service
|
||||||
files/ipmasq-ZZZzzz_fail2ban.rul
|
files/ipmasq-ZZZzzz_fail2ban.rul
|
||||||
files/nagios/README
|
|
||||||
|
|
|
@ -69,27 +69,10 @@ FAIL2BAN CONFIGURATION
|
||||||
|
|
||||||
OPT: Create /etc/fail2ban/fail2ban.local containing:
|
OPT: Create /etc/fail2ban/fail2ban.local containing:
|
||||||
|
|
||||||
# Fail2Ban main configuration file
|
# Fail2Ban configuration file for logging fail2ban on Solaris
|
||||||
#
|
|
||||||
# Comments: use '#' for comment lines and ';' (following a space) for inline comments
|
|
||||||
#
|
|
||||||
# Changes: in most of the cases you should not modify this
|
|
||||||
# file, but provide customizations in fail2ban.local file, e.g.:
|
|
||||||
#
|
|
||||||
# [Definition]
|
|
||||||
# loglevel = 4
|
|
||||||
#
|
#
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: logtarget
|
|
||||||
# Notes.: Set the log target. This could be a file, SYSLOG, STDERR or STDOUT.
|
|
||||||
# Only one log target can be specified.
|
|
||||||
# If you change logtarget from the default value and you are
|
|
||||||
# using logrotate -- also adjust or disable rotation in the
|
|
||||||
# corresponding configuration file
|
|
||||||
# (e.g. /etc/logrotate.d/fail2ban on Debian systems)
|
|
||||||
# Values: STDOUT STDERR SYSLOG file Default: /var/log/fail2ban.log
|
|
||||||
#
|
|
||||||
logtarget = /var/adm/fail2ban.log
|
logtarget = /var/adm/fail2ban.log
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,13 +82,13 @@ REQ: Create /etc/fail2ban/jail.local containing:
|
||||||
|
|
||||||
enabled = true
|
enabled = true
|
||||||
filter = sshd
|
filter = sshd
|
||||||
action = hostsdeny
|
action = hostsdeny[daemon_list=sshd]
|
||||||
sendmail-whois[name=SSH, dest=you@example.com]
|
sendmail-whois[name=SSH, dest=you@example.com]
|
||||||
ignoreregex = for myuser from
|
ignoreregex = for myuser from
|
||||||
logpath = /var/adm/auth.log
|
logpath = /var/adm/auth.log
|
||||||
|
|
||||||
Set the sendmail dest address to something useful or drop the line to stop it spamming you.
|
Set the sendmail dest address to something useful or drop the line to stop it spamming you.
|
||||||
Set 'myuser' to your username to avoid banning yourself or drop it.
|
Set 'myuser' to your username to avoid banning yourself or remove the line.
|
||||||
|
|
||||||
START (OR RESTART) FAIL2BAN
|
START (OR RESTART) FAIL2BAN
|
||||||
|
|
||||||
|
@ -128,7 +111,7 @@ GOTCHAS AND FIXMES
|
||||||
svcadm enable fail2ban
|
svcadm enable fail2ban
|
||||||
|
|
||||||
* If svcs -xv says that fail2ban failed to start or svcs says it's in maintenance mode
|
* If svcs -xv says that fail2ban failed to start or svcs says it's in maintenance mode
|
||||||
chcek /var/svc/log/network-fail2ban:default.log for clues.
|
check /var/svc/log/network-fail2ban:default.log for clues.
|
||||||
Check permissions on /var/adm, /var/adm/auth.log /var/adm/fail2ban.log and /var/run/fail2ban
|
Check permissions on /var/adm, /var/adm/auth.log /var/adm/fail2ban.log and /var/run/fail2ban
|
||||||
You may need to:
|
You may need to:
|
||||||
|
|
||||||
|
@ -136,6 +119,4 @@ GOTCHAS AND FIXMES
|
||||||
|
|
||||||
* Fail2ban adds lines like these to /etc/hosts.deny:
|
* Fail2ban adds lines like these to /etc/hosts.deny:
|
||||||
|
|
||||||
ALL: 1.2.3.4
|
sshd: 1.2.3.4
|
||||||
|
|
||||||
wouldn't it be better to just block sshd?
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/ _|__ _(_) |_ ) |__ __ _ _ _
|
/ _|__ _(_) |_ ) |__ __ _ _ _
|
||||||
| _/ _` | | |/ /| '_ \/ _` | ' \
|
| _/ _` | | |/ /| '_ \/ _` | ' \
|
||||||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||||
v0.8.10 2013/06/12
|
v0.8.11-pre1 2013/10/30
|
||||||
|
|
||||||
## Fail2Ban: ban hosts that cause multiple authentication errors
|
## Fail2Ban: ban hosts that cause multiple authentication errors
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ Optional:
|
||||||
|
|
||||||
To install, just do:
|
To install, just do:
|
||||||
|
|
||||||
tar xvfj fail2ban-0.8.10.tar.bz2
|
tar xvfj fail2ban-0.8.11.tar.bz2
|
||||||
cd fail2ban-0.8.10
|
cd fail2ban-0.8.11
|
||||||
python setup.py install
|
python setup.py install
|
||||||
|
|
||||||
This will install Fail2Ban into /usr/share/fail2ban. The executable scripts are
|
This will install Fail2Ban into /usr/share/fail2ban. The executable scripts are
|
||||||
|
|
35
THANKS
35
THANKS
|
@ -1,44 +1,65 @@
|
||||||
Fail2Ban is an open source project with many contributions from its
|
Fail2Ban is an open source project which was conceived and originally
|
||||||
users community. Below is an alphabetically sorted partial list of the
|
developed by Cyril Jaquier until 2010. Since then Fail2Ban grew into
|
||||||
contributors to the project. If you have been left off, please let us
|
a community-driven project with many contributions from its users.
|
||||||
know (preferably send a pull request on github with the "fix") and you
|
Below is an alphabetically sorted partial list of the contributors to
|
||||||
will be added
|
the project. If you have been left off, please let us know
|
||||||
|
(preferably send a pull request on github with the "fix") and you will
|
||||||
|
be added
|
||||||
|
|
||||||
Adrien Clerc
|
Adrien Clerc
|
||||||
|
ache
|
||||||
|
Amir Caspi
|
||||||
Andrey G. Grozin
|
Andrey G. Grozin
|
||||||
|
Andy Fragen
|
||||||
Arturo 'Buanzo' Busleiman
|
Arturo 'Buanzo' Busleiman
|
||||||
Axel Thimm
|
Axel Thimm
|
||||||
|
Beau Raines
|
||||||
Bill Heaton
|
Bill Heaton
|
||||||
Carlos Alberto Lopez Perez
|
Carlos Alberto Lopez Perez
|
||||||
Christian Rauch
|
Christian Rauch
|
||||||
|
Christophe Carles
|
||||||
Christoph Haas
|
Christoph Haas
|
||||||
Christos Psonis
|
Christos Psonis
|
||||||
|
Cyril Jaquier
|
||||||
Daniel B. Cid
|
Daniel B. Cid
|
||||||
Daniel Black
|
Daniel Black
|
||||||
David Nutter
|
David Nutter
|
||||||
Eric Gerbier
|
Eric Gerbier
|
||||||
Enrico Labedzki
|
Enrico Labedzki
|
||||||
|
ftoppi
|
||||||
|
François Boulogne
|
||||||
|
Frédéric
|
||||||
|
Georgiy Mernov
|
||||||
Guillaume Delvit
|
Guillaume Delvit
|
||||||
Hanno 'Rince' Wagner
|
Hanno 'Rince' Wagner
|
||||||
Iain Lea
|
Iain Lea
|
||||||
Jonathan Kamens
|
Jonathan Kamens
|
||||||
Jonathan Underwood
|
Jonathan Underwood
|
||||||
Joël Bertrand
|
Joël Bertrand
|
||||||
|
JP Espinosa
|
||||||
Justin Shore
|
Justin Shore
|
||||||
Kévin Drapel
|
Kévin Drapel
|
||||||
|
kjohnsonecl
|
||||||
kojiro
|
kojiro
|
||||||
|
Manuel Arostegui Ramirez
|
||||||
|
Marcel Dopita
|
||||||
Mark Edgington
|
Mark Edgington
|
||||||
|
Mark McKinstry
|
||||||
Markus Hoffmann
|
Markus Hoffmann
|
||||||
Marvin Rouge
|
Marvin Rouge
|
||||||
mEDI
|
mEDI
|
||||||
|
Мернов Георгий
|
||||||
Michael C. Haller
|
Michael C. Haller
|
||||||
Michael Hanselmann
|
Michael Hanselmann
|
||||||
NickMunger
|
Nick Munger
|
||||||
Patrick Börjesson
|
Patrick Börjesson
|
||||||
Raphaël Marichez
|
Raphaël Marichez
|
||||||
|
RealRancor
|
||||||
René Berber
|
René Berber
|
||||||
Robert Edeker
|
Robert Edeker
|
||||||
|
Rolf Fokkens
|
||||||
Russell Odom
|
Russell Odom
|
||||||
|
Sebastian Arcus
|
||||||
Sireyessire
|
Sireyessire
|
||||||
silviogarbes
|
silviogarbes
|
||||||
Stephen Gildea
|
Stephen Gildea
|
||||||
|
@ -48,5 +69,7 @@ Tyler
|
||||||
Vaclav Misek
|
Vaclav Misek
|
||||||
Vincent Deffontaines
|
Vincent Deffontaines
|
||||||
Yaroslav Halchenko
|
Yaroslav Halchenko
|
||||||
|
ykimon
|
||||||
Yehuda Katz
|
Yehuda Katz
|
||||||
zugeschmiert
|
zugeschmiert
|
||||||
|
Zurd
|
||||||
|
|
|
@ -54,16 +54,19 @@ class ConfigReader(SafeConfigParserWithIncludes):
|
||||||
% self._basedir)
|
% self._basedir)
|
||||||
basename = os.path.join(self._basedir, filename)
|
basename = os.path.join(self._basedir, filename)
|
||||||
logSys.debug("Reading configs for %s under %s " % (basename, self._basedir))
|
logSys.debug("Reading configs for %s under %s " % (basename, self._basedir))
|
||||||
config_files = [ basename + ".conf",
|
config_files = [ basename + ".conf" ]
|
||||||
basename + ".local" ]
|
|
||||||
|
|
||||||
# choose only existing ones
|
|
||||||
config_files = filter(os.path.exists, config_files)
|
|
||||||
|
|
||||||
# possible further customizations under a .conf.d directory
|
# possible further customizations under a .conf.d directory
|
||||||
config_dir = basename + '.d'
|
config_dir = basename + '.d'
|
||||||
config_files += sorted(glob.glob('%s/*.conf' % config_dir))
|
config_files += sorted(glob.glob('%s/*.conf' % config_dir))
|
||||||
|
|
||||||
|
config_files.append(basename + ".local")
|
||||||
|
|
||||||
|
config_files += sorted(glob.glob('%s/*.local' % config_dir))
|
||||||
|
|
||||||
|
# choose only existing ones
|
||||||
|
config_files = filter(os.path.exists, config_files)
|
||||||
|
|
||||||
if len(config_files):
|
if len(config_files):
|
||||||
# at least one config exists and accessible
|
# at least one config exists and accessible
|
||||||
logSys.debug("Reading config files: " + ', '.join(config_files))
|
logSys.debug("Reading config files: " + ', '.join(config_files))
|
||||||
|
|
|
@ -39,7 +39,7 @@ class Fail2banReader(ConfigReader):
|
||||||
ConfigReader.read(self, "fail2ban")
|
ConfigReader.read(self, "fail2ban")
|
||||||
|
|
||||||
def getEarlyOptions(self):
|
def getEarlyOptions(self):
|
||||||
opts = [["string", "socket", "/tmp/fail2ban.sock"],
|
opts = [["string", "socket", "/var/run/fail2ban/fail2ban.sock"],
|
||||||
["string", "pidfile", "/var/run/fail2ban/fail2ban.pid"]]
|
["string", "pidfile", "/var/run/fail2ban/fail2ban.pid"]]
|
||||||
return ConfigReader.getOptions(self, "Definition", opts)
|
return ConfigReader.getOptions(self, "Definition", opts)
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ __author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import logging, re, glob
|
import logging, re, glob, os.path
|
||||||
|
|
||||||
from configreader import ConfigReader
|
from configreader import ConfigReader
|
||||||
from filterreader import FilterReader
|
from filterreader import FilterReader
|
||||||
|
@ -55,7 +55,23 @@ class JailReader(ConfigReader):
|
||||||
|
|
||||||
def isEnabled(self):
|
def isEnabled(self):
|
||||||
return self.__force_enable or self.__opts["enabled"]
|
return self.__force_enable or self.__opts["enabled"]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _glob(path):
|
||||||
|
"""Given a path for glob return list of files to be passed to server.
|
||||||
|
|
||||||
|
Dangling symlinks are warned about and not returned
|
||||||
|
"""
|
||||||
|
pathList = []
|
||||||
|
for p in glob.glob(path):
|
||||||
|
if not os.path.exists(p):
|
||||||
|
logSys.warning("File %s doesn't even exist, thus cannot be monitored" % p)
|
||||||
|
elif not os.path.lexists(p):
|
||||||
|
logSys.warning("File %s is a dangling link, thus cannot be monitored" % p)
|
||||||
|
else:
|
||||||
|
pathList.append(p)
|
||||||
|
return pathList
|
||||||
|
|
||||||
def getOptions(self):
|
def getOptions(self):
|
||||||
opts = [["bool", "enabled", "false"],
|
opts = [["bool", "enabled", "false"],
|
||||||
["string", "logpath", "/var/log/messages"],
|
["string", "logpath", "/var/log/messages"],
|
||||||
|
@ -103,16 +119,30 @@ class JailReader(ConfigReader):
|
||||||
logSys.warn("No actions were defined for %s" % self.__name)
|
logSys.warn("No actions were defined for %s" % self.__name)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def convert(self):
|
def convert(self, allow_no_files=False):
|
||||||
|
"""Convert read before __opts to the commands stream
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
allow_missing : bool
|
||||||
|
Either to allow log files to be missing entirely. Primarily is
|
||||||
|
used for testing
|
||||||
|
"""
|
||||||
|
|
||||||
stream = []
|
stream = []
|
||||||
for opt in self.__opts:
|
for opt in self.__opts:
|
||||||
if opt == "logpath":
|
if opt == "logpath":
|
||||||
|
found_files = 0
|
||||||
for path in self.__opts[opt].split("\n"):
|
for path in self.__opts[opt].split("\n"):
|
||||||
pathList = glob.glob(path)
|
pathList = JailReader._glob(path)
|
||||||
if len(pathList) == 0:
|
if len(pathList) == 0:
|
||||||
logSys.error("No file found for " + path)
|
logSys.error("No file(s) found for glob %s" % path)
|
||||||
for p in pathList:
|
for p in pathList:
|
||||||
|
found_files += 1
|
||||||
stream.append(["set", self.__name, "addlogpath", p])
|
stream.append(["set", self.__name, "addlogpath", p])
|
||||||
|
if not (found_files or allow_no_files):
|
||||||
|
raise ValueError(
|
||||||
|
"Have not found any log file for %s jail" % self.__name)
|
||||||
elif opt == "backend":
|
elif opt == "backend":
|
||||||
backend = self.__opts[opt]
|
backend = self.__opts[opt]
|
||||||
elif opt == "maxretry":
|
elif opt == "maxretry":
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
# Author: Cyril Jaquier
|
# Author: Cyril Jaquier
|
||||||
#
|
#
|
||||||
|
|
||||||
__author__ = "Cyril Jaquier"
|
__author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
|
@ -32,7 +32,7 @@ from jailreader import JailReader
|
||||||
logSys = logging.getLogger("fail2ban.client.config")
|
logSys = logging.getLogger("fail2ban.client.config")
|
||||||
|
|
||||||
class JailsReader(ConfigReader):
|
class JailsReader(ConfigReader):
|
||||||
|
|
||||||
def __init__(self, force_enable=False, **kwargs):
|
def __init__(self, force_enable=False, **kwargs):
|
||||||
"""
|
"""
|
||||||
Parameters
|
Parameters
|
||||||
|
@ -44,17 +44,25 @@ class JailsReader(ConfigReader):
|
||||||
ConfigReader.__init__(self, **kwargs)
|
ConfigReader.__init__(self, **kwargs)
|
||||||
self.__jails = list()
|
self.__jails = list()
|
||||||
self.__force_enable = force_enable
|
self.__force_enable = force_enable
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
return ConfigReader.read(self, "jail")
|
return ConfigReader.read(self, "jail")
|
||||||
|
|
||||||
def getOptions(self, section = None):
|
def getOptions(self, section=None):
|
||||||
|
"""Reads configuration for jail(s) and adds enabled jails to __jails
|
||||||
|
"""
|
||||||
opts = []
|
opts = []
|
||||||
self.__opts = ConfigReader.getOptions(self, "Definition", opts)
|
self.__opts = ConfigReader.getOptions(self, "Definition", opts)
|
||||||
|
|
||||||
if section:
|
if section is None:
|
||||||
# Get the options of a specific jail.
|
sections = self.sections()
|
||||||
jail = JailReader(section, basedir=self.getBaseDir(), force_enable=self.__force_enable)
|
else:
|
||||||
|
sections = [ section ]
|
||||||
|
|
||||||
|
# Get the options of all jails.
|
||||||
|
for sec in sections:
|
||||||
|
jail = JailReader(sec, basedir=self.getBaseDir(),
|
||||||
|
force_enable=self.__force_enable)
|
||||||
jail.read()
|
jail.read()
|
||||||
ret = jail.getOptions()
|
ret = jail.getOptions()
|
||||||
if ret:
|
if ret:
|
||||||
|
@ -62,34 +70,30 @@ class JailsReader(ConfigReader):
|
||||||
# We only add enabled jails
|
# We only add enabled jails
|
||||||
self.__jails.append(jail)
|
self.__jails.append(jail)
|
||||||
else:
|
else:
|
||||||
logSys.error("Errors in jail '%s'. Skipping..." % section)
|
logSys.error("Errors in jail %r. Skipping..." % sec)
|
||||||
return False
|
return False
|
||||||
else:
|
|
||||||
# Get the options of all jails.
|
|
||||||
for sec in self.sections():
|
|
||||||
jail = JailReader(sec, basedir=self.getBaseDir(), force_enable=self.__force_enable)
|
|
||||||
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...")
|
|
||||||
return False
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def convert(self):
|
def convert(self, allow_no_files=False):
|
||||||
|
"""Convert read before __opts and jails to the commands stream
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
allow_missing : bool
|
||||||
|
Either to allow log files to be missing entirely. Primarily is
|
||||||
|
used for testing
|
||||||
|
"""
|
||||||
|
|
||||||
stream = list()
|
stream = list()
|
||||||
for opt in self.__opts:
|
for opt in self.__opts:
|
||||||
if opt == "":
|
if opt == "":
|
||||||
stream.append([])
|
stream.append([])
|
||||||
# Convert jails
|
# Convert jails
|
||||||
for jail in self.__jails:
|
for jail in self.__jails:
|
||||||
stream.extend(jail.convert())
|
stream.extend(jail.convert(allow_no_files=allow_no_files))
|
||||||
# Start jails
|
# Start jails
|
||||||
for jail in self.__jails:
|
for jail in self.__jails:
|
||||||
stream.append(["start", jail.getName()])
|
stream.append(["start", jail.getName()])
|
||||||
|
|
||||||
return stream
|
return stream
|
||||||
|
|
||||||
|
|
|
@ -23,3 +23,8 @@
|
||||||
__author__ = "Cyril Jaquier"
|
__author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# Custom debug level
|
||||||
|
logging.HEAVYDEBUG = 5
|
||||||
|
|
|
@ -17,24 +17,12 @@
|
||||||
# along with Fail2Ban; if not, write to the Free Software
|
# along with Fail2Ban; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
__author__ = "Cyril Jaquier, Arturo 'Buanzo' Busleiman"
|
__author__ = "Cyril Jaquier, Arturo 'Buanzo' Busleiman, Yaroslav Halchenko"
|
||||||
__copyright__ = "Copyright (c) 2009 Cyril Jaquier"
|
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
|
|
||||||
def formatExceptionInfo():
|
def formatExceptionInfo():
|
||||||
""" Author: Arturo 'Buanzo' Busleiman """
|
""" Consistently format exception information """
|
||||||
import sys
|
import sys
|
||||||
cla, exc = sys.exc_info()[:2]
|
cla, exc = sys.exc_info()[:2]
|
||||||
excName = cla.__name__
|
return (cla.__name__, str(exc))
|
||||||
try:
|
|
||||||
excArgs = exc.__dict__["args"]
|
|
||||||
# Assure that we always return a string, without unneeded
|
|
||||||
# 'decorations' with python <= 2.5 where args would be a tuple
|
|
||||||
if isinstance(excArgs, tuple) and len(excArgs) == 1:
|
|
||||||
excArgs = excArgs[0]
|
|
||||||
excArgs = str(excArgs)
|
|
||||||
except KeyError:
|
|
||||||
# And always provide a string output
|
|
||||||
excArgs = str(exc)
|
|
||||||
return (excName, excArgs)
|
|
||||||
|
|
|
@ -24,4 +24,4 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
version = "0.8.10"
|
version = "0.8.11.pre1"
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
# Fail2Ban configuration file
|
||||||
|
#
|
||||||
|
# Author: Mark McKinstry
|
||||||
|
#
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
# Option: actionstart
|
||||||
|
# Notes.: command executed once at the start of Fail2Ban.
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actionstart =
|
||||||
|
|
||||||
|
# Option: actionstop
|
||||||
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actionstop =
|
||||||
|
|
||||||
|
# Option: actioncheck
|
||||||
|
# Notes.: command executed once before each actionban command
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actioncheck =
|
||||||
|
|
||||||
|
# Option: actionban
|
||||||
|
# Notes.: command executed when banning an IP. Take care that the
|
||||||
|
# command is executed with Fail2Ban user rights.
|
||||||
|
# Tags: <ip> IP address
|
||||||
|
# <failures> number of failures
|
||||||
|
# <time> unix timestamp of the ban time
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actionban = apf --deny <ip> "banned by Fail2Ban <name>"
|
||||||
|
|
||||||
|
# Option: actionunban
|
||||||
|
# Notes.: command executed when unbanning an IP. Take care that the
|
||||||
|
# command is executed with Fail2Ban user rights.
|
||||||
|
# Tags: <ip> IP address
|
||||||
|
# <failures> number of failures
|
||||||
|
# <time> unix timestamp of the ban time
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actionunban = apf --remove <ip>
|
|
@ -14,14 +14,14 @@
|
||||||
# Notes.: command executed once at the start of Fail2Ban.
|
# Notes.: command executed once at the start of Fail2Ban.
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstart = ipfw show | fgrep -q 'table(<table>)' || ( ipfw show | awk 'BEGIN { b = 1 } { if ($1 <= b) { b = $1 + 1 } else { e = b } } END { if (e) exit e <br> else exit b }'; num=$?; ipfw -q add $num deny <block> from table\(<table>\) to me <port>; echo $num > "<startstatefile>" )
|
actionstart = ipfw show | fgrep -q 'table(<table>)' || ( ipfw show | awk 'BEGIN { b = 1 } { if ($1 <= b) { b = $1 + 1 } else { e = b } } END { if (e) exit e <br> else exit b }'; num=$?; ipfw -q add $num <blocktype> <block> from table\(<table>\) to me <port>; echo $num > "<startstatefile>" )
|
||||||
|
|
||||||
|
|
||||||
# Option: actionstop
|
# Option: actionstop
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstop = [ -f <startstatefile> ] && ( read num < "<startstatefile>" <br> ipfw -q delete $num <br> rm "<startstatefile>" )
|
actionstop = [ ! -f <startstatefile> ] || ( read num < "<startstatefile>" <br> ipfw -q delete $num <br> rm "<startstatefile>" )
|
||||||
|
|
||||||
|
|
||||||
# Option: actioncheck
|
# Option: actioncheck
|
||||||
|
@ -68,15 +68,16 @@ port =
|
||||||
# Values: STRING
|
# Values: STRING
|
||||||
startstatefile = /var/run/fail2ban/ipfw-started-table_<table>
|
startstatefile = /var/run/fail2ban/ipfw-started-table_<table>
|
||||||
|
|
||||||
# Option: action
|
|
||||||
# Notes: This is the action to take for automaticly created rules. See the
|
|
||||||
# ACTION defination at the top of man ipfw for allowed values.
|
|
||||||
# "deny" and "unreach port" are probably the useful.
|
|
||||||
# Values: STRING
|
|
||||||
action = deny
|
|
||||||
|
|
||||||
# Option: block
|
# Option: block
|
||||||
# Notes: This is how much to block.
|
# Notes: This is how much to block.
|
||||||
# Can be "ip", "tcp", "udp" or various other options.
|
# Can be "ip", "tcp", "udp" or various other options.
|
||||||
# Values: STRING
|
# Values: STRING
|
||||||
block = ip
|
block = ip
|
||||||
|
|
||||||
|
# Option: blocktype
|
||||||
|
# Notes.: How to block the traffic. Use a action from man 5 ipfw
|
||||||
|
# Common values: deny, unreach port, reset
|
||||||
|
# ACTION defination at the top of man ipfw for allowed values.
|
||||||
|
# Values: STRING
|
||||||
|
#
|
||||||
|
blocktype = unreach port
|
||||||
|
|
|
@ -58,7 +58,7 @@ actioncheck =
|
||||||
actionban = ADDRESSES=`whois <ip> | perl -e 'while (<STDIN>) { next if /^changed|@(ripe|apnic)\.net/io; $m += (/abuse|trouble:|report|spam|security/io?3:0); if (/([a-z0-9_\-\.+]+@[a-z0-9\-]+(\.[[a-z0-9\-]+)+)/io) { while (s/([a-z0-9_\-\.+]+@[a-z0-9\-]+(\.[[a-z0-9\-]+)+)//io) { if ($m) { $a{lc($1)}=$m } else { $b{lc($1)}=$m } } $m=0 } else { $m && --$m } } if (%%a) {print join(",",keys(%%a))} else {print join(",",keys(%%b))}'`
|
actionban = ADDRESSES=`whois <ip> | perl -e 'while (<STDIN>) { next if /^changed|@(ripe|apnic)\.net/io; $m += (/abuse|trouble:|report|spam|security/io?3:0); if (/([a-z0-9_\-\.+]+@[a-z0-9\-]+(\.[[a-z0-9\-]+)+)/io) { while (s/([a-z0-9_\-\.+]+@[a-z0-9\-]+(\.[[a-z0-9\-]+)+)//io) { if ($m) { $a{lc($1)}=$m } else { $b{lc($1)}=$m } } $m=0 } else { $m && --$m } } if (%%a) {print join(",",keys(%%a))} else {print join(",",keys(%%b))}'`
|
||||||
IP=<ip>
|
IP=<ip>
|
||||||
if [ ! -z "$ADDRESSES" ]; then
|
if [ ! -z "$ADDRESSES" ]; then
|
||||||
(printf %%b "<message>\n"; date '+Note: Local timezone is %%z (%%Z)'; grep '<ip>' <logpath>) | <mailcmd> "Abuse from <ip>" $ADDRESSES <mailargs>
|
(printf %%b "<message>\n"; date '+Note: Local timezone is %%z (%%Z)'; grep '<ip>' <logpath>) | <mailcmd> "Abuse from <ip>" <mailargs> $ADDRESSES
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Option: actionunban
|
# Option: actionunban
|
||||||
|
@ -78,7 +78,7 @@ logpath = /dev/null
|
||||||
|
|
||||||
# Option: mailcmd
|
# Option: mailcmd
|
||||||
# Notes.: Your system mail command. Is passed 2 args: subject and recipient
|
# Notes.: Your system mail command. Is passed 2 args: subject and recipient
|
||||||
# Values: CMD Default: mail -s
|
# Values: CMD
|
||||||
#
|
#
|
||||||
mailcmd = mail -s
|
mailcmd = mail -s
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ mailcmd = mail -s
|
||||||
# Appear to come from a different address - the '--' indicates
|
# Appear to come from a different address - the '--' indicates
|
||||||
# arguments to be passed to Sendmail:
|
# arguments to be passed to Sendmail:
|
||||||
# -- -f me@example.com
|
# -- -f me@example.com
|
||||||
# Values: [ STRING ] Default: (empty)
|
# Values: [ STRING ]
|
||||||
#
|
#
|
||||||
mailargs =
|
mailargs =
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ actionstart =
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstop = if [ -f <tmpfile>.buffer ]; then
|
actionstop = if [ -f <tmpfile>.buffer ]; then
|
||||||
cat <tmpfile>.buffer | <mailcmd> "FORMAT DSHIELD USERID <userid> TZ `date +%%z | sed 's/\([+-]..\)\(..\)/\1:\2/'` Fail2Ban" <dest> <mailargs>
|
cat <tmpfile>.buffer | <mailcmd> "FORMAT DSHIELD USERID <userid> TZ `date +%%z | sed 's/\([+-]..\)\(..\)/\1:\2/'` Fail2Ban" <mailargs> <dest>
|
||||||
date +%%s > <tmpfile>.lastsent
|
date +%%s > <tmpfile>.lastsent
|
||||||
fi
|
fi
|
||||||
rm -f <tmpfile>.buffer <tmpfile>.first
|
rm -f <tmpfile>.buffer <tmpfile>.first
|
||||||
|
@ -80,7 +80,7 @@ actionban = TZONE=`date +%%z | sed 's/\([+-]..\)\(..\)/\1:\2/'`
|
||||||
LASTREPORT=$(($NOW - `cat <tmpfile>.lastsent`))
|
LASTREPORT=$(($NOW - `cat <tmpfile>.lastsent`))
|
||||||
LINES=$( wc -l <tmpfile>.buffer | awk '{ print $1 }' )
|
LINES=$( wc -l <tmpfile>.buffer | awk '{ print $1 }' )
|
||||||
if [ $LINES -ge <lines> && $LASTREPORT -gt <minreportinterval> ] || [ $LOGAGE -gt <maxbufferage> ]; then
|
if [ $LINES -ge <lines> && $LASTREPORT -gt <minreportinterval> ] || [ $LOGAGE -gt <maxbufferage> ]; then
|
||||||
cat <tmpfile>.buffer | <mailcmd> "FORMAT DSHIELD USERID <userid> TZ $TZONE Fail2Ban" <dest> <mailargs>
|
cat <tmpfile>.buffer | <mailcmd> "FORMAT DSHIELD USERID <userid> TZ $TZONE Fail2Ban" <mailargs> <dest>
|
||||||
rm -f <tmpfile>.buffer <tmpfile>.first
|
rm -f <tmpfile>.buffer <tmpfile>.first
|
||||||
echo $NOW > <tmpfile>.lastsent
|
echo $NOW > <tmpfile>.lastsent
|
||||||
fi
|
fi
|
||||||
|
@ -95,7 +95,7 @@ actionunban = if [ -f <tmpfile>.first ]; then
|
||||||
NOW=`date +%%s`
|
NOW=`date +%%s`
|
||||||
LOGAGE=$(($NOW - `cat <tmpfile>.first`))
|
LOGAGE=$(($NOW - `cat <tmpfile>.first`))
|
||||||
if [ $LOGAGE -gt <maxbufferage> ]; then
|
if [ $LOGAGE -gt <maxbufferage> ]; then
|
||||||
cat <tmpfile>.buffer | <mailcmd> "FORMAT DSHIELD USERID <userid> TZ `date +%%z | sed 's/\([+-]..\)\(..\)/\1:\2/'` Fail2Ban" <dest> <mailargs>
|
cat <tmpfile>.buffer | <mailcmd> "FORMAT DSHIELD USERID <userid> TZ `date +%%z | sed 's/\([+-]..\)\(..\)/\1:\2/'` Fail2Ban" <mailargs> <dest>
|
||||||
rm -f <tmpfile>.buffer <tmpfile>.first
|
rm -f <tmpfile>.buffer <tmpfile>.first
|
||||||
echo $NOW > <tmpfile>.lastsent
|
echo $NOW > <tmpfile>.lastsent
|
||||||
fi
|
fi
|
||||||
|
@ -106,7 +106,7 @@ actionunban = if [ -f <tmpfile>.first ]; then
|
||||||
# Option: port
|
# Option: port
|
||||||
# Notes.: The target port for the attack (numerical). MUST be provided in the
|
# Notes.: The target port for the attack (numerical). MUST be provided in the
|
||||||
# jail config, as it cannot be detected here.
|
# jail config, as it cannot be detected here.
|
||||||
# Values: [ NUM ] Default: ???
|
# Values: [ NUM ]
|
||||||
#
|
#
|
||||||
port = ???
|
port = ???
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ port = ???
|
||||||
# Notes.: Your DShield user ID. Should be provided either in the jail config or
|
# Notes.: Your DShield user ID. Should be provided either in the jail config or
|
||||||
# in a .local file.
|
# in a .local file.
|
||||||
# Register at https://secure.dshield.org/register.html
|
# Register at https://secure.dshield.org/register.html
|
||||||
# Values: [ NUM ] Default: 0
|
# Values: [ NUM ]
|
||||||
#
|
#
|
||||||
userid = 0
|
userid = 0
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ protocol = tcp
|
||||||
# Notes.: How many lines to buffer before making a report. Regardless of this,
|
# Notes.: How many lines to buffer before making a report. Regardless of this,
|
||||||
# reports are sent a minimum of <minreportinterval> apart, or if the
|
# reports are sent a minimum of <minreportinterval> apart, or if the
|
||||||
# buffer contains an event over <maxbufferage> old, or on shutdown
|
# buffer contains an event over <maxbufferage> old, or on shutdown
|
||||||
# Values: [ NUM ] Default: 50
|
# Values: [ NUM ]
|
||||||
#
|
#
|
||||||
lines = 50
|
lines = 50
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ lines = 50
|
||||||
# Notes.: Minimum period (in seconds) that must elapse before we submit another
|
# Notes.: Minimum period (in seconds) that must elapse before we submit another
|
||||||
# batch of reports. DShield request a minimum of 1 hour (3600 secs)
|
# batch of reports. DShield request a minimum of 1 hour (3600 secs)
|
||||||
# between reports.
|
# between reports.
|
||||||
# Values: [ NUM ] Default: 3600
|
# Values: [ NUM ]
|
||||||
#
|
#
|
||||||
minreportinterval = 3600
|
minreportinterval = 3600
|
||||||
|
|
||||||
|
@ -154,27 +154,27 @@ minreportinterval = 3600
|
||||||
# submit the batch, even if we haven't reached <lines> yet. Note that
|
# submit the batch, even if we haven't reached <lines> yet. Note that
|
||||||
# this is only checked on each ban/unban, and that we always send
|
# this is only checked on each ban/unban, and that we always send
|
||||||
# anything in the buffer on shutdown. Must be greater than
|
# anything in the buffer on shutdown. Must be greater than
|
||||||
# Values: [ NUM ] Default: 21600 (6 hours)
|
# Values: [ NUM ]
|
||||||
#
|
#
|
||||||
maxbufferage = 21600
|
maxbufferage = 21600
|
||||||
|
|
||||||
# Option: srcport
|
# Option: srcport
|
||||||
# Notes.: The source port of the attack. You're unlikely to have this info, so
|
# Notes.: The source port of the attack. You're unlikely to have this info, so
|
||||||
# you can leave the default
|
# you can leave the default
|
||||||
# Values: [ NUM ] Default: ???
|
# Values: [ NUM ]
|
||||||
#
|
#
|
||||||
srcport = ???
|
srcport = ???
|
||||||
|
|
||||||
# Option: tcpflags
|
# Option: tcpflags
|
||||||
# Notes.: TCP flags on attack. You're unlikely to have this info, so you can
|
# Notes.: TCP flags on attack. You're unlikely to have this info, so you can
|
||||||
# leave empty
|
# leave empty
|
||||||
# Values: [ STRING ] Default: (empty)
|
# Values: [ STRING ]
|
||||||
#
|
#
|
||||||
tcpflags =
|
tcpflags =
|
||||||
|
|
||||||
# Option: mailcmd
|
# Option: mailcmd
|
||||||
# Notes.: Your system mail command. Is passed 2 args: subject and recipient
|
# Notes.: Your system mail command. Is passed 2 args: subject and recipient
|
||||||
# Values: CMD Default: mail -s
|
# Values: CMD
|
||||||
#
|
#
|
||||||
mailcmd = mail -s
|
mailcmd = mail -s
|
||||||
|
|
||||||
|
@ -186,19 +186,19 @@ mailcmd = mail -s
|
||||||
# the one configured at DShield - the '--' indicates arguments to be
|
# the one configured at DShield - the '--' indicates arguments to be
|
||||||
# passed to Sendmail):
|
# passed to Sendmail):
|
||||||
# -- -f me@example.com
|
# -- -f me@example.com
|
||||||
# Values: [ STRING ] Default: (empty)
|
# Values: [ STRING ]
|
||||||
#
|
#
|
||||||
mailargs =
|
mailargs =
|
||||||
|
|
||||||
# Option: dest
|
# Option: dest
|
||||||
# Notes.: Destination e-mail address for reports
|
# Notes.: Destination e-mail address for reports
|
||||||
# Values: [ STRING ] Default: reports@dshield.org
|
# Values: [ STRING ]
|
||||||
#
|
#
|
||||||
dest = reports@dshield.org
|
dest = reports@dshield.org
|
||||||
|
|
||||||
# Option: tmpfile
|
# Option: tmpfile
|
||||||
# Notes.: Base name of temporary files used for buffering
|
# Notes.: Base name of temporary files used for buffering
|
||||||
# Values: [ STRING ] Default: /var/run/fail2ban/tmp-dshield
|
# Values: [ STRING ]
|
||||||
#
|
#
|
||||||
tmpfile = /var/run/fail2ban/tmp-dshield
|
tmpfile = /var/run/fail2ban/tmp-dshield
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,14 @@
|
||||||
# Notes.: command executed once at the start of Fail2Ban.
|
# Notes.: command executed once at the start of Fail2Ban.
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstart = touch /tmp/fail2ban.dummy
|
actionstart = touch /var/run/fail2ban/fail2ban.dummy
|
||||||
printf %%b "<init>\n" >> /tmp/fail2ban.dummy
|
printf %%b "<init>\n" >> /var/run/fail2ban/fail2ban.dummy
|
||||||
|
|
||||||
# Option: actionstop
|
# Option: actionstop
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstop = rm -f /tmp/fail2ban.dummy
|
actionstop = rm -f /var/run/fail2ban/fail2ban.dummy
|
||||||
|
|
||||||
# Option: actioncheck
|
# Option: actioncheck
|
||||||
# Notes.: command executed once before each actionban command
|
# Notes.: command executed once before each actionban command
|
||||||
|
@ -31,7 +31,7 @@ actioncheck =
|
||||||
# Tags: See jail.conf(5) man page
|
# Tags: See jail.conf(5) man page
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionban = printf %%b "+<ip>\n" >> /tmp/fail2ban.dummy
|
actionban = printf %%b "+<ip>\n" >> /var/run/fail2ban/fail2ban.dummy
|
||||||
|
|
||||||
# Option: actionunban
|
# Option: actionunban
|
||||||
# Notes.: command executed when unbanning an IP. Take care that the
|
# Notes.: command executed when unbanning an IP. Take care that the
|
||||||
|
@ -39,7 +39,7 @@ actionban = printf %%b "+<ip>\n" >> /tmp/fail2ban.dummy
|
||||||
# Tags: See jail.conf(5) man page
|
# Tags: See jail.conf(5) man page
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionunban = printf %%b "-<ip>\n" >> /tmp/fail2ban.dummy
|
actionunban = printf %%b "-<ip>\n" >> /var/run/fail2ban/fail2ban.dummy
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
# Fail2Ban configuration file
|
||||||
|
#
|
||||||
|
# Author: Edgar Hoch
|
||||||
|
# Copied from iptables-new.conf and modified for use with firewalld by Edgar Hoch.
|
||||||
|
# It uses "firewall-cmd" instead of "iptables".
|
||||||
|
#
|
||||||
|
# Because of the --remove-rules in stop this action requires firewalld-0.3.8+
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = iptables-blocktype.conf
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
actionstart = firewall-cmd --direct --add-chain ipv4 filter fail2ban-<name>
|
||||||
|
firewall-cmd --direct --add-rule ipv4 filter fail2ban-<name> 1000 -j RETURN
|
||||||
|
firewall-cmd --direct --add-rule ipv4 filter <chain> 0 -m state --state NEW -p <protocol> --dport <port> -j fail2ban-<name>
|
||||||
|
|
||||||
|
actionstop = firewall-cmd --direct --remove-rule ipv4 filter <chain> 0 -m state --state NEW -p <protocol> --dport <port> -j fail2ban-<name>
|
||||||
|
firewall-cmd --direct --remove-rules ipv4 filter fail2ban-<name>
|
||||||
|
firewall-cmd --direct --remove-chain ipv4 filter fail2ban-<name>
|
||||||
|
|
||||||
|
actioncheck = firewall-cmd --direct --get-chains ipv4 filter | grep -q 'fail2ban-<name>[ \t]'
|
||||||
|
|
||||||
|
actionban = firewall-cmd --direct --add-rule ipv4 filter fail2ban-<name> 0 -s <ip> -j <blocktype>
|
||||||
|
|
||||||
|
actionunban = firewall-cmd --direct --remove-rule ipv4 filter fail2ban-<name> 0 -s <ip> -j <blocktype>
|
||||||
|
|
||||||
|
[Init]
|
||||||
|
|
||||||
|
# Default name of the chain
|
||||||
|
#
|
||||||
|
name = default
|
||||||
|
|
||||||
|
# Option: port
|
||||||
|
# Notes.: specifies port to monitor
|
||||||
|
# Values: [ NUM | STRING ]
|
||||||
|
#
|
||||||
|
port = ssh
|
||||||
|
|
||||||
|
# Option: protocol
|
||||||
|
# Notes.: internally used by config reader for interpolations.
|
||||||
|
# Values: [ tcp | udp | icmp | all ]
|
||||||
|
#
|
||||||
|
protocol = tcp
|
||||||
|
|
||||||
|
# Option: chain
|
||||||
|
# Notes specifies the iptables chain to which the fail2ban rules should be
|
||||||
|
# added
|
||||||
|
# Values: [ STRING ]
|
||||||
|
#
|
||||||
|
chain = INPUT_direct
|
|
@ -1,6 +1,7 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban configuration file
|
||||||
#
|
#
|
||||||
# Author: Cyril Jaquier
|
# Author: Cyril Jaquier
|
||||||
|
# Edited for cross platform by: James Stout, Yaroslav Halchenko and Daniel Black
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ actioncheck =
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionban = IP=<ip> &&
|
actionban = IP=<ip> &&
|
||||||
printf %%b "ALL: $IP\n" >> <file>
|
printf %%b "<daemon_list>: $IP\n" >> <file>
|
||||||
|
|
||||||
# Option: actionunban
|
# Option: actionunban
|
||||||
# Notes.: command executed when unbanning an IP. Take care that the
|
# Notes.: command executed when unbanning an IP. Take care that the
|
||||||
|
@ -39,7 +40,7 @@ actionban = IP=<ip> &&
|
||||||
# Tags: See jail.conf(5) man page
|
# Tags: See jail.conf(5) man page
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionunban = IP=<ip> && sed /ALL:\ $IP/d <file> > <file>.new && mv <file>.new <file>
|
actionunban = echo "/^<daemon_list>: <ip>$/<br>d<br>w<br>q" | ed <file>
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
|
|
||||||
|
@ -48,3 +49,9 @@ actionunban = IP=<ip> && sed /ALL:\ $IP/d <file> > <file>.new && mv <file>.new
|
||||||
# Values: STR Default: /etc/hosts.deny
|
# Values: STR Default: /etc/hosts.deny
|
||||||
#
|
#
|
||||||
file = /etc/hosts.deny
|
file = /etc/hosts.deny
|
||||||
|
|
||||||
|
# Option: daemon_list
|
||||||
|
# Notes: The list of services that this action will deny. See the man page
|
||||||
|
# for hosts.deny/hosts_access. Default is all services.
|
||||||
|
# Values: STR Default: ALL
|
||||||
|
daemon_list = ALL
|
||||||
|
|
|
@ -11,12 +11,11 @@
|
||||||
# IPset was a feature introduced in the linux kernel 2.6.39 and 3.0.0 kernels.
|
# IPset was a feature introduced in the linux kernel 2.6.39 and 3.0.0 kernels.
|
||||||
#
|
#
|
||||||
# If you are running on an older kernel you make need to patch in external
|
# If you are running on an older kernel you make need to patch in external
|
||||||
# modules.
|
# modules. Debian squeeze can do this with:
|
||||||
|
# apt-get install xtables-addons-source
|
||||||
|
# module-assistant auto-install xtables-addons
|
||||||
#
|
#
|
||||||
# On Debian machines this can be done with:
|
# Debian wheezy and above uses protocol 6
|
||||||
#
|
|
||||||
# apt-get install ipset xtables-addons-source
|
|
||||||
# module-assistant auto-install xtables-addons
|
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
# Fail2Ban configuration file
|
||||||
|
#
|
||||||
|
# Author: Daniel Black
|
||||||
|
#
|
||||||
|
# This is for ipset protocol 6 (and hopefully later) (ipset v6.14).
|
||||||
|
# Use ipset -V to see the protocol and version. Version 4 should use
|
||||||
|
# iptables-ipset-proto4.conf.
|
||||||
|
#
|
||||||
|
# This requires the program ipset which is normally in package called ipset.
|
||||||
|
#
|
||||||
|
# IPset was a feature introduced in the linux kernel 2.6.39 and 3.0.0 kernels.
|
||||||
|
#
|
||||||
|
# If you are running on an older kernel you make need to patch in external
|
||||||
|
# modules which probably won't be protocol version 6.
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = iptables-blocktype.conf
|
||||||
|
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
# Option: actionstart
|
||||||
|
# Notes.: command executed once at the start of Fail2Ban.
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actionstart = ipset create fail2ban-<name> hash:ip timeout <bantime>
|
||||||
|
iptables -I INPUT -m set --match-set fail2ban-<name> src -j <blocktype>
|
||||||
|
|
||||||
|
# Option: actionstop
|
||||||
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actionstop = iptables -D INPUT -m set --match-set fail2ban-<name> src -j <blocktype>
|
||||||
|
ipset flush fail2ban-<name>
|
||||||
|
ipset destroy fail2ban-<name>
|
||||||
|
|
||||||
|
# Option: actionban
|
||||||
|
# Notes.: command executed when banning an IP. Take care that the
|
||||||
|
# command is executed with Fail2Ban user rights.
|
||||||
|
# Tags: See jail.conf(5) man page
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actionban = ipset add fail2ban-<name> <ip> timeout <bantime> -exist
|
||||||
|
|
||||||
|
# Option: actionunban
|
||||||
|
# Notes.: command executed when unbanning an IP. Take care that the
|
||||||
|
# command is executed with Fail2Ban user rights.
|
||||||
|
# Tags: See jail.conf(5) man page
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actionunban = ipset del fail2ban-<name> <ip> -exist
|
||||||
|
|
||||||
|
[Init]
|
||||||
|
|
||||||
|
# Default name of the ipset
|
||||||
|
#
|
||||||
|
name = default
|
||||||
|
|
||||||
|
# Option: bantime
|
||||||
|
# Notes: specifies the bantime in seconds (handled internally rather than by fail2ban)
|
||||||
|
# Values: [ NUM ] Default: 600
|
||||||
|
|
||||||
|
bantime = 600
|
|
@ -12,11 +12,6 @@
|
||||||
#
|
#
|
||||||
# If you are running on an older kernel you make need to patch in external
|
# If you are running on an older kernel you make need to patch in external
|
||||||
# modules.
|
# modules.
|
||||||
#
|
|
||||||
# On Debian machines this can be done with:
|
|
||||||
#
|
|
||||||
# apt-get install ipset xtables-addons-source
|
|
||||||
# module-assistant auto-install xtables-addons
|
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
|
@ -30,13 +25,13 @@ before = iptables-blocktype.conf
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstart = ipset create fail2ban-<name> hash:ip timeout <bantime>
|
actionstart = ipset create fail2ban-<name> hash:ip timeout <bantime>
|
||||||
iptables -I INPUT -p <protocol> -m multiport --dports <port> -m set --match-set fail2ban-<name> src -j DROP
|
iptables -I INPUT -p <protocol> -m multiport --dports <port> -m set --match-set fail2ban-<name> src -j <blocktype>
|
||||||
|
|
||||||
# Option: actionstop
|
# Option: actionstop
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstop = iptables -D INPUT -p <protocol> -m multiport --dports <port> -m set --match-set fail2ban-<name> src -j DROP
|
actionstop = iptables -D INPUT -p <protocol> -m multiport --dports <port> -m set --match-set fail2ban-<name> src -j <blocktype>
|
||||||
ipset flush fail2ban-<name>
|
ipset flush fail2ban-<name>
|
||||||
ipset destroy fail2ban-<name>
|
ipset destroy fail2ban-<name>
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ actionstart = printf %%b "Hi,\n
|
||||||
The jail <name> has been started successfully.\n
|
The jail <name> has been started successfully.\n
|
||||||
Output will be buffered until <lines> lines are available.\n
|
Output will be buffered until <lines> lines are available.\n
|
||||||
Regards,\n
|
Regards,\n
|
||||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: started" <dest>
|
Fail2Ban"|mail -s "[Fail2Ban] <name>: started on `uname -n`" <dest>
|
||||||
|
|
||||||
# Option: actionstop
|
# Option: actionstop
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
|
@ -25,13 +25,13 @@ actionstop = if [ -f <tmpfile> ]; then
|
||||||
These hosts have been banned by Fail2Ban.\n
|
These hosts have been banned by Fail2Ban.\n
|
||||||
`cat <tmpfile>`
|
`cat <tmpfile>`
|
||||||
Regards,\n
|
Regards,\n
|
||||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: Summary" <dest>
|
Fail2Ban"|mail -s "[Fail2Ban] <name>: Summary from `uname -n`" <dest>
|
||||||
rm <tmpfile>
|
rm <tmpfile>
|
||||||
fi
|
fi
|
||||||
printf %%b "Hi,\n
|
printf %%b "Hi,\n
|
||||||
The jail <name> has been stopped.\n
|
The jail <name> has been stopped.\n
|
||||||
Regards,\n
|
Regards,\n
|
||||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped" <dest>
|
Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on `uname -n`" <dest>
|
||||||
|
|
||||||
# Option: actioncheck
|
# Option: actioncheck
|
||||||
# Notes.: command executed once before each actionban command
|
# Notes.: command executed once before each actionban command
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
actionstart = printf %%b "Hi,\n
|
actionstart = printf %%b "Hi,\n
|
||||||
The jail <name> has been started successfully.\n
|
The jail <name> has been started successfully.\n
|
||||||
Regards,\n
|
Regards,\n
|
||||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: started" <dest>
|
Fail2Ban"|mail -s "[Fail2Ban] <name>: started on `uname -n`" <dest>
|
||||||
|
|
||||||
# Option: actionstop
|
# Option: actionstop
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
|
@ -22,7 +22,7 @@ actionstart = printf %%b "Hi,\n
|
||||||
actionstop = printf %%b "Hi,\n
|
actionstop = printf %%b "Hi,\n
|
||||||
The jail <name> has been stopped.\n
|
The jail <name> has been stopped.\n
|
||||||
Regards,\n
|
Regards,\n
|
||||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped" <dest>
|
Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on `uname -n`" <dest>
|
||||||
|
|
||||||
# Option: actioncheck
|
# Option: actioncheck
|
||||||
# Notes.: command executed once before each actionban command
|
# Notes.: command executed once before each actionban command
|
||||||
|
@ -44,7 +44,7 @@ actionban = printf %%b "Hi,\n
|
||||||
Lines containing IP:<ip> in <logpath>\n
|
Lines containing IP:<ip> in <logpath>\n
|
||||||
`grep '\<<ip>\>' <logpath>`\n\n
|
`grep '\<<ip>\>' <logpath>`\n\n
|
||||||
Regards,\n
|
Regards,\n
|
||||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip>" <dest>
|
Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip> from `uname -n`" <dest>
|
||||||
|
|
||||||
# Option: actionunban
|
# Option: actionunban
|
||||||
# Notes.: command executed when unbanning an IP. Take care that the
|
# Notes.: command executed when unbanning an IP. Take care that the
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
actionstart = printf %%b "Hi,\n
|
actionstart = printf %%b "Hi,\n
|
||||||
The jail <name> has been started successfully.\n
|
The jail <name> has been started successfully.\n
|
||||||
Regards,\n
|
Regards,\n
|
||||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: started" <dest>
|
Fail2Ban"|mail -s "[Fail2Ban] <name>: started on `uname -n`" <dest>
|
||||||
|
|
||||||
# Option: actionstop
|
# Option: actionstop
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
|
@ -22,7 +22,7 @@ actionstart = printf %%b "Hi,\n
|
||||||
actionstop = printf %%b "Hi,\n
|
actionstop = printf %%b "Hi,\n
|
||||||
The jail <name> has been stopped.\n
|
The jail <name> has been stopped.\n
|
||||||
Regards,\n
|
Regards,\n
|
||||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped" <dest>
|
Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on `uname -n`" <dest>
|
||||||
|
|
||||||
# Option: actioncheck
|
# Option: actioncheck
|
||||||
# Notes.: command executed once before each actionban command
|
# Notes.: command executed once before each actionban command
|
||||||
|
@ -42,7 +42,7 @@ actionban = printf %%b "Hi,\n
|
||||||
Here are more information about <ip>:\n
|
Here are more information about <ip>:\n
|
||||||
`whois <ip>`\n
|
`whois <ip>`\n
|
||||||
Regards,\n
|
Regards,\n
|
||||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip>" <dest>
|
Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip> from `uname -n`" <dest>
|
||||||
|
|
||||||
# Option: actionunban
|
# Option: actionunban
|
||||||
# Notes.: command executed when unbanning an IP. Take care that the
|
# Notes.: command executed when unbanning an IP. Take care that the
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
actionstart = printf %%b "Hi,\n
|
actionstart = printf %%b "Hi,\n
|
||||||
The jail <name> has been started successfully.\n
|
The jail <name> has been started successfully.\n
|
||||||
Regards,\n
|
Regards,\n
|
||||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: started" <dest>
|
Fail2Ban"|mail -s "[Fail2Ban] <name>: started on `uname -n`" <dest>
|
||||||
|
|
||||||
# Option: actionstop
|
# Option: actionstop
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
|
@ -22,7 +22,7 @@ actionstart = printf %%b "Hi,\n
|
||||||
actionstop = printf %%b "Hi,\n
|
actionstop = printf %%b "Hi,\n
|
||||||
The jail <name> has been stopped.\n
|
The jail <name> has been stopped.\n
|
||||||
Regards,\n
|
Regards,\n
|
||||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped" <dest>
|
Fail2Ban"|mail -s "[Fail2Ban] <name>: stopped on `uname -n`" <dest>
|
||||||
|
|
||||||
# Option: actioncheck
|
# Option: actioncheck
|
||||||
# Notes.: command executed once before each actionban command
|
# Notes.: command executed once before each actionban command
|
||||||
|
@ -40,7 +40,7 @@ actionban = printf %%b "Hi,\n
|
||||||
The IP <ip> has just been banned by Fail2Ban after
|
The IP <ip> has just been banned by Fail2Ban after
|
||||||
<failures> attempts against <name>.\n
|
<failures> attempts against <name>.\n
|
||||||
Regards,\n
|
Regards,\n
|
||||||
Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip>" <dest>
|
Fail2Ban"|mail -s "[Fail2Ban] <name>: banned <ip> from `uname -n`" <dest>
|
||||||
|
|
||||||
# Option: actionunban
|
# Option: actionunban
|
||||||
# Notes.: command executed when unbanning an IP. Take care that the
|
# Notes.: command executed when unbanning an IP. Take care that the
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Fail2Ban configuration file for using afctl on Mac OS X Server 10.5
|
||||||
|
#
|
||||||
|
# Anonymous author
|
||||||
|
# http://www.fail2ban.org/wiki/index.php?title=HOWTO_Mac_OS_X_Server_(10.5)&diff=prev&oldid=4081
|
||||||
|
#
|
||||||
|
# Ref: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man8/afctl.8.html
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
actionstart =
|
||||||
|
actionstop =
|
||||||
|
actioncheck =
|
||||||
|
actionban = /usr/libexec/afctl -a <ip> -t <bantime>
|
||||||
|
actionunban = /usr/libexec/afctl -r <ip>
|
||||||
|
|
||||||
|
[Init]
|
||||||
|
bantime = 2880
|
|
@ -0,0 +1,87 @@
|
||||||
|
# Fail2Ban configuration file
|
||||||
|
#
|
||||||
|
# Author: Nick Munger
|
||||||
|
# Modified by: Andy Fragen and Daniel Black
|
||||||
|
#
|
||||||
|
# Mod for OS X, using random rulenum as OSX ipfw doesn't include tables
|
||||||
|
#
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
# Option: actionstart
|
||||||
|
# Notes.: command executed once at the start of Fail2Ban.
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actionstart =
|
||||||
|
|
||||||
|
|
||||||
|
# Option: actionstop
|
||||||
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actionstop =
|
||||||
|
|
||||||
|
|
||||||
|
# Option: actioncheck
|
||||||
|
# Notes.: command executed once before each actionban command
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actioncheck =
|
||||||
|
|
||||||
|
|
||||||
|
# Option: actionban
|
||||||
|
# Notes.: command executed when banning an IP. Take care that the
|
||||||
|
# command is executed with Fail2Ban user rights.
|
||||||
|
# Tags: <ip> IP address
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actionban = ipfw add <rulenum> set <setnum> <blocktype> log <block> from <ip> to <dst> <port>
|
||||||
|
|
||||||
|
|
||||||
|
# Option: actionunban
|
||||||
|
# Notes.: command executed when unbanning an IP. Take care that the
|
||||||
|
# command is executed with Fail2Ban user rights.
|
||||||
|
# Tags: <ip> IP address
|
||||||
|
# Values: CMD
|
||||||
|
#
|
||||||
|
actionunban = ipfw delete `ipfw -S list | grep -i 'set <setnum> <blocktype> log <block> from <ip> to <dst>' | awk '{print $1;}'`
|
||||||
|
|
||||||
|
[Init]
|
||||||
|
|
||||||
|
# Option: port
|
||||||
|
# Notes.: specifies port to block. Can be blank however may require block="ip"
|
||||||
|
# Values: [ NUM | STRING ]
|
||||||
|
#
|
||||||
|
port = ssh
|
||||||
|
|
||||||
|
# Option: dst
|
||||||
|
# Notes.: the local IP address of the network interface
|
||||||
|
# Values: IP, any, me or anything support by ipfw as a dst
|
||||||
|
#
|
||||||
|
dst = me
|
||||||
|
|
||||||
|
# Option: block
|
||||||
|
# Notes: This is how much to block.
|
||||||
|
# Can be "ip", "tcp", "udp" or various other options.
|
||||||
|
# Values: STRING
|
||||||
|
block = tcp
|
||||||
|
|
||||||
|
# Option: blocktype
|
||||||
|
# Notes.: How to block the traffic. Use a action from man 8 ipfw
|
||||||
|
# Common values: deny, unreach port, reset
|
||||||
|
# Values: STRING
|
||||||
|
#
|
||||||
|
blocktype = unreach port
|
||||||
|
|
||||||
|
# Option: set number
|
||||||
|
# Notes.: The ipset number this is added to.
|
||||||
|
# Values: 0-31
|
||||||
|
setnum = 10
|
||||||
|
|
||||||
|
# Option: number for ipfw rule
|
||||||
|
# Notes: This is meant to be automaticly generated and not overwritten
|
||||||
|
# Values: Random value between 10000 and 12000
|
||||||
|
rulenum="`echo $((RANDOM%%2000+10000))`"
|
||||||
|
|
||||||
|
# Duplicate prevention mechanism
|
||||||
|
#rulenum = "`a=$((RANDOM%%2000+10000)); while ipfw show | grep -q ^$a\ ; do a=$((RANDOM%%2000+10000)); done; echo $a`"
|
|
@ -56,7 +56,7 @@ actionunban = /sbin/pfctl -t <tablename> -T delete <ip>/32
|
||||||
[Init]
|
[Init]
|
||||||
# Option: tablename
|
# Option: tablename
|
||||||
# Notes.: The pf table name.
|
# Notes.: The pf table name.
|
||||||
# Values: [ STRING ] Default: fail2ban
|
# Values: [ STRING ]
|
||||||
#
|
#
|
||||||
tablename = fail2ban
|
tablename = fail2ban
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,18 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = sendmail-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: actionstart
|
# Option: actionstart
|
||||||
# Notes.: command executed once at the start of Fail2Ban.
|
# Notes.: command executed once at the start of Fail2Ban.
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
actionstart = printf %%b "Subject: [Fail2Ban] <name>: started on `uname -n`
|
||||||
From: Fail2Ban <<sender>>
|
From: <sendername> <<sender>>
|
||||||
To: <dest>\n
|
To: <dest>\n
|
||||||
Hi,\n
|
Hi,\n
|
||||||
The jail <name> has been started successfully.\n
|
The jail <name> has been started successfully.\n
|
||||||
|
@ -24,8 +28,8 @@ actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstop = if [ -f <tmpfile> ]; then
|
actionstop = if [ -f <tmpfile> ]; then
|
||||||
printf %%b "Subject: [Fail2Ban] <name>: summary
|
printf %%b "Subject: [Fail2Ban] <name>: summary from `uname -n`
|
||||||
From: Fail2Ban <<sender>>
|
From: <sendername> <<sender>>
|
||||||
To: <dest>\n
|
To: <dest>\n
|
||||||
Hi,\n
|
Hi,\n
|
||||||
These hosts have been banned by Fail2Ban.\n
|
These hosts have been banned by Fail2Ban.\n
|
||||||
|
@ -34,7 +38,7 @@ actionstop = if [ -f <tmpfile> ]; then
|
||||||
Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest>
|
Fail2Ban" | /usr/sbin/sendmail -f <sender> <dest>
|
||||||
rm <tmpfile>
|
rm <tmpfile>
|
||||||
fi
|
fi
|
||||||
printf %%b "Subject: [Fail2Ban] <name>: stopped
|
printf %%b "Subject: [Fail2Ban] <name>: stopped on `uname -n`
|
||||||
From: Fail2Ban <<sender>>
|
From: Fail2Ban <<sender>>
|
||||||
To: <dest>\n
|
To: <dest>\n
|
||||||
Hi,\n
|
Hi,\n
|
||||||
|
@ -57,8 +61,8 @@ actioncheck =
|
||||||
actionban = printf %%b "`date`: <ip> (<failures> failures)\n" >> <tmpfile>
|
actionban = printf %%b "`date`: <ip> (<failures> failures)\n" >> <tmpfile>
|
||||||
LINE=$( wc -l <tmpfile> | awk '{ print $1 }' )
|
LINE=$( wc -l <tmpfile> | awk '{ print $1 }' )
|
||||||
if [ $LINE -ge <lines> ]; then
|
if [ $LINE -ge <lines> ]; then
|
||||||
printf %%b "Subject: [Fail2Ban] <name>: summary
|
printf %%b "Subject: [Fail2Ban] <name>: summary from `uname -n`
|
||||||
From: Fail2Ban <<sender>>
|
From: <sendername> <<sender>>
|
||||||
To: <dest>\n
|
To: <dest>\n
|
||||||
Hi,\n
|
Hi,\n
|
||||||
These hosts have been banned by Fail2Ban.\n
|
These hosts have been banned by Fail2Ban.\n
|
||||||
|
@ -82,14 +86,6 @@ actionunban =
|
||||||
#
|
#
|
||||||
name = default
|
name = default
|
||||||
|
|
||||||
# Destination/Addressee of the mail
|
|
||||||
#
|
|
||||||
dest = root
|
|
||||||
|
|
||||||
# Sender of the mail
|
|
||||||
#
|
|
||||||
sender = fail2ban
|
|
||||||
|
|
||||||
# Default number of lines that are buffered
|
# Default number of lines that are buffered
|
||||||
#
|
#
|
||||||
lines = 5
|
lines = 5
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Fail2Ban configuration file
|
||||||
|
#
|
||||||
|
# Common settings for sendmail actions
|
||||||
|
#
|
||||||
|
# Users can override the defaults in sendmail-common.local
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
after = sendmail-common.local
|
||||||
|
|
||||||
|
[Init]
|
||||||
|
|
||||||
|
# Recipient mail address
|
||||||
|
#
|
||||||
|
dest = root
|
||||||
|
|
||||||
|
# Sender mail address
|
||||||
|
#
|
||||||
|
sender = fail2ban
|
||||||
|
|
||||||
|
# Sender display name
|
||||||
|
#
|
||||||
|
sendername = Fail2Ban
|
|
@ -4,15 +4,19 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = sendmail-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: actionstart
|
# Option: actionstart
|
||||||
# Notes.: command executed once at the start of Fail2Ban.
|
# Notes.: command executed once at the start of Fail2Ban.
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
actionstart = printf %%b "Subject: [Fail2Ban] <name>: started on `uname -n`
|
||||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||||
From: Fail2Ban <<sender>>
|
From: <sendername> <<sender>>
|
||||||
To: <dest>\n
|
To: <dest>\n
|
||||||
Hi,\n
|
Hi,\n
|
||||||
The jail <name> has been started successfully.\n
|
The jail <name> has been started successfully.\n
|
||||||
|
@ -23,9 +27,9 @@ actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstop = printf %%b "Subject: [Fail2Ban] <name>: stopped
|
actionstop = printf %%b "Subject: [Fail2Ban] <name>: stopped on `uname -n`
|
||||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||||
From: Fail2Ban <<sender>>
|
From: <sendername> <<sender>>
|
||||||
To: <dest>\n
|
To: <dest>\n
|
||||||
Hi,\n
|
Hi,\n
|
||||||
The jail <name> has been stopped.\n
|
The jail <name> has been stopped.\n
|
||||||
|
@ -44,9 +48,9 @@ actioncheck =
|
||||||
# Tags: See jail.conf(5) man page
|
# Tags: See jail.conf(5) man page
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip>
|
actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from `uname -n`
|
||||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||||
From: Fail2Ban <<sender>>
|
From: <sendername> <<sender>>
|
||||||
To: <dest>\n
|
To: <dest>\n
|
||||||
Hi,\n
|
Hi,\n
|
||||||
The IP <ip> has just been banned by Fail2Ban after
|
The IP <ip> has just been banned by Fail2Ban after
|
||||||
|
@ -72,14 +76,6 @@ actionunban =
|
||||||
#
|
#
|
||||||
name = default
|
name = default
|
||||||
|
|
||||||
# Destination/Addressee of the mail
|
|
||||||
#
|
|
||||||
dest = root
|
|
||||||
|
|
||||||
# Sender of the mail
|
|
||||||
#
|
|
||||||
sender = fail2ban
|
|
||||||
|
|
||||||
# Path to the log files which contain relevant lines for the abuser IP
|
# Path to the log files which contain relevant lines for the abuser IP
|
||||||
#
|
#
|
||||||
logpath = /dev/null
|
logpath = /dev/null
|
||||||
|
|
|
@ -4,15 +4,19 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = sendmail-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: actionstart
|
# Option: actionstart
|
||||||
# Notes.: command executed once at the start of Fail2Ban.
|
# Notes.: command executed once at the start of Fail2Ban.
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
actionstart = printf %%b "Subject: [Fail2Ban] <name>: started on `uname -n`
|
||||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||||
From: Fail2Ban <<sender>>
|
From: <sendername> <<sender>>
|
||||||
To: <dest>\n
|
To: <dest>\n
|
||||||
Hi,\n
|
Hi,\n
|
||||||
The jail <name> has been started successfully.\n
|
The jail <name> has been started successfully.\n
|
||||||
|
@ -23,9 +27,9 @@ actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstop = printf %%b "Subject: [Fail2Ban] <name>: stopped
|
actionstop = printf %%b "Subject: [Fail2Ban] <name>: stopped on `uname -n`
|
||||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||||
From: Fail2Ban <<sender>>
|
From: <sendername> <<sender>>
|
||||||
To: <dest>\n
|
To: <dest>\n
|
||||||
Hi,\n
|
Hi,\n
|
||||||
The jail <name> has been stopped.\n
|
The jail <name> has been stopped.\n
|
||||||
|
@ -44,9 +48,9 @@ actioncheck =
|
||||||
# Tags: See jail.conf(5) man page
|
# Tags: See jail.conf(5) man page
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip>
|
actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from `uname -n`
|
||||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||||
From: Fail2Ban <<sender>>
|
From: <sendername> <<sender>>
|
||||||
To: <dest>\n
|
To: <dest>\n
|
||||||
Hi,\n
|
Hi,\n
|
||||||
The IP <ip> has just been banned by Fail2Ban after
|
The IP <ip> has just been banned by Fail2Ban after
|
||||||
|
@ -70,11 +74,3 @@ actionunban =
|
||||||
#
|
#
|
||||||
name = default
|
name = default
|
||||||
|
|
||||||
# Destination/Addressee of the mail
|
|
||||||
#
|
|
||||||
dest = root
|
|
||||||
|
|
||||||
# Sender of the mail
|
|
||||||
#
|
|
||||||
sender = fail2ban
|
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,19 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = sendmail-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: actionstart
|
# Option: actionstart
|
||||||
# Notes.: command executed once at the start of Fail2Ban.
|
# Notes.: command executed once at the start of Fail2Ban.
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
actionstart = printf %%b "Subject: [Fail2Ban] <name>: started on `uname -n`
|
||||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||||
From: Fail2Ban <<sender>>
|
From: <sendername> <<sender>>
|
||||||
To: <dest>\n
|
To: <dest>\n
|
||||||
Hi,\n
|
Hi,\n
|
||||||
The jail <name> has been started successfully.\n
|
The jail <name> has been started successfully.\n
|
||||||
|
@ -23,9 +27,9 @@ actionstart = printf %%b "Subject: [Fail2Ban] <name>: started
|
||||||
# Notes.: command executed once at the end of Fail2Ban
|
# Notes.: command executed once at the end of Fail2Ban
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionstop = printf %%b "Subject: [Fail2Ban] <name>: stopped
|
actionstop = printf %%b "Subject: [Fail2Ban] <name>: stopped on `uname -n`
|
||||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||||
From: Fail2Ban <<sender>>
|
From: <sendername> <<sender>>
|
||||||
To: <dest>\n
|
To: <dest>\n
|
||||||
Hi,\n
|
Hi,\n
|
||||||
The jail <name> has been stopped.\n
|
The jail <name> has been stopped.\n
|
||||||
|
@ -44,9 +48,9 @@ actioncheck =
|
||||||
# Tags: See jail.conf(5) man page
|
# Tags: See jail.conf(5) man page
|
||||||
# Values: CMD
|
# Values: CMD
|
||||||
#
|
#
|
||||||
actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip>
|
actionban = printf %%b "Subject: [Fail2Ban] <name>: banned <ip> from `uname -n`
|
||||||
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
Date: `LC_TIME=C date -u +"%%a, %%d %%h %%Y %%T +0000"`
|
||||||
From: Fail2Ban <<sender>>
|
From: <sendername> <<sender>>
|
||||||
To: <dest>\n
|
To: <dest>\n
|
||||||
Hi,\n
|
Hi,\n
|
||||||
The IP <ip> has just been banned by Fail2Ban after
|
The IP <ip> has just been banned by Fail2Ban after
|
||||||
|
@ -68,11 +72,3 @@ actionunban =
|
||||||
#
|
#
|
||||||
name = default
|
name = default
|
||||||
|
|
||||||
# Destination/Addressee of the mail
|
|
||||||
#
|
|
||||||
dest = root
|
|
||||||
|
|
||||||
# Sender of the mail
|
|
||||||
#
|
|
||||||
sender = fail2ban
|
|
||||||
|
|
||||||
|
|
|
@ -11,24 +11,24 @@
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: loglevel
|
# Option: loglevel
|
||||||
# Notes.: Set the log level output.
|
# Notes.: Set the log level output.
|
||||||
# 1 = ERROR
|
# 1 = ERROR
|
||||||
# 2 = WARN
|
# 2 = WARN
|
||||||
# 3 = INFO
|
# 3 = INFO
|
||||||
# 4 = DEBUG
|
# 4 = DEBUG
|
||||||
# Values: NUM Default: 3
|
# Values: [ NUM ] Default: 1
|
||||||
#
|
#
|
||||||
loglevel = 3
|
loglevel = 3
|
||||||
|
|
||||||
# Option: logtarget
|
# Option: logtarget
|
||||||
# Notes.: Set the log target. This could be a file, SYSLOG, STDERR or STDOUT.
|
# Notes.: Set the log target. This could be a file, SYSLOG, STDERR or STDOUT.
|
||||||
# Only one log target can be specified.
|
# Only one log target can be specified.
|
||||||
# If you change logtarget from the default value and you are
|
# If you change logtarget from the default value and you are
|
||||||
# using logrotate -- also adjust or disable rotation in the
|
# using logrotate -- also adjust or disable rotation in the
|
||||||
# corresponding configuration file
|
# corresponding configuration file
|
||||||
# (e.g. /etc/logrotate.d/fail2ban on Debian systems)
|
# (e.g. /etc/logrotate.d/fail2ban on Debian systems)
|
||||||
# Values: STDOUT STDERR SYSLOG file Default: /var/log/fail2ban.log
|
# Values: [ STDOUT | STDERR | SYSLOG | FILE ] Default: STDERR
|
||||||
#
|
#
|
||||||
logtarget = /var/log/fail2ban.log
|
logtarget = /var/log/fail2ban.log
|
||||||
|
|
||||||
|
@ -36,14 +36,14 @@ logtarget = /var/log/fail2ban.log
|
||||||
# Notes.: Set the socket file. This is used to communicate with the daemon. Do
|
# Notes.: Set the socket file. This is used to communicate with the daemon. Do
|
||||||
# not remove this file when Fail2ban runs. It will not be possible to
|
# not remove this file when Fail2ban runs. It will not be possible to
|
||||||
# communicate with the server afterwards.
|
# communicate with the server afterwards.
|
||||||
# Values: FILE Default: /var/run/fail2ban/fail2ban.sock
|
# Values: [ FILE ] Default: /var/run/fail2ban/fail2ban.sock
|
||||||
#
|
#
|
||||||
socket = /var/run/fail2ban/fail2ban.sock
|
socket = /var/run/fail2ban/fail2ban.sock
|
||||||
|
|
||||||
# Option: pidfile
|
# Option: pidfile
|
||||||
# Notes.: Set the PID file. This is used to store the process ID of the
|
# Notes.: Set the PID file. This is used to store the process ID of the
|
||||||
# fail2ban server.
|
# fail2ban server.
|
||||||
# Values: FILE Default: /var/run/fail2ban/fail2ban.pid
|
# Values: [ FILE ] Default: /var/run/fail2ban/fail2ban.pid
|
||||||
#
|
#
|
||||||
pidfile = /var/run/fail2ban/fail2ban.pid
|
pidfile = /var/run/fail2ban/fail2ban.pid
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Fail2Ban filter for 3proxy
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
|
||||||
|
failregex = ^\s[+-]\d{4} \S+ \d{3}0[1-9] \S+ <HOST>:\d+ [\d.]+:\d+ \d+ \d+ \d+\s
|
||||||
|
|
||||||
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
# http://www.3proxy.ru/howtoe.asp#ERRORS indicates that 01-09 are
|
||||||
|
# all authentication problems (%E field)
|
||||||
|
# Log format is: "L%d-%m-%Y %H:%M:%S %z %N.%p %E %U %C:%c %R:%r %O %I %h %T"
|
||||||
|
#
|
||||||
|
# Requested by ykimon in https://github.com/fail2ban/fail2ban/issues/246
|
||||||
|
# Author: Daniel Black
|
|
@ -1,28 +1,54 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban apache-auth filter
|
||||||
#
|
|
||||||
# Author: Cyril Jaquier
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
# Read common prefixes. If any customizations available -- read them from
|
# Read common prefixes. If any customizations available -- read them from
|
||||||
# common.local
|
# apache-common.local
|
||||||
before = apache-common.conf
|
before = apache-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
|
||||||
# Notes.: regex to match the password failure messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = ^%(_apache_error_client)s user .* (authentication failure|not found|password mismatch)\s*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
failregex = ^%(_apache_error_client)s (AH01797: )?client denied by server configuration: (uri )?\S*\s*$
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
^%(_apache_error_client)s (AH01617: )?user .* authentication failure for "\S*": Password Mismatch$
|
||||||
# Values: TEXT
|
^%(_apache_error_client)s (AH01618: )?user .* not found(: )?\S*\s*$
|
||||||
#
|
^%(_apache_error_client)s (AH01614: )?client used wrong authentication scheme: \S*\s*$
|
||||||
|
^%(_apache_error_client)s (AH\d+: )?Authorization of user \S+ to access \S* failed, reason: .*$
|
||||||
|
^%(_apache_error_client)s (AH0179[24]: )?(Digest: )?user .*: password mismatch: \S*\s*$
|
||||||
|
^%(_apache_error_client)s (AH0179[01]: |Digest: )user `.*' in realm `.+' (not found|denied by provider): \S*\s*$
|
||||||
|
^%(_apache_error_client)s (AH01631: )?user .*: authorization failure for "\S*":\s*$
|
||||||
|
^%(_apache_error_client)s (AH01775: )?(Digest: )?invalid nonce .* received - length is not \S+\s*$
|
||||||
|
^%(_apache_error_client)s (AH01788: )?(Digest: )?realm mismatch - got `.*' but expected `.+'\s*$
|
||||||
|
^%(_apache_error_client)s (AH01789: )?(Digest: )?unknown algorithm `.*' received: \S*\s*$
|
||||||
|
^%(_apache_error_client)s (AH01793: )?invalid qop `.*' received: \S*\s*$
|
||||||
|
^%(_apache_error_client)s (AH01777: )?(Digest: )?invalid nonce .* received - user attempted time travel\s*$
|
||||||
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
#
|
||||||
|
# This filter matches the authorization failures of Apache. It takes the log messages
|
||||||
|
# from the modules in aaa that return HTTP_UNAUTHORIZED, HTTP_METHOD_NOT_ALLOWED or
|
||||||
|
# HTTP_FORBIDDEN and not AUTH_GENERAL_ERROR or HTTP_INTERNAL_SERVER_ERROR.
|
||||||
|
#
|
||||||
|
# An unauthorized response 401 is the first step for a browser to instigate authentication
|
||||||
|
# however apache doesn't log this as an error. Only subsequent errors are logged in the
|
||||||
|
# error log.
|
||||||
|
#
|
||||||
|
# Source:
|
||||||
|
#
|
||||||
|
# By searching the code in http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/aaa/*
|
||||||
|
# for ap_log_rerror(APLOG_MARK, APLOG_ERR and examining resulting return code should get
|
||||||
|
# all of these expressions. Lots of submodules like mod_authz_* return back to mod_authz_core
|
||||||
|
# to return the actual failure.
|
||||||
|
#
|
||||||
|
# See also: http://wiki.apache.org/httpd/ListOfErrors
|
||||||
|
# Expressions that don't have tests and aren't common.
|
||||||
|
# more be added with https://issues.apache.org/bugzilla/show_bug.cgi?id=55284
|
||||||
|
# ^%(_apache_error_client)s (AH01778: )?user .*: nonce expired \([\d.]+ seconds old - max lifetime [\d.]+\) - sending new nonce\s*$
|
||||||
|
# ^%(_apache_error_client)s (AH01779: )?user .*: one-time-nonce mismatch - sending new nonce\s*$
|
||||||
|
# ^%(_apache_error_client)s (AH02486: )?realm mismatch - got `.*' but no realm specified\s*$
|
||||||
|
#
|
||||||
|
# Author: Cyril Jaquier
|
||||||
|
# Major edits by Daniel Black
|
||||||
|
|
|
@ -1,27 +1,21 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban configuration file
|
||||||
#
|
#
|
||||||
# List of bad bots fetched from http://www.user-agents.org
|
# Regexp to catch known spambots and software alike. Please verify
|
||||||
# Generated on Sun Feb 11 01:09:15 EST 2007 by ./badbots.sh
|
# that it is your intent to block IPs which were driven by
|
||||||
#
|
# above mentioned bots.
|
||||||
# Author: Yaroslav Halchenko
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
badbotscustom = EmailCollector|WebEMailExtrac|TrackBack/1\.02|sogou music spider
|
badbotscustom = EmailCollector|WebEMailExtrac|TrackBack/1\.02|sogou music spider
|
||||||
badbots = atSpider/1\.0|autoemailspider|China Local Browse 2\.6|ContentSmartz|DataCha0s/2\.0|DBrowse 1\.4b|DBrowse 1\.4d|Demo Bot DOT 16b|Demo Bot Z 16b|DSurf15a 01|DSurf15a 71|DSurf15a 81|DSurf15a VA|EBrowse 1\.4b|Educate Search VxB|EmailSiphon|EmailWolf 1\.00|ESurf15a 15|ExtractorPro|Franklin Locator 1\.8|FSurf15a 01|Full Web Bot 0416B|Full Web Bot 0516B|Full Web Bot 2816B|Industry Program 1\.0\.x|ISC Systems iRc Search 2\.1|IUPUI Research Bot v 1\.9a|LARBIN-EXPERIMENTAL \(efp@gmx\.net\)|LetsCrawl\.com/1\.0 +http\://letscrawl\.com/|Lincoln State Web Browser|LWP\:\:Simple/5\.803|Mac Finder 1\.0\.xx|MFC Foundation Class Library 4\.0|Microsoft URL Control - 6\.00\.8xxx|Missauga Locate 1\.0\.0|Missigua Locator 1\.9|Missouri College Browse|Mizzu Labs 2\.2|Mo College 1\.9|Mozilla/2\.0 \(compatible; NEWT ActiveX; Win32\)|Mozilla/3\.0 \(compatible; Indy Library\)|Mozilla/4\.0 \(compatible; Advanced Email Extractor v2\.xx\)|Mozilla/4\.0 \(compatible; Iplexx Spider/1\.0 http\://www\.iplexx\.at\)|Mozilla/4\.0 \(compatible; MSIE 5\.0; Windows NT; DigExt; DTS Agent|Mozilla/4\.0 efp@gmx\.net|Mozilla/5\.0 \(Version\: xxxx Type\:xx\)|MVAClient|NASA Search 1\.0|Nsauditor/1\.x|PBrowse 1\.4b|PEval 1\.4b|Poirot|Port Huron Labs|Production Bot 0116B|Production Bot 2016B|Production Bot DOT 3016B|Program Shareware 1\.0\.2|PSurf15a 11|PSurf15a 51|PSurf15a VA|psycheclone|RSurf15a 41|RSurf15a 51|RSurf15a 81|searchbot admin@google\.com|sogou spider|sohu agent|SSurf15a 11 |TSurf15a 11|Under the Rainbow 2\.2|User-Agent\: Mozilla/4\.0 \(compatible; MSIE 6\.0; Windows NT 5\.1\)|WebVulnCrawl\.blogspot\.com/1\.0 libwww-perl/5\.803|Wells Search II|WEP Search 00
|
badbots = Atomic_Email_Hunter/4\.0|atSpider/1\.0|autoemailspider|bwh3_user_agent|China Local Browse 2\.6|ContactBot/0\.2|ContentSmartz|DataCha0s/2\.0|DBrowse 1\.4b|DBrowse 1\.4d|Demo Bot DOT 16b|Demo Bot Z 16b|DSurf15a 01|DSurf15a 71|DSurf15a 81|DSurf15a VA|EBrowse 1\.4b|Educate Search VxB|EmailSiphon|EmailSpider|EmailWolf 1\.00|ESurf15a 15|ExtractorPro|Franklin Locator 1\.8|FSurf15a 01|Full Web Bot 0416B|Full Web Bot 0516B|Full Web Bot 2816B|Guestbook Auto Submitter|Industry Program 1\.0\.x|ISC Systems iRc Search 2\.1|IUPUI Research Bot v 1\.9a|LARBIN-EXPERIMENTAL \(efp@gmx\.net\)|LetsCrawl\.com/1\.0 +http\://letscrawl\.com/|Lincoln State Web Browser|LMQueueBot/0\.2|LWP\:\:Simple/5\.803|Mac Finder 1\.0\.xx|MFC Foundation Class Library 4\.0|Microsoft URL Control - 6\.00\.8xxx|Missauga Locate 1\.0\.0|Missigua Locator 1\.9|Missouri College Browse|Mizzu Labs 2\.2|Mo College 1\.9|MVAClient|Mozilla/2\.0 \(compatible; NEWT ActiveX; Win32\)|Mozilla/3\.0 \(compatible; Indy Library\)|Mozilla/3\.0 \(compatible; scan4mail \(advanced version\) http\://www\.peterspages\.net/?scan4mail\)|Mozilla/4\.0 \(compatible; Advanced Email Extractor v2\.xx\)|Mozilla/4\.0 \(compatible; Iplexx Spider/1\.0 http\://www\.iplexx\.at\)|Mozilla/4\.0 \(compatible; MSIE 5\.0; Windows NT; DigExt; DTS Agent|Mozilla/4\.0 efp@gmx\.net|Mozilla/5\.0 \(Version\: xxxx Type\:xx\)|NameOfAgent \(CMS Spider\)|NASA Search 1\.0|Nsauditor/1\.x|PBrowse 1\.4b|PEval 1\.4b|Poirot|Port Huron Labs|Production Bot 0116B|Production Bot 2016B|Production Bot DOT 3016B|Program Shareware 1\.0\.2|PSurf15a 11|PSurf15a 51|PSurf15a VA|psycheclone|RSurf15a 41|RSurf15a 51|RSurf15a 81|searchbot admin@google\.com|ShablastBot 1\.0|snap\.com beta crawler v0|Snapbot/1\.0|Snapbot/1\.0 \(Snap Shots, +http\://www\.snap\.com\)|sogou develop spider|Sogou Orion spider/3\.0\(+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sogou spider|Sogou web spider/3\.0\(+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sohu agent|SSurf15a 11 |TSurf15a 11|Under the Rainbow 2\.2|User-Agent\: Mozilla/4\.0 \(compatible; MSIE 6\.0; Windows NT 5\.1\)|VadixBot|WebVulnCrawl\.unknown/1\.0 libwww-perl/5\.803|Wells Search II|WEP Search 00
|
||||||
|
|
||||||
# Option: failregex
|
|
||||||
# Notes.: Regexp to catch known spambots and software alike. Please verify
|
|
||||||
# that it is your intent to block IPs which were driven by
|
|
||||||
# above mentioned bots.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = ^<HOST> -.*"(GET|POST).*HTTP.*"(?:%(badbots)s|%(badbotscustom)s)"$
|
failregex = ^<HOST> -.*"(GET|POST).*HTTP.*"(?:%(badbots)s|%(badbotscustom)s)"$
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
# List of bad bots fetched from http://www.user-agents.org
|
||||||
|
# Generated on Thu Nov 7 14:23:35 PST 2013 by files/gen_badbots.
|
||||||
|
#
|
||||||
|
# Author: Yaroslav Halchenko
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
# Generic configuration items (to be used as interpolations) in other
|
# Generic configuration items (to be used as interpolations) in other
|
||||||
# apache filters
|
# apache filters.
|
||||||
#
|
|
||||||
# Author: Yaroslav Halchenko
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
# Load customizations if any available
|
# Load customizations if any available
|
||||||
after = apache-common.local
|
after = apache-common.local
|
||||||
|
|
||||||
|
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
|
|
||||||
|
_apache_error_client = \[[^]]*\] \[(error|\S+:\S+)\]( \[pid \d+:\S+ \d+\])? \[client <HOST>(:\d{1,5})?\]
|
||||||
|
|
||||||
# Common prefix for [error] apache messages which also would include <HOST>
|
# Common prefix for [error] apache messages which also would include <HOST>
|
||||||
_apache_error_client = \[[^]]+\] \[error\] \[client <HOST>\]
|
# Depending on the version it could be
|
||||||
|
# 2.2: [Sat Jun 01 11:23:08 2013] [error] [client 1.2.3.4]
|
||||||
|
# 2.4: [Thu Jun 27 11:55:44.569531 2013] [core:info] [pid 4101:tid 2992634688] [client 1.2.3.4:46652]
|
||||||
|
#
|
||||||
|
# Reference: https://github.com/fail2ban/fail2ban/issues/268
|
||||||
|
#
|
||||||
|
# Author: Yaroslav Halchenko
|
||||||
|
|
|
@ -1,28 +1,20 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter to web requests for home directories on Apache servers
|
||||||
#
|
|
||||||
# Author: Yaroslav O. Halchenko <debian@onerussian.com>
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
|
# Regex to match failures to find a home directory on a server, which
|
||||||
|
# became popular last days. Most often attacker just uses IP instead of
|
||||||
|
# domain name -- so expect to see them in generic error.log if you have
|
||||||
|
# per-domain log files.
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
# Read common prefixes. If any customizations available -- read them from
|
# overwrite with apache-common.local if _apache_error_client is incorrect.
|
||||||
# common.local
|
|
||||||
before = apache-common.conf
|
before = apache-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
|
||||||
# Notes.: regex to match failures to find a home directory on a server, which
|
|
||||||
# became popular last days. Most often attacker just uses IP instead of
|
|
||||||
# domain name -- so expect to see them in generic error.log if you have
|
|
||||||
# per-domain log files.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = ^%(_apache_error_client)s File does not exist: .*/~.*
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
failregex = ^%(_apache_error_client)s (AH00128: )?File does not exist: .*/~.*
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Yaroslav O. Halchenko <debian@onerussian.com>
|
||||||
|
|
|
@ -1,29 +1,18 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter to block web requests for scripts (on non scripted websites)
|
||||||
#
|
|
||||||
# Author: Cyril Jaquier
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
# Read common prefixes. If any customizations available -- read them from
|
# overwrite with apache-common.local if _apache_error_client is incorrect.
|
||||||
# common.local
|
|
||||||
before = apache-common.conf
|
before = apache-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
|
||||||
# Notes.: regex to match the password failure messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = ^%(_apache_error_client)s (File does not exist|script not found or unable to stat): /\S*(\.php|\.asp|\.exe|\.pl)\s*$
|
failregex = ^%(_apache_error_client)s (File does not exist|script not found or unable to stat): /\S*(\.php|\.asp|\.exe|\.pl)\s*$
|
||||||
^%(_apache_error_client)s script '/\S*(\.php|\.asp|\.exe|\.pl)\S*' not found or unable to stat\s*$
|
^%(_apache_error_client)s script '/\S*(\.php|\.asp|\.exe|\.pl)\S*' not found or unable to stat\s*$
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
|
||||||
|
# Author: Cyril Jaquier
|
||||||
|
|
|
@ -1,25 +1,15 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter to block web requests on a long or suspicious nature
|
||||||
#
|
|
||||||
# Author: Tim Connors
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
# Read common prefixes. If any customizations available -- read them from
|
# overwrite with apache-common.local if _apache_error_client is incorrect.
|
||||||
# common.local
|
|
||||||
before = apache-common.conf
|
before = apache-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
|
||||||
# Notes.: Regexp to catch Apache overflow attempts.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = ^%(_apache_error_client)s (Invalid (method|URI) in request|request failed: URI too long|erroneous characters after protocol string)
|
failregex = ^%(_apache_error_client)s (Invalid (method|URI) in request|request failed: URI too long|erroneous characters after protocol string)
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Tim Connors
|
||||||
|
|
|
@ -1,33 +1,24 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for Anti-Spam SMTP Proxy Server also known as ASSP
|
||||||
# for Anti-Spam SMTP Proxy Server also known as ASSP
|
#
|
||||||
# Honmepage: http://www.magicvillage.de/~Fritz_Borgstedt/assp/0003D91C-8000001C/
|
# Honmepage: http://www.magicvillage.de/~Fritz_Borgstedt/assp/0003D91C-8000001C/
|
||||||
# ProjektSite: http://sourceforge.net/projects/assp/?source=directory
|
# ProjektSite: http://sourceforge.net/projects/assp/?source=directory
|
||||||
#
|
#
|
||||||
# Author: Enrico Labedzki (enrico.labedzki@deiwos.de)
|
|
||||||
#
|
#
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
__assp_actions = (?:dropping|refusing)
|
||||||
# Notes.: regex to match the SMTP failure messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
failregex = ^(:? \[SSL-out\])? <HOST> max sender authentication errors \(\d{,3}\) exceeded -- %(__assp_actions)s connection - after reply: \d{3} \d{1}\.\d{1}.\d{1} Error: authentication failed: \w+;$
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
^(?: \[SSL-out\])? <HOST> SSL negotiation with client failed: SSL accept attempt failed with unknown error.*:unknown protocol;$
|
||||||
# (?:::f{4,6}:)?(?P<host>\S+)
|
^ Blocking <HOST> - too much AUTH errors \(\d{,3}\);$
|
||||||
# Values: TEXT
|
|
||||||
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
#
|
#
|
||||||
# Examples: Apr-27-13 02:33:09 Blocking 217.194.197.97 - too much AUTH errors (41);
|
# Examples: Apr-27-13 02:33:09 Blocking 217.194.197.97 - too much AUTH errors (41);
|
||||||
# Dec-29-12 17:10:31 [SSL-out] 200.247.87.82 SSL negotiation with client failed: SSL accept attempt failed with unknown errorerror:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol;
|
# Dec-29-12 17:10:31 [SSL-out] 200.247.87.82 SSL negotiation with client failed: SSL accept attempt failed with unknown errorerror:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol;
|
||||||
# Dec-30-12 04:01:47 [SSL-out] 81.82.232.66 max sender authentication errors (5) exceeded
|
# Dec-30-12 04:01:47 [SSL-out] 81.82.232.66 max sender authentication errors (5) exceeded
|
||||||
__assp_actions = (dropping|refusing)
|
|
||||||
|
|
||||||
failregex = <HOST> max sender authentication errors \(\d{,3}\) exceeded -- %(__assp_actions)s connection - after reply: \d{3} \d{1}\.\d{1}.\d{1} Error: authentication failed: [a-zA-Z0-9]+;$
|
|
||||||
<HOST> SSL negotiation with client failed: SSL accept attempt failed with unknown error.*:unknown protocol;$
|
|
||||||
Blocking <HOST> - too much AUTH errors \(\d{,3}\);$
|
|
||||||
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
#
|
||||||
ignoreregex =
|
# Author: Enrico Labedzki (enrico.labedzki@deiwos.de)
|
||||||
|
|
||||||
|
|
|
@ -1,43 +1,23 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for asterisk authentication failures
|
||||||
#
|
#
|
||||||
# Author: Xavier Devlamynck
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
[INCLUDES]
|
|
||||||
|
|
||||||
# Read common prefixes. If any customizations available -- read them from
|
|
||||||
# common.local
|
|
||||||
before = common.conf
|
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
__pid_re = (?:\[\d+\])
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
# All Asterisk log messages begin like this:
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
log_prefix= \[\]\s*(?:NOTICE|SECURITY)%(__pid_re)s:?(?:\[\S+\d*\])? \S+:\d*
|
||||||
# (?:::f{4,6}:)?(?P<host>\S+)
|
|
||||||
# Values: TEXT
|
failregex = ^%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - (Wrong password|No matching peer found|Username/auth name mismatch|Device does not match ACL|Peer is not supposed to register|ACL error \(permit/deny\)|Not a local domain)$
|
||||||
#
|
^%(log_prefix)s Call from '[^']*' \(<HOST>:\d+\) to extension '\d+' rejected because extension not found in context 'default'\.$
|
||||||
failregex = NOTICE%(__pid_re)s [^:]+: Registration from '[^']*' failed for '<HOST>(:[0-9]+)?' - Wrong password$
|
^%(log_prefix)s Host <HOST> failed to authenticate as '[^']*'$
|
||||||
NOTICE%(__pid_re)s [^:]+: Registration from '[^']*' failed for '<HOST>(:[0-9]+)?' - No matching peer found$
|
^%(log_prefix)s No registration for peer '[^']*' \(from <HOST>\)$
|
||||||
NOTICE%(__pid_re)s [^:]+: Registration from '[^']*' failed for '<HOST>(:[0-9]+)?' - Username/auth name mismatch$
|
^%(log_prefix)s Host <HOST> failed MD5 authentication for '[^']*' \([^)]+\)$
|
||||||
NOTICE%(__pid_re)s [^:]+: Registration from '[^']*' failed for '<HOST>(:[0-9]+)?' - Device does not match ACL$
|
^%(log_prefix)s Failed to authenticate (user|device) [^@]+@<HOST>\S*$
|
||||||
NOTICE%(__pid_re)s [^:]+: Registration from '[^']*' failed for '<HOST>(:[0-9]+)?' - Peer is not supposed to register$
|
^%(log_prefix)s (?:handle_request_subscribe: )?Sending fake auth rejection for (device|user) \d*<sip:[^@]+@<HOST>>;tag=\w+\S*$
|
||||||
NOTICE%(__pid_re)s [^:]+: Registration from '[^']*' failed for '<HOST>(:[0-9]+)?' - ACL error \(permit/deny\)$
|
^%(log_prefix)s SecurityEvent="(FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)",EventTV="[\d-]+",Severity="[\w]+",Service="[\w]+",EventVersion="\d+",AccountID="\d+",SessionID="0x[\da-f]+",LocalAddress="IPV[46]/(UD|TC)P/[\da-fA-F:.]+/\d+",RemoteAddress="IPV[46]/(UD|TC)P/<HOST>/\d+"(,Challenge="\w+",ReceivedChallenge="\w+")?(,ReceivedHash="[\da-f]+")?$
|
||||||
NOTICE%(__pid_re)s [^:]+: Registration from '[^']*' failed for '<HOST>(:[0-9]+)?' - Not a local domain$
|
|
||||||
NOTICE%(__pid_re)s\[[^:]+\] [^:]+: Call from '[^']*' \(<HOST>:[0-9]+\) to extension '[0-9]+' rejected because extension not found in context 'default'.$
|
|
||||||
NOTICE%(__pid_re)s [^:]+: Host <HOST> failed to authenticate as '[^']*'$
|
|
||||||
NOTICE%(__pid_re)s [^:]+: No registration for peer '[^']*' \(from <HOST>\)$
|
|
||||||
NOTICE%(__pid_re)s [^:]+: Host <HOST> failed MD5 authentication for '[^']*' \([^)]+\)$
|
|
||||||
NOTICE%(__pid_re)s [^:]+: Failed to authenticate user [^@]+@<HOST>\S*$
|
|
||||||
SECURITY%(__pid_re)s [^:]+: SecurityEvent="InvalidAccountID",EventTV="[0-9-]+",Severity="[a-zA-Z]+",Service="[a-zA-Z]+",EventVersion="[0-9]+",AccountID="[0-9]+",SessionID="0x[0-9a-f]+",LocalAddress="IPV[46]/(UD|TC)P/[0-9a-fA-F:.]+/[0-9]+",RemoteAddress="IPV[46]/(UD|TC)P/<HOST>/[0-9]+"$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
|
||||||
|
# Author: Xavier Devlamynck
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
# Generic configuration items (to be used as interpolations) in other
|
# Generic configuration items (to be used as interpolations) in other
|
||||||
# filters or actions configurations
|
# filters or actions configurations
|
||||||
#
|
#
|
||||||
# Author: Yaroslav Halchenko
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
|
@ -33,7 +30,7 @@ __daemon_extra_re = (?:\[ID \d+ \S+\])
|
||||||
|
|
||||||
# Combinations of daemon name and PID
|
# Combinations of daemon name and PID
|
||||||
# EXAMPLES: sshd[31607], pop(pam_unix)[4920]
|
# EXAMPLES: sshd[31607], pop(pam_unix)[4920]
|
||||||
__daemon_combs_re = (?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_re)s?:)
|
__daemon_combs_re = (?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_re)s?:?)
|
||||||
|
|
||||||
# Some messages have a kernel prefix with a timestamp
|
# Some messages have a kernel prefix with a timestamp
|
||||||
# EXAMPLES: kernel: [769570.846956]
|
# EXAMPLES: kernel: [769570.846956]
|
||||||
|
@ -41,12 +38,14 @@ __kernel_prefix = kernel: \[\d+\.\d+\]
|
||||||
|
|
||||||
__hostname = \S+
|
__hostname = \S+
|
||||||
|
|
||||||
|
# A MD5 hex
|
||||||
|
# EXAMPLES: 07:06:27:55:b0:e3:0c:3c:5a:28:2d:7c:7e:4c:77:5f
|
||||||
|
__md5hex = (?:[\da-f]{2}:){15}[\da-f]{2}
|
||||||
|
|
||||||
# bsdverbose is where syslogd is started with -v or -vv and results in <4.3> or
|
# bsdverbose is where syslogd is started with -v or -vv and results in <4.3> or
|
||||||
# <auth.info> appearing before the host as per testcases/files/logs/bsd/*.
|
# <auth.info> appearing before the host as per testcases/files/logs/bsd/*.
|
||||||
__bsd_syslog_verbose = (<[^.]+\.[^.]+>)
|
__bsd_syslog_verbose = (<[^.]+\.[^.]+>)
|
||||||
|
|
||||||
#
|
|
||||||
# Common line prefixes (beginnings) which could be used in filters
|
# Common line prefixes (beginnings) which could be used in filters
|
||||||
#
|
#
|
||||||
# [bsdverbose]? [hostname] [vserver tag] daemon_id spaces
|
# [bsdverbose]? [hostname] [vserver tag] daemon_id spaces
|
||||||
|
@ -54,3 +53,4 @@ __bsd_syslog_verbose = (<[^.]+\.[^.]+>)
|
||||||
# This can be optional (for instance if we match named native log files)
|
# This can be optional (for instance if we match named native log files)
|
||||||
__prefix_line = \s*%(__bsd_syslog_verbose)s?\s*(?:%(__hostname)s )?(?:%(__kernel_prefix)s )?(?:@vserver_\S+ )?%(__daemon_combs_re)s?\s%(__daemon_extra_re)s?\s*
|
__prefix_line = \s*%(__bsd_syslog_verbose)s?\s*(?:%(__hostname)s )?(?:%(__kernel_prefix)s )?(?:@vserver_\S+ )?%(__daemon_combs_re)s?\s%(__daemon_extra_re)s?\s*
|
||||||
|
|
||||||
|
# Author: Yaroslav Halchenko
|
||||||
|
|
|
@ -1,23 +1,19 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for courier authentication failures
|
||||||
#
|
|
||||||
# Author: Christoph Haas
|
|
||||||
# Modified by: Cyril Jaquier
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
# Read common prefixes. If any customizations available -- read them from
|
||||||
|
# common.local
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
_daemon = (?:courier)?(?:imapd?|pop3d?)(?:login)?(?:-ssl)?
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
failregex = ^%(__prefix_line)sLOGIN FAILED, user=.*, ip=\[<HOST>\]$
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = LOGIN FAILED, .*, ip=\[<HOST>\]$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Christoph Haas
|
||||||
|
# Modified by: Cyril Jaquier
|
||||||
|
|
|
@ -1,22 +1,19 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter to block relay attempts though a Courier smtp server
|
||||||
#
|
|
||||||
# Author: Cyril Jaquier
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
# Read common prefixes. If any customizations available -- read them from
|
||||||
|
# common.local
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
_daemon = courieresmtpd
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
failregex = ^%(__prefix_line)serror,relay=<HOST>,.*: 550 User unknown\.$
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = error,relay=<HOST>,.*550 User unknown
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Cyril Jaquier
|
||||||
|
|
|
@ -1,25 +1,20 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for authentication failures on Cyrus imap server
|
||||||
#
|
|
||||||
# Author: Jan Wagner <waja@cyconet.org>
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
# Read common prefixes. If any customizations available -- read them from
|
||||||
|
# common.local
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
_daemon = (?:cyrus/)?(?:imapd?|pop3d?)
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
failregex = ^%(__prefix_line)sbadlogin: \S+ ?\[<HOST>\] \S+ .*?\[?SASL\(-13\): authentication failure: .*\]?$
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = : badlogin: .*\[<HOST>\] plaintext .*SASL\(-13\): authentication failure: checkpass failed$
|
|
||||||
: badlogin: .*\[<HOST>\] LOGIN \[SASL\(-13\): authentication failure: checkpass failed\]$
|
|
||||||
: badlogin: .*\[<HOST>\] (?:CRAM-MD5|NTLM) \[SASL\(-13\): authentication failure: incorrect (?:digest|NTLM) response\]$
|
|
||||||
: badlogin: .*\[<HOST>\] DIGEST-MD5 \[SASL\(-13\): authentication failure: client response doesn't match what we generated\]$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Jan Wagner <waja@cyconet.org>
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
# Fail2Ban configuration file for dovcot
|
# Fail2Ban filter Dovecot authentication and pop3/imap server
|
||||||
#
|
|
||||||
# Author: Martin Waschbuesch
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
_daemon = (auth|dovecot(-auth)?|auth-worker)
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
failregex = ^%(__prefix_line)s(pam_unix(\(dovecot:auth\))?:)?\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=dovecot ruser=\S* rhost=<HOST>(\s+user=\S*)?\s*$
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
^%(__prefix_line)s(pop3|imap)-login: (Info: )?(Aborted login|Disconnected)(: Inactivity)? \(((no auth attempts|auth failed, \d+ attempts)( in \d+ secs)?|tried to use (disabled|disallowed) \S+ auth)\):( user=<\S*>,)?( method=\S+,)? rip=<HOST>, lip=(\d{1,3}\.){3}\d{1,3}(, session=<\w+>)?(, TLS( handshaking)?(: Disconnected)?)?\s*$
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
^%(__prefix_line)s(Info|dovecot: auth\(default\)): pam\(\S+,<HOST>\): pam_authenticate\(\) failed: (User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \(password mismatch\?\))\s*$
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = .*(?:pop3-login|imap-login):.*(?:Authentication failure|Aborted login \(auth failed|Aborted login \(tried to use disabled|Disconnected \(auth failed).*\s+rip=(?P<host>\S*),.*
|
|
||||||
pam.*dovecot.*(?:authentication failure).*\s+rhost=<HOST>(?:\s+user=.*)?\s*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
# * the first regex is essentially a copy of pam-generic.conf
|
||||||
|
# * Probably doesn't do dovecot sql/ldap backends properly
|
||||||
|
#
|
||||||
|
# Author: Martin Waschbuesch
|
||||||
|
# Daniel Black (rewrote with begin and end anchors)
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for dropbear
|
||||||
#
|
#
|
||||||
# Author: Francis Russell
|
# NOTE: The regex below is ONLY intended to work with a patched
|
||||||
# Zak B. Elep
|
# version of Dropbear as described here:
|
||||||
|
# http://www.unchartedbackwaters.co.uk/pyblosxom/static/patches
|
||||||
|
# ^%(__prefix_line)sexit before auth from <HOST>.*\s*$
|
||||||
#
|
#
|
||||||
|
# The standard Dropbear output doesn't provide enough information to
|
||||||
|
# ban all types of attack. The Dropbear patch adds IP address
|
||||||
|
# information to the 'exit before auth' message which is always
|
||||||
|
# produced for any form of non-successful login. It is that message
|
||||||
|
# which this file matches.
|
||||||
#
|
#
|
||||||
# More information: http://bugs.debian.org/546913
|
# More information: http://bugs.debian.org/546913
|
||||||
|
|
||||||
|
@ -12,40 +19,23 @@
|
||||||
# common.local
|
# common.local
|
||||||
before = common.conf
|
before = common.conf
|
||||||
|
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
_daemon = dropbear
|
_daemon = dropbear
|
||||||
|
|
||||||
# Option: failregex
|
failregex = ^%(__prefix_line)s[Ll]ogin attempt for nonexistent user ('.*' )?from <HOST>:.*$
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
^%(__prefix_line)s[Bb]ad (PAM )?password attempt for .+ from <HOST>.*$
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
^%(__prefix_line)s[Ee]xit before auth \(user '.+', \d+ fails\): Max auth tries reached - user '.+' from <HOST>:\d+\s*$
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>\S+)
|
|
||||||
# Values: TEXT
|
|
||||||
|
|
||||||
# These match the unmodified dropbear messages. It isn't possible to
|
|
||||||
# match the source of the 'exit before auth' messages from dropbear.
|
|
||||||
#
|
|
||||||
failregex = ^%(__prefix_line)slogin attempt for nonexistent user ('.*' )?from <HOST>:.*\s*$
|
|
||||||
^%(__prefix_line)sbad password attempt for .+ from <HOST>:.*\s*$
|
|
||||||
|
|
||||||
# The only line we need to match with the modified dropbear.
|
|
||||||
|
|
||||||
# NOTE: The failregex below is ONLY intended to work with a patched
|
|
||||||
# version of Dropbear as described here:
|
|
||||||
# http://www.unchartedbackwaters.co.uk/pyblosxom/static/patches
|
|
||||||
#
|
|
||||||
# The standard Dropbear output doesn't provide enough information to
|
|
||||||
# ban all types of attack. The Dropbear patch adds IP address
|
|
||||||
# information to the 'exit before auth' message which is always
|
|
||||||
# produced for any form of non-successful login. It is that message
|
|
||||||
# which this file matches.
|
|
||||||
|
|
||||||
# failregex = ^%(__prefix_line)sexit before auth from <HOST>.*\s*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
#
|
||||||
|
# The first two regexs here match the unmodified dropbear messages. It isn't
|
||||||
|
# possible to match the source of the 'exit before auth' messages from dropbear
|
||||||
|
# as they don't include the "from <HOST>" bit.
|
||||||
|
#
|
||||||
|
# The second last failregex line we need to match with the modified dropbear.
|
||||||
|
#
|
||||||
|
# Author: Francis Russell
|
||||||
|
# Zak B. Elep
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Fail2Ban filter file for common exim expressions
|
||||||
|
#
|
||||||
|
# This is to be used by other exim filters
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
# Load customizations if any available
|
||||||
|
after = exim-common.local
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
host_info = H=([\w.-]+ )?(\(\S+\) )?\[<HOST>\](:\d+)? (I=\[\S+\]:\d+ )?(U=\S+ )?(P=e?smtp )?
|
||||||
|
pid = ( \[\d+\])?
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
# From exim source code: ./src/receive.c:add_host_info_for_log
|
||||||
|
#
|
||||||
|
# Author: Daniel Black
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Fail2Ban filter for exim the spam rejection messages
|
||||||
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
# Read common prefixes. If any customizations available -- read them from
|
||||||
|
# exim-common.local
|
||||||
|
before = exim-common.conf
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
failregex = ^%(pid)s \S+ F=(<>|\S+@\S+) %(host_info)srejected by local_scan\(\): .{0,256}$
|
||||||
|
^%(pid)s %(host_info)sF=(<>|[^@]+@\S+) rejected RCPT [^@]+@\S+: .*dnsbl.*\s*$
|
||||||
|
^%(pid)s \S+ %(host_info)sF=(<>|[^@]+@\S+) rejected after DATA: This message contains a virus \(\S+\)\.\s*$
|
||||||
|
|
||||||
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
# The %(host_info) defination contains a <HOST> match
|
||||||
|
#
|
||||||
|
# Author: Cyril Jaquier
|
||||||
|
# Daniel Black (rewrote with strong regexs)
|
|
@ -1,23 +1,28 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for exim
|
||||||
#
|
|
||||||
# Author: Cyril Jaquier
|
|
||||||
#
|
#
|
||||||
|
# This includes the rejection messages of exim. For spam and filter
|
||||||
|
# related bans use the exim-spam.conf
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
# Read common prefixes. If any customizations available -- read them from
|
||||||
|
# exim-common.local
|
||||||
|
before = exim-common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
failregex = ^%(pid)s %(host_info)ssender verify fail for <\S+>: (?:Unknown user|Unrouteable address|all relevant MX records point to non-existent hosts)\s*$
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
^%(pid)s (plain|login) authenticator failed for (\S+ )?\(\S+\) \[<HOST>\]: 535 Incorrect authentication data( \(set_id=.*\)|: \d+ Time\(s\))?\s*$
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
^%(pid)s %(host_info)sF=(<>|[^@]+@\S+) rejected RCPT [^@]+@\S+: (relay not permitted|Sender verify failed|Unknown user)\s*$
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
^%(pid)s SMTP protocol synchronization error \(.*\): rejected (connection from|"\S+") %(host_info)s(next )?input=".*"\s*$
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
^%(pid)s SMTP call from \S+ \[<HOST>\](:\d+)? (I=\[\S+\]:\d+ )?dropped: too many nonmail commands \(last was "\S+"\)\s*$
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = \[<HOST>\] .*(?:rejected by local_scan|Unrouteable address)
|
|
||||||
login authenticator failed for .* \[<HOST>\]: 535 Incorrect authentication data \(set_id=.*\)\s*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
# The %(host_info) defination contains a <HOST> match
|
||||||
|
#
|
||||||
|
# Author: Cyril Jaquier
|
||||||
|
# Daniel Black (rewrote with strong regexs)
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
# Fail2Ban configuration file for wuftpd
|
# Fail2Ban filter file for gssftp
|
||||||
#
|
|
||||||
# Author: Kevin Zembower (copied from wsftpd.conf)
|
|
||||||
#
|
#
|
||||||
|
# Note: gssftp is part of the krb5-appl-servers in Fedora
|
||||||
#
|
#
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
_daemon = ftpd
|
||||||
# Notes.: regex to match the password failures messages in the logfile.
|
|
||||||
# Values: TEXT
|
failregex = ^%(__prefix_line)srepeated login failures from <HOST> \(\S+\)$
|
||||||
#
|
|
||||||
failregex = ftpd(?:\[\d+\])?:\s+repeated login failures from <HOST> \(\S+\)$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Kevin Zembower
|
||||||
|
# Edited: Daniel Black - syslog based daemon
|
||||||
|
|
|
@ -1,18 +1,10 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter to match wrong passwords as notified by lighttpd's auth Module
|
||||||
#
|
|
||||||
# Author: Francois Boulogne <fboulogne@april.org>
|
|
||||||
#
|
#
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
failregex = ^: \(http_auth\.c\.\d+\) (password doesn\'t match .* username: .*|digest: auth failed for .*: wrong password|get_password failed), IP: <HOST>\s*$
|
||||||
# Notes.: regex to match wrong passwords as notified by lighttpd's auth Module
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = .*http_auth.*(password doesn\'t match|wrong password).*IP: <HOST>\s*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Francois Boulogne <fboulogne@april.org>
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Fail2Ban configuration file
|
|
||||||
#
|
|
||||||
# Author: Arturo 'Buanzo' Busleiman <buanzo@buanzo.com.ar>
|
|
||||||
#
|
|
||||||
|
|
||||||
[Definition]
|
|
||||||
|
|
||||||
# Option: failregex
|
|
||||||
# Notes.: regex to match ALERTS as notified by lighttpd's FastCGI Module
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = .*ALERT\ -\ .*attacker\ \'<HOST>\'
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
|
|
@ -1,8 +1,11 @@
|
||||||
# Fail2Ban configuration file for unsuccesfull MySQL authentication attempts
|
# Fail2Ban filter for unsuccesfull MySQL authentication attempts
|
||||||
#
|
#
|
||||||
# Authors: Artur Penttinen
|
|
||||||
# Yaroslav O. Halchenko
|
|
||||||
#
|
#
|
||||||
|
# To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld]:
|
||||||
|
# log-error=/var/log/mysqld.log
|
||||||
|
# log-warning = 2
|
||||||
|
#
|
||||||
|
# If using mysql syslog [mysql_safe] has syslog in /etc/my.cnf
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
|
||||||
|
@ -10,22 +13,20 @@
|
||||||
# common.local
|
# common.local
|
||||||
before = common.conf
|
before = common.conf
|
||||||
|
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
#_daemon = mysqld
|
_daemon = mysqld
|
||||||
|
|
||||||
# Option: failregex
|
failregex = ^%(__prefix_line)s(\d{6} \s?\d{1,2}:\d{2}:\d{2} )?\[Warning\] Access denied for user '\w+'@'<HOST>' (to database '[^']*'|\(using password: (YES|NO)\))*\s*$
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
|
||||||
# 130322 11:26:54 [Warning] Access denied for user 'root'@'127.0.0.1' (using password: YES)
|
|
||||||
failregex = Access denied for user '\w+'@'<HOST>' (to database '[^']*'|\(using password: (YES|NO)\))*\s*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
#
|
||||||
|
# Technically __prefix_line can equate to an empty string hence it can support
|
||||||
|
# syslog and non-syslog at once.
|
||||||
|
# Example:
|
||||||
|
# 130322 11:26:54 [Warning] Access denied for user 'root'@'127.0.0.1' (using password: YES)
|
||||||
|
#
|
||||||
|
# Authors: Artur Penttinen
|
||||||
|
# Yaroslav O. Halchenko
|
||||||
|
|
|
@ -1,34 +1,48 @@
|
||||||
# Fail2Ban configuration file for named (bind9). Trying to generalize the
|
# Fail2Ban filter file for named (bind9).
|
||||||
# structure which is general to capture general patterns in log
|
|
||||||
# lines to cover different configurations/distributions
|
|
||||||
#
|
#
|
||||||
# Author: Yaroslav Halchenko
|
|
||||||
|
# This filter blocks attacks against named (bind9) however it requires special
|
||||||
|
# configuration on bind.
|
||||||
#
|
#
|
||||||
|
# By default, logging is off with bind9 installation.
|
||||||
#
|
#
|
||||||
|
# You will need something like this in your named.conf to provide proper logging.
|
||||||
|
#
|
||||||
|
# logging {
|
||||||
|
# channel security_file {
|
||||||
|
# file "/var/log/named/security.log" versions 3 size 30m;
|
||||||
|
# severity dynamic;
|
||||||
|
# print-time yes;
|
||||||
|
# };
|
||||||
|
# category security {
|
||||||
|
# security_file;
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
#
|
|
||||||
# Daemon name
|
# Daemon name
|
||||||
_daemon=named
|
_daemon=named
|
||||||
|
|
||||||
#
|
|
||||||
# Shortcuts for easier comprehension of the failregex
|
# Shortcuts for easier comprehension of the failregex
|
||||||
|
|
||||||
__pid_re=(?:\[\d+\])
|
__pid_re=(?:\[\d+\])
|
||||||
__daemon_re=\(?%(_daemon)s(?:\(\S+\))?\)?:?
|
__daemon_re=\(?%(_daemon)s(?:\(\S+\))?\)?:?
|
||||||
__daemon_combs_re=(?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_re)s?:)
|
__daemon_combs_re=(?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_re)s?:)
|
||||||
|
|
||||||
# hostname daemon_id spaces
|
# hostname daemon_id spaces
|
||||||
# this can be optional (for instance if we match named native log files)
|
# this can be optional (for instance if we match named native log files)
|
||||||
__line_prefix=(?:\s\S+ %(__daemon_combs_re)s\s+)?
|
__line_prefix=(?:\s\S+ %(__daemon_combs_re)s\s+)?
|
||||||
|
|
||||||
# Option: failregex
|
failregex = ^%(__line_prefix)s(\.\d+)?( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: (view (internal|external): )?query(?: \(cache\))? '.*' denied\s*$
|
||||||
# Notes.: regex to match the password failures messages in the logfile.
|
^%(__line_prefix)s(\.\d+)?( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: zone transfer '\S+/AXFR/\w+' denied\s*$
|
||||||
# Values: TEXT
|
^%(__line_prefix)s(\.\d+)?( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: bad zone transfer request: '\S+/IN': non-authoritative zone \(NOTAUTH\)\s*$
|
||||||
#
|
|
||||||
failregex = %(__line_prefix)sclient <HOST>#\S+: (view (internal|external): )?query(?: \(cache\))? '.*' denied\s*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
# DEV Notes:
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
# Trying to generalize the
|
||||||
# Values: TEXT
|
# structure which is general to capture general patterns in log
|
||||||
|
# lines to cover different configurations/distributions
|
||||||
|
#
|
||||||
|
# (\.\d+)? is a really ugly catch of the microseconds not captured in the date detector
|
||||||
#
|
#
|
||||||
ignoreregex =
|
# Author: Yaroslav Halchenko
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
# fail2ban filter configuration for nginx
|
||||||
|
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
|
||||||
|
failregex = ^ \[error\] \d+#\d+: \*\d+ user "\S+":? (password mismatch|was not found in ".*"), client: <HOST>, server: \S+, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"
|
||||||
|
|
||||||
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV NOTES:
|
||||||
|
# Based on samples in https://github.com/fail2ban/fail2ban/pull/43/files
|
||||||
|
# Extensive search of all nginx auth failures not done yet.
|
||||||
|
#
|
||||||
|
# Author: Daniel Black
|
|
@ -1,30 +1,29 @@
|
||||||
# Fail2Ban configuration file for generic PAM authentication errors
|
# Fail2Ban configuration file for generic PAM authentication errors
|
||||||
#
|
#
|
||||||
# Author: Yaroslav Halchenko
|
|
||||||
#
|
[INCLUDES]
|
||||||
#
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# if you want to catch only login erros from specific daemons, use smth like
|
# if you want to catch only login errors from specific daemons, use something like
|
||||||
#_ttys_re=(?:ssh|pure-ftpd|ftp)
|
#_ttys_re=(?:ssh|pure-ftpd|ftp)
|
||||||
# To catch all failed logins
|
#
|
||||||
|
# Default: catch all failed logins
|
||||||
_ttys_re=\S*
|
_ttys_re=\S*
|
||||||
|
|
||||||
#
|
|
||||||
# Shortcuts for easier comprehension of the failregex
|
|
||||||
__pid_re=(?:\[\d+\])
|
|
||||||
__pam_re=\(?pam_unix(?:\(\S+\))?\)?:?
|
__pam_re=\(?pam_unix(?:\(\S+\))?\)?:?
|
||||||
__pam_combs_re=(?:%(__pid_re)s?:\s+%(__pam_re)s|%(__pam_re)s%(__pid_re)s?:)
|
_daemon = \S+
|
||||||
|
|
||||||
# Option: failregex
|
failregex = ^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=%(_ttys_re)s ruser=\S* rhost=<HOST>(?:\s+user=.*)?\s*$
|
||||||
# Notes.: regex to match the password failures messages in the logfile.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = \s\S+ \S+%(__pam_combs_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=%(_ttys_re)s ruser=\S* rhost=<HOST>(?:\s+user=.*)?\s*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
#
|
||||||
|
# for linux-pam before 0.99.2.0 (late 2005) (removed before 0.8.11 release)
|
||||||
|
# _daemon = \S*\(?pam_unix\)?
|
||||||
|
# failregex = ^%(__prefix_line)sauthentication failure; logname=\S* uid=\S* euid=\S* tty=%(_ttys_re)s ruser=\S* rhost=<HOST>(?:\s+user=.*)?\s*$
|
||||||
|
#
|
||||||
|
# Author: Yaroslav Halchenko
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Fail2Ban filter for perdition
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
_daemon=perdition.\S+
|
||||||
|
|
||||||
|
failregex = ^%(__prefix_line)sAuth: <HOST>:\d+->(\d{1,3}\.){3}\d{1,3}:\d+ client-secure=\S+ authorisation_id=NONE authentication_id=".+" server="\S+" protocol=\S+ server-secure=\S+ status="failed: (local authentication failure|Re-Authentication Failure)"$
|
||||||
|
^%(__prefix_line)sFatal Error reading authentication information from client <HOST>:\d+->(\d{1,3}\.){3}\d{1,3}:\d+: Exiting child$
|
||||||
|
|
||||||
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Christophe Carles and Daniel Black
|
|
@ -1,23 +1,20 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for URLs with a URL as a script parameters
|
||||||
|
# which can be an indication of a fopen url php injection
|
||||||
|
#
|
||||||
|
# Example of web requests in Apache access log:
|
||||||
|
# 66.185.212.172 - - [26/Mar/2009:08:44:20 -0500] "GET /index.php?n=http://eatmyfood.hostinginfive.com/pizza.htm? HTTP/1.1" 200 114 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
failregex = ^<HOST> -.*"(GET|POST).*\?.*\=http\:\/\/.* HTTP\/.*$
|
||||||
|
|
||||||
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
#
|
#
|
||||||
# Author: Arturo 'Buanzo' Busleiman <buanzo@buanzo.com.ar>
|
|
||||||
# Version 2
|
# Version 2
|
||||||
# fixes the failregex so REFERERS that contain =http:// don't get blocked
|
# fixes the failregex so REFERERS that contain =http:// don't get blocked
|
||||||
# (mentioned by "fasuto" (no real email provided... blog comment) in this entry:
|
# (mentioned by "fasuto" (no real email provided... blog comment) in this entry:
|
||||||
# http://blogs.buanzo.com.ar/2009/04/fail2ban-filter-for-php-injection-attacks.html#comment-1489
|
# http://blogs.buanzo.com.ar/2009/04/fail2ban-filter-for-php-injection-attacks.html#comment-1489
|
||||||
#
|
#
|
||||||
|
# Author: Arturo 'Buanzo' Busleiman <buanzo@buanzo.com.ar>
|
||||||
[Definition]
|
|
||||||
|
|
||||||
# Option: failregex
|
|
||||||
# Notes.: regex to match this kind of request:
|
|
||||||
#
|
|
||||||
# 66.185.212.172 - - [26/Mar/2009:08:44:20 -0500] "GET /index.php?n=http://eatmyfood.hostinginfive.com/pizza.htm? HTTP/1.1" 200 114 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
|
|
||||||
#
|
|
||||||
failregex = ^<HOST> -.*"(GET|POST).*\?.*\=http\:\/\/.* HTTP\/.*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Fail2Ban filter for postfix authentication failures
|
||||||
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
_daemon = postfix/smtpd
|
||||||
|
|
||||||
|
failregex = ^%(__prefix_line)swarning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?\s*$
|
||||||
|
|
||||||
|
# Author: Yaroslav Halchenko
|
|
@ -1,23 +1,21 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for selected Postfix SMTP rejections
|
||||||
#
|
|
||||||
# Author: Cyril Jaquier
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
# Read common prefixes. If any customizations available -- read them from
|
||||||
|
# common.local
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
_daemon = postfix/smtpd
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
failregex = ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 554 5\.7\.1 .*$
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 450 4\.7\.1 : Helo command rejected: Host not found; from=<> to=<> proto=ESMTP helo= *$
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
^%(__prefix_line)sNOQUEUE: reject: VRFY from \S+\[<HOST>\]: 550 5\.1\.1 .*$
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = reject: RCPT from (.*)\[<HOST>\]: 554
|
|
||||||
reject: RCPT from (.*)\[<HOST>\]: 450 4\.7\.1 : Helo command rejected: Host not found; from=<> to=<> proto=ESMTP helo= *$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Cyril Jaquier
|
||||||
|
|
|
@ -1,25 +1,22 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban fitler for the Proftpd FTP daemon
|
||||||
#
|
|
||||||
# Author: Yaroslav Halchenko
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
_daemon = proftpd
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
__suffix_failed_login = (User not authorized for login|No such user found|Incorrect password|Password expired|Account disabled|Invalid shell: '\S+'|User in \S+|Limit (access|configuration) denies login|Not a UserAlias|maximum login length exceeded).?
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
failregex = ^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ USER .*: no such user found from \S+ \[\S+\] to \S+:\S+ *$
|
||||||
# Values: TEXT
|
^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ USER .* \(Login failed\): %(__suffix_failed_login)s\s*$
|
||||||
#
|
^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ SECURITY VIOLATION: .* login attempted\. *$
|
||||||
failregex = \(\S+\[<HOST>\]\)[: -]+ USER \S+: no such user found from \S+ \[\S+\] to \S+:\S+ *$
|
^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ Maximum login attempts \(\d+\) exceeded *$
|
||||||
\(\S+\[<HOST>\]\)[: -]+ USER \S+ \(Login failed\): .*$
|
|
||||||
\(\S+\[<HOST>\]\)[: -]+ SECURITY VIOLATION: \S+ login attempted\. *$
|
|
||||||
\(\S+\[<HOST>\]\)[: -]+ Maximum login attempts \(\d+\) exceeded *$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Yaroslav Halchenko
|
||||||
|
# Daniel Black - hardening of regex
|
||||||
|
|
|
@ -1,28 +1,19 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for pureftp
|
||||||
#
|
|
||||||
# Author: Cyril Jaquier
|
|
||||||
# Modified: Yaroslav Halchenko for pure-ftpd
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Error message specified in multiple languages
|
# Error message specified in multiple languages
|
||||||
__errmsg = (?:Authentication failed for user|Erreur d'authentification pour l'utilisateur)
|
__errmsg = (?:Authentication failed for user|Erreur d'authentification pour l'utilisateur)
|
||||||
|
|
||||||
#
|
failregex = ^%(__prefix_line)s\(.+?@<HOST>\) \[WARNING\] %(__errmsg)s \[.+\]\s*$
|
||||||
# Option: failregex
|
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = pure-ftpd(?:\[\d+\])?: \(.+?@<HOST>\) \[WARNING\] %(__errmsg)s \[.+\]\s*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Cyril Jaquier
|
||||||
|
# Modified: Yaroslav Halchenko for pure-ftpd
|
||||||
|
|
|
@ -1,22 +1,31 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filters for qmail RBL patches/fake proxies
|
||||||
#
|
#
|
||||||
# Author: Cyril Jaquier
|
# the default djb RBL implementation doesn't log any rejections
|
||||||
|
# so is useless with this filter.
|
||||||
#
|
#
|
||||||
|
# One patch is here:
|
||||||
#
|
#
|
||||||
|
# http://www.tjsi.com/rblsmtpd/faq/ patch to rblsmtpd
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
_daemon = (?:qmail|rblsmtpd)
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = (?:[\d,.]+[\d,.] rblsmtpd: |421 badiprbl: ip )<HOST>
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
failregex = ^%(__prefix_line)s\d+\.\d+ rblsmtpd: <HOST> pid \d+ \S+ 4\d\d \S+\s*$
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
^%(__prefix_line)s\d+\.\d+ qmail-smtpd: 4\d\d badiprbl: ip <HOST> rbl: \S+\s*$
|
||||||
# Values: TEXT
|
^%(__prefix_line)s\S+ blocked <HOST> \S+ -\s*$
|
||||||
|
|
||||||
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
#
|
#
|
||||||
ignoreregex =
|
# These seem to be for two or 3 different patches to qmail or rblsmtpd
|
||||||
|
# so you'll probably only ever see one of these regex's that match.
|
||||||
|
#
|
||||||
|
# ref: https://github.com/fail2ban/fail2ban/pull/386
|
||||||
|
#
|
||||||
|
# Author: Daniel Black
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for repeat bans
|
||||||
#
|
#
|
||||||
# Author: Tom Hendrikx, modifications by Amir Caspi
|
|
||||||
#
|
|
||||||
# This filter monitors the fail2ban log file, and enables you to add long
|
# This filter monitors the fail2ban log file, and enables you to add long
|
||||||
# time bans for ip addresses that get banned by fail2ban multiple times.
|
# time bans for ip addresses that get banned by fail2ban multiple times.
|
||||||
|
#
|
||||||
# Reasons to use this: block very persistent attackers for a longer time,
|
# Reasons to use this: block very persistent attackers for a longer time,
|
||||||
# stop receiving email notifications about the same attacker over and
|
# stop receiving email notifications about the same attacker over and
|
||||||
# over again.
|
# over again.
|
||||||
|
@ -13,26 +12,21 @@
|
||||||
# drawbacks, namely in that it works only with iptables, or if you use a
|
# drawbacks, namely in that it works only with iptables, or if you use a
|
||||||
# different blocking mechanism for this jail versus others (e.g. hostsdeny
|
# different blocking mechanism for this jail versus others (e.g. hostsdeny
|
||||||
# for most jails, and shorewall for this one).
|
# for most jails, and shorewall for this one).
|
||||||
#
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
# Read common prefixes. If any customizations available -- read them from
|
||||||
|
# common.local
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
|
_daemon = fail2ban\.actions
|
||||||
|
|
||||||
# The name of the jail that this filter is used for. In jail.conf, name the
|
# The name of the jail that this filter is used for. In jail.conf, name the
|
||||||
# jail using this filter 'recidive', or change this line!
|
# jail using this filter 'recidive', or change this line!
|
||||||
_jailname = recidive
|
_jailname = recidive
|
||||||
|
|
||||||
# Option: failregex
|
failregex = ^(%(__prefix_line)s|,\d{3} fail2ban.actions:\s+)WARNING\s+\[(?!%(_jailname)s\])(?:.*)\]\s+Ban\s+<HOST>\s*$
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>\S+)
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = fail2ban.actions:\s+WARNING\s+\[(?:.*)\]\s+Ban\s+<HOST>
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
# Author: Tom Hendrikx, modifications by Amir Caspi
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
# Ignore our own bans, to keep our counts exact.
|
|
||||||
ignoreregex = fail2ban.actions:\s+WARNING\s+\[%(_jailname)s\]\s+Ban\s+<HOST>
|
|
||||||
|
|
|
@ -1,22 +1,16 @@
|
||||||
# Fail2Ban configuration file for roundcube web server
|
# Fail2Ban configuration file for roundcube web server
|
||||||
#
|
#
|
||||||
# Author: Teodor Micu & Yaroslav Halchenko & terence namusonge
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
failregex = ^\s*(\[(\s[+-][0-9]{4})?\])?(%(__hostname)s roundcube: IMAP Error)?: (FAILED login|Login failed) for .*? from <HOST>(\. AUTHENTICATE .*)?\s*$
|
||||||
# Notes.: regex to match the password failure messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = (FAILED login|Login failed) for .* from <HOST>\s*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Teodor Micu & Yaroslav Halchenko & terence namusonge
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
# Fail2Ban configuration file
|
|
||||||
#
|
|
||||||
# Author: Yaroslav Halchenko
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
[Definition]
|
|
||||||
|
|
||||||
# Option: failregex
|
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = (?i): warning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?\s*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Fail2Ban configuration file for generic SELinux audit messages
|
||||||
|
#
|
||||||
|
# This file is not intended to be used directly, and should be included into a
|
||||||
|
# filter file which would define following variables. See selinux-ssh.conf as
|
||||||
|
# and example.
|
||||||
|
#
|
||||||
|
# _type
|
||||||
|
# _uid
|
||||||
|
# _auid
|
||||||
|
# _subj
|
||||||
|
# _msg
|
||||||
|
#
|
||||||
|
# Also one of these variables must include <HOST>.
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
failregex = ^type=%(_type)s msg=audit\(:\d+\): (user )?pid=\d+ uid=%(_uid)s auid=%(_auid)s ses=\d+ subj=%(_subj)s msg='%(_msg)s'$
|
||||||
|
|
||||||
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Daniel Black
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Fail2Ban configuration file for SELinux ssh authentication errors
|
||||||
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
after = selinux-common.conf
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
_type = USER_(ERR|AUTH)
|
||||||
|
_uid = 0
|
||||||
|
_auid = \d+
|
||||||
|
_subj = (?:unconfined_u|system_u):system_r:sshd_t:s0-s0:c0\.c1023
|
||||||
|
|
||||||
|
_exe =/usr/sbin/sshd
|
||||||
|
_terminal = ssh
|
||||||
|
|
||||||
|
_msg = op=\S+ acct=(?P<_quote_acct>"?)\S+(?P=_quote_acct) exe="%(_exe)s" hostname=(\?|(\d+\.){3}\d+) addr=<HOST> terminal=%(_terminal)s res=failed
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
#
|
||||||
|
# Note: USER_LOGIN is ignored as this is the duplicate messsage
|
||||||
|
# ssh logs after 3 USER_AUTH failures.
|
||||||
|
#
|
||||||
|
# Author: Daniel Black
|
|
@ -1,21 +1,18 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for sieve authentication failures
|
||||||
#
|
|
||||||
# Author: Jan Wagner <waja@cyconet.org>
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
# Read common prefixes. If any customizations available -- read them from
|
||||||
|
# common.local
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
_deamon = (?:cyrus/)?(?:tim)?sieved?
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
failregex = ^%(__prefix_line)sbadlogin: \S+ ?\[<HOST>\] \S+ authentication failure$
|
||||||
# be used for standard IP/hostname matching.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = : badlogin: .*\[<HOST>\] (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failure$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Jan Wagner <waja@cyconet.org>
|
||||||
|
|
|
@ -1,20 +1,17 @@
|
||||||
# /etc/fail2ban/filter.d/sogo-auth.conf
|
# Fail2ban filter for SOGo authentcation
|
||||||
#
|
|
||||||
# Fail2Ban configuration file
|
|
||||||
# By Arnd Brandes
|
|
||||||
# SOGo
|
|
||||||
#
|
#
|
||||||
|
# Log file usually in /var/log/sogo/sogo.log
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
# Option: failregex
|
|
||||||
# Filter Ban in /var/log/sogo/sogo.log
|
|
||||||
# Note: the error log may contain multiple hosts, whereas the first one
|
|
||||||
# is the client and all others are poxys. We match the first one, only
|
|
||||||
|
|
||||||
failregex = Login from '<HOST>' for user '.*' might not have worked( - password policy: \d* grace: -?\d* expire: -?\d* bound: -?\d*)?\s*$
|
failregex = ^ sogod \[\d+\]: SOGoRootPage Login from '<HOST>' for user '.*' might not have worked( - password policy: \d* grace: -?\d* expire: -?\d* bound: -?\d*)?\s*$
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
#
|
||||||
|
# DEV Notes:
|
||||||
|
#
|
||||||
|
# The error log may contain multiple hosts, whereas the first one
|
||||||
|
# is the client and all others are poxys. We match the first one, only
|
||||||
|
#
|
||||||
|
# Author: Arnd Brandes
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban ssh filter for at attempted exploit
|
||||||
#
|
|
||||||
# Author: Yaroslav Halchenko
|
|
||||||
#
|
#
|
||||||
# The regex here also relates to a exploit:
|
# The regex here also relates to a exploit:
|
||||||
#
|
#
|
||||||
|
@ -20,17 +18,8 @@ before = common.conf
|
||||||
|
|
||||||
_daemon = sshd
|
_daemon = sshd
|
||||||
|
|
||||||
# Option: failregex
|
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = ^%(__prefix_line)sDid not receive identification string from <HOST>\s*$
|
failregex = ^%(__prefix_line)sDid not receive identification string from <HOST>\s*$
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Yaroslav Halchenko
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for openssh
|
||||||
#
|
|
||||||
# Author: Cyril Jaquier
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
|
|
||||||
[INCLUDES]
|
[INCLUDES]
|
||||||
|
@ -15,16 +12,9 @@ before = common.conf
|
||||||
|
|
||||||
_daemon = sshd
|
_daemon = sshd
|
||||||
|
|
||||||
# Option: failregex
|
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from <HOST>( via \S+)?\s*$
|
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from <HOST>( via \S+)?\s*$
|
||||||
^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
|
^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
|
||||||
^%(__prefix_line)sFailed \S+ for .* from <HOST>(?: port \d*)?(?: ssh\d*)?\s*$
|
^%(__prefix_line)sFailed \S+ for .*? from <HOST>(?: port \d*)?(?: ssh\d*)?(: (ruser .*|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".*", client host ".*")?))?\s*$
|
||||||
^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$
|
^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$
|
||||||
^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$
|
^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$
|
||||||
^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$
|
^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$
|
||||||
|
@ -34,8 +24,13 @@ failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|erro
|
||||||
^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$
|
^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$
|
||||||
^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$
|
^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
#
|
||||||
|
# "Failed \S+ for .*? from <HOST>..." failregex uses non-greedy catch-all because
|
||||||
|
# it is coming before use of <HOST> which is not hard-anchored at the end as well,
|
||||||
|
# and later catch-all's could contain user-provided input, which need to be greedily
|
||||||
|
# matched away first.
|
||||||
|
#
|
||||||
|
# Author: Cyril Jaquier, Yaroslav Halchenko, Petr Voralek, Daniel Black
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Fail2Ban filter for suhosian PHP hardening
|
||||||
|
#
|
||||||
|
# This occurs with lighttpd or directly from the plugin
|
||||||
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
# Read common prefixes. If any customizations available -- read them from
|
||||||
|
# common.local
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
_daemon = (?:lighttpd|suhosin)
|
||||||
|
|
||||||
|
|
||||||
|
_lighttpd_prefix = (?:\(mod_fastcgi\.c\.\d+\) FastCGI-stderr:\s)
|
||||||
|
|
||||||
|
failregex = ^%(__prefix_line)s%(_lighttpd_prefix)s?ALERT - .* \(attacker '<HOST>', file '.*'(?:, line \d+)?\)$
|
||||||
|
|
||||||
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
#
|
||||||
|
# https://github.com/stefanesser/suhosin/blob/1fba865ab73cc98a3109f88d85eb82c1bfc29b37/log.c#L161
|
||||||
|
#
|
||||||
|
# Author: Arturo 'Buanzo' Busleiman <buanzo@buanzo.com.ar>
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Fail2Ban filter for uwimap
|
||||||
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
_daemon = (?:ipop3d|imapd)
|
||||||
|
|
||||||
|
failregex = ^%(__prefix_line)sLogin (?:failed|excessive login failures|disabled|SYSTEM BREAK-IN ATTEMPT) user=\S* auth=\S* host=.*\[<HOST>\]\s*$
|
||||||
|
^%(__prefix_line)sFailed .* override of user=.* host=.*\[<HOST>\]\s*$
|
||||||
|
|
||||||
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Amir Caspi
|
|
@ -1,23 +1,18 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for vsftp
|
||||||
#
|
|
||||||
# Author: Cyril Jaquier
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
__pam_re=\(?pam_unix(?:\(\S+\))?\)?:?
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
_daemon = vsftpd
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
failregex = ^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=(ftp)? ruser=\S* rhost=<HOST>(?:\s+user=.*)?\s*$
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
^ \[pid \d+\] \[.+\] FAIL LOGIN: Client "<HOST>"\s*$
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = vsftpd(?:\(pam_unix\))?(?:\[\d+\])?:.* authentication failure; .* rhost=<HOST>(?:\s+user=\S*)?\s*$
|
|
||||||
\[.+\] FAIL LOGIN: Client "<HOST>"\s*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Cyril Jaquier
|
||||||
|
|
|
@ -1,27 +1,22 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for webmin
|
||||||
#
|
|
||||||
# Author: Cyril Jaquier
|
|
||||||
# Rule by : Delvit Guillaume
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# patern : webmin[15673]: Non-existent login as toto from 86.0.6.217
|
_daemon = webmin
|
||||||
|
|
||||||
|
failregex = ^%(__prefix_line)sNon-existent login as .+ from <HOST>\s*$
|
||||||
|
^%(__prefix_line)sInvalid login as .+ from <HOST>\s*$
|
||||||
|
|
||||||
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
#
|
||||||
|
# pattern : webmin[15673]: Non-existent login as toto from 86.0.6.217
|
||||||
# webmin[29544]: Invalid login as root from 86.0.6.217
|
# webmin[29544]: Invalid login as root from 86.0.6.217
|
||||||
#
|
#
|
||||||
# Option: failregex
|
# Rule Author: Delvit Guillaume
|
||||||
# Notes.: regex to match the password failure messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
failregex = webmin.* Non-existent login as .+ from <HOST>\s*$
|
|
||||||
webmin.* Invalid login as .+ from <HOST>\s*$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
# Fail2Ban configuration file for wuftpd
|
# Fail2Ban configuration file for wuftpd
|
||||||
#
|
#
|
||||||
# Author: Yaroslav Halchenko
|
|
||||||
#
|
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
# Read common prefixes. If any customizations available -- read them from
|
||||||
|
# common.local
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
_daemon = wu-ftpd
|
||||||
# Notes.: regex to match the password failures messages in the logfile.
|
__pam_re=\(?pam_unix(?:\(wu-ftpd:auth\))?\)?:?
|
||||||
# Values: TEXT
|
|
||||||
#
|
failregex = ^%(__prefix_line)sfailed login from \S+ \[<HOST>\]\s*$
|
||||||
failregex = wu-ftpd(?:\[\d+\])?:\s+\(pam_unix\)\s+authentication failure.* rhost=<HOST>$
|
^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=(ftp)? ruser=\S* rhost=<HOST>(?:\s+user=.*)?\s*$
|
||||||
wu-ftpd(?:\[\d+\])?: *failed login from .*\[<HOST>\] *$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
ignoreregex =
|
||||||
|
|
||||||
|
# Author: Yaroslav Halchenko
|
||||||
|
|
|
@ -1,29 +1,27 @@
|
||||||
# Fail2Ban configuration file
|
# Fail2Ban filter for xinetd failures
|
||||||
#
|
#
|
||||||
# Author: Guido Bozzetto
|
# Cfr.: /var/log/(daemon\.|sys)log
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
|
[INCLUDES]
|
||||||
|
|
||||||
|
# Read common prefixes. If any customizations available -- read them from
|
||||||
|
# common.local
|
||||||
|
before = common.conf
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
|
|
||||||
# Option: failregex
|
_daemon = xinetd
|
||||||
# Notes.: regex to match the password failures messages in the logfile. The
|
|
||||||
# host must be matched by a group named "host". The tag "<HOST>" can
|
failregex = ^%(__prefix_line)sFAIL: \S+ address from=<HOST>$
|
||||||
# be used for standard IP/hostname matching and is only an alias for
|
^%(__prefix_line)sFAIL: \S+ libwrap from=<HOST>$
|
||||||
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
|
|
||||||
# Values: TEXT
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
#
|
#
|
||||||
# Cfr.: /var/log/(daemon\.|sys)log
|
|
||||||
# libwrap => tcp wrappers: hosts.(allow|deny)
|
# libwrap => tcp wrappers: hosts.(allow|deny)
|
||||||
# address => xinetd: deny_from|only_from
|
# address => xinetd: deny_from|only_from
|
||||||
# load => xinetd: max_load (temporary problem)
|
|
||||||
#
|
#
|
||||||
|
# Author: Guido Bozzetto
|
||||||
failregex = xinetd(?:\[\d{1,5}\])?: FAIL: \S+ address from=<HOST>$
|
|
||||||
xinetd(?:\[\d{1,5}\])?: FAIL: \S+ libwrap from=<HOST>$
|
|
||||||
|
|
||||||
# Option: ignoreregex
|
|
||||||
# Notes.: regex to ignore. If this regex matches, the line is ignored.
|
|
||||||
# Values: TEXT
|
|
||||||
#
|
|
||||||
ignoreregex =
|
|
||||||
|
|
280
config/jail.conf
280
config/jail.conf
|
@ -1,16 +1,25 @@
|
||||||
# Fail2Ban jail specifications file
|
# Fail2Ban jail base specification file
|
||||||
#
|
#
|
||||||
# Comments: use '#' for comment lines and ';' (following a space) for inline comments
|
# HOW TO ACTIVATE JAILS:
|
||||||
#
|
#
|
||||||
# Changes: in most of the cases you should not modify this
|
# YOU SHOULD NOT MODIFY THIS FILE.
|
||||||
# file, but provide customizations in jail.local file, e.g.:
|
#
|
||||||
|
# It will probably be overwitten or improved in a distribution update.
|
||||||
|
#
|
||||||
|
# Provide customizations in a jail.local file or a jail.d/customisation.local.
|
||||||
|
# For example to change the default bantime for all jails and to enable the
|
||||||
|
# ssh-iptables jail the following (uncommented) would appear in the .local file.
|
||||||
|
# See man 5 jail.conf for details.
|
||||||
#
|
#
|
||||||
# [DEFAULT]
|
# [DEFAULT]
|
||||||
# bantime = 3600
|
# bantime = 3600
|
||||||
#
|
#
|
||||||
# [ssh-iptables]
|
# [ssh-iptables]
|
||||||
# enabled = true
|
# enabled = true
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
|
# Comments: use '#' for comment lines and ';' (following a space) for inline comments
|
||||||
|
|
||||||
# The DEFAULT allows a global definition of the options. They can be overridden
|
# The DEFAULT allows a global definition of the options. They can be overridden
|
||||||
# in each jail afterwards.
|
# in each jail afterwards.
|
||||||
|
@ -56,7 +65,7 @@ backend = auto
|
||||||
usedns = warn
|
usedns = warn
|
||||||
|
|
||||||
|
|
||||||
# This jail corresponds to the standard configuration in Fail2ban 0.6.
|
# This jail corresponds to the standard configuration in Fail2ban.
|
||||||
# The mail-whois action send a notification e-mail with a whois request
|
# The mail-whois action send a notification e-mail with a whois request
|
||||||
# in the body.
|
# in the body.
|
||||||
|
|
||||||
|
@ -65,7 +74,7 @@ usedns = warn
|
||||||
enabled = false
|
enabled = false
|
||||||
filter = sshd
|
filter = sshd
|
||||||
action = iptables[name=SSH, port=ssh, protocol=tcp]
|
action = iptables[name=SSH, port=ssh, protocol=tcp]
|
||||||
sendmail-whois[name=SSH, dest=you@example.com, sender=fail2ban@example.com]
|
sendmail-whois[name=SSH, dest=you@example.com, sender=fail2ban@example.com, sendername="Fail2Ban"]
|
||||||
logpath = /var/log/sshd.log
|
logpath = /var/log/sshd.log
|
||||||
maxretry = 5
|
maxretry = 5
|
||||||
|
|
||||||
|
@ -78,47 +87,50 @@ action = iptables[name=ProFTPD, port=ftp, protocol=tcp]
|
||||||
logpath = /var/log/proftpd/proftpd.log
|
logpath = /var/log/proftpd/proftpd.log
|
||||||
maxretry = 6
|
maxretry = 6
|
||||||
|
|
||||||
# This jail forces the backend to "polling".
|
|
||||||
|
|
||||||
|
# This jail forces the backend to "polling".
|
||||||
[sasl-iptables]
|
[sasl-iptables]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
filter = sasl
|
filter = postfix-sasl
|
||||||
backend = polling
|
backend = polling
|
||||||
action = iptables[name=sasl, port=smtp, protocol=tcp]
|
action = iptables[name=sasl, port=smtp, protocol=tcp]
|
||||||
sendmail-whois[name=sasl, dest=you@example.com]
|
sendmail-whois[name=sasl, dest=you@example.com]
|
||||||
logpath = /var/log/mail.log
|
logpath = /var/log/mail.log
|
||||||
|
|
||||||
|
|
||||||
# ASSP SMTP Proxy Jail
|
# ASSP SMTP Proxy Jail
|
||||||
[assp]
|
[assp]
|
||||||
enabled = false
|
|
||||||
filter = assp
|
enabled = false
|
||||||
action = iptables-multiport[name=assp,port="25,465,587"]
|
filter = assp
|
||||||
logpath = /root/path/to/assp/logs/maillog.txt
|
action = iptables-multiport[name=assp,port="25,465,587"]
|
||||||
|
logpath = /root/path/to/assp/logs/maillog.txt
|
||||||
|
|
||||||
|
|
||||||
# Here we use TCP-Wrappers instead of Netfilter/Iptables. "ignoreregex" is
|
# Here we use TCP-Wrappers instead of Netfilter/Iptables. "ignoreregex" is
|
||||||
# used to avoid banning the user "myuser".
|
# used to avoid banning the user "myuser".
|
||||||
|
|
||||||
[ssh-tcpwrapper]
|
[ssh-tcpwrapper]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
filter = sshd
|
filter = sshd
|
||||||
action = hostsdeny
|
action = hostsdeny[daemon_list=sshd]
|
||||||
sendmail-whois[name=SSH, dest=you@example.com]
|
sendmail-whois[name=SSH, dest=you@example.com]
|
||||||
ignoreregex = for myuser from
|
ignoreregex = for myuser from
|
||||||
logpath = /var/log/sshd.log
|
logpath = /var/log/sshd.log
|
||||||
|
|
||||||
|
|
||||||
# Here we use blackhole routes for not requiring any additional kernel support
|
# Here we use blackhole routes for not requiring any additional kernel support
|
||||||
# to store large volumes of banned IPs
|
# to store large volumes of banned IPs
|
||||||
|
|
||||||
[ssh-route]
|
[ssh-route]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
filter = sshd
|
filter = sshd
|
||||||
action = route
|
action = route
|
||||||
logpath = /var/log/sshd.log
|
logpath = /var/log/sshd.log
|
||||||
maxretry = 5
|
maxretry = 5
|
||||||
|
|
||||||
|
|
||||||
# Here we use a combination of Netfilter/Iptables and IPsets
|
# Here we use a combination of Netfilter/Iptables and IPsets
|
||||||
# for storing large volumes of banned IPs
|
# for storing large volumes of banned IPs
|
||||||
#
|
#
|
||||||
|
@ -132,13 +144,16 @@ action = iptables-ipset-proto4[name=SSH, port=ssh, protocol=tcp]
|
||||||
logpath = /var/log/sshd.log
|
logpath = /var/log/sshd.log
|
||||||
maxretry = 5
|
maxretry = 5
|
||||||
|
|
||||||
|
|
||||||
[ssh-iptables-ipset6]
|
[ssh-iptables-ipset6]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
filter = sshd
|
filter = sshd
|
||||||
action = iptables-ipset-proto6[name=SSH, port=ssh, protocol=tcp, bantime=600]
|
action = iptables-ipset-proto6[name=SSH, port=ssh, protocol=tcp, bantime=600]
|
||||||
logpath = /var/log/sshd.log
|
logpath = /var/log/sshd.log
|
||||||
maxretry = 5
|
maxretry = 5
|
||||||
|
|
||||||
|
|
||||||
# bsd-ipfw is ipfw used by BSD. It uses ipfw tables.
|
# bsd-ipfw is ipfw used by BSD. It uses ipfw tables.
|
||||||
# table number must be unique.
|
# table number must be unique.
|
||||||
#
|
#
|
||||||
|
@ -146,15 +161,16 @@ maxretry = 5
|
||||||
# for the table doesn't ready exist.
|
# for the table doesn't ready exist.
|
||||||
#
|
#
|
||||||
[ssh-bsd-ipfw]
|
[ssh-bsd-ipfw]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
filter = sshd
|
filter = sshd
|
||||||
action = bsd-ipfw[port=ssh,table=1]
|
action = bsd-ipfw[port=ssh,table=1]
|
||||||
logpath = /var/log/auth.log
|
logpath = /var/log/auth.log
|
||||||
maxretry = 5
|
maxretry = 5
|
||||||
|
|
||||||
|
|
||||||
# This jail demonstrates the use of wildcards in "logpath".
|
# This jail demonstrates the use of wildcards in "logpath".
|
||||||
# Moreover, it is possible to give other files on a new line.
|
# Moreover, it is possible to give other files on a new line.
|
||||||
|
|
||||||
[apache-tcpwrapper]
|
[apache-tcpwrapper]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -164,9 +180,17 @@ logpath = /var/log/apache*/*error.log
|
||||||
/home/www/myhomepage/error.log
|
/home/www/myhomepage/error.log
|
||||||
maxretry = 6
|
maxretry = 6
|
||||||
|
|
||||||
|
|
||||||
|
[nginx-http-auth]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = nginx-http-auth
|
||||||
|
action = iptables-multiport[name=nginx-http-auth,port="80,443"]
|
||||||
|
logpath = /var/log/nginx/error.log
|
||||||
|
|
||||||
|
|
||||||
# The hosts.deny path can be defined with the "file" argument if it is
|
# The hosts.deny path can be defined with the "file" argument if it is
|
||||||
# not in /etc.
|
# not in /etc.
|
||||||
|
|
||||||
[postfix-tcpwrapper]
|
[postfix-tcpwrapper]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -176,9 +200,9 @@ action = hostsdeny[file=/not/a/standard/path/hosts.deny]
|
||||||
logpath = /var/log/postfix.log
|
logpath = /var/log/postfix.log
|
||||||
bantime = 300
|
bantime = 300
|
||||||
|
|
||||||
|
|
||||||
# Do not ban anybody. Just report information about the remote host.
|
# Do not ban anybody. Just report information about the remote host.
|
||||||
# A notification is sent at most every 600 seconds (bantime).
|
# A notification is sent at most every 600 seconds (bantime).
|
||||||
|
|
||||||
[vsftpd-notification]
|
[vsftpd-notification]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -188,8 +212,8 @@ logpath = /var/log/vsftpd.log
|
||||||
maxretry = 5
|
maxretry = 5
|
||||||
bantime = 1800
|
bantime = 1800
|
||||||
|
|
||||||
# Same as above but with banning the IP address.
|
|
||||||
|
|
||||||
|
# Same as above but with banning the IP address.
|
||||||
[vsftpd-iptables]
|
[vsftpd-iptables]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -200,9 +224,9 @@ logpath = /var/log/vsftpd.log
|
||||||
maxretry = 5
|
maxretry = 5
|
||||||
bantime = 1800
|
bantime = 1800
|
||||||
|
|
||||||
|
|
||||||
# Ban hosts which agent identifies spammer robots crawling the web
|
# Ban hosts which agent identifies spammer robots crawling the web
|
||||||
# for email addresses. The mail outputs are buffered.
|
# for email addresses. The mail outputs are buffered.
|
||||||
|
|
||||||
[apache-badbots]
|
[apache-badbots]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -213,8 +237,8 @@ logpath = /var/www/*/logs/access_log
|
||||||
bantime = 172800
|
bantime = 172800
|
||||||
maxretry = 1
|
maxretry = 1
|
||||||
|
|
||||||
# Use shorewall instead of iptables.
|
|
||||||
|
|
||||||
|
# Use shorewall instead of iptables.
|
||||||
[apache-shorewall]
|
[apache-shorewall]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -223,72 +247,63 @@ action = shorewall
|
||||||
sendmail[name=Postfix, dest=you@example.com]
|
sendmail[name=Postfix, dest=you@example.com]
|
||||||
logpath = /var/log/apache2/error_log
|
logpath = /var/log/apache2/error_log
|
||||||
|
|
||||||
# Monitor roundcube server
|
|
||||||
|
|
||||||
|
# Monitor roundcube server
|
||||||
[roundcube-iptables]
|
[roundcube-iptables]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
filter = roundcube-auth
|
filter = roundcube-auth
|
||||||
action = iptables[name=RoundCube, port="http,https"]
|
action = iptables-multiport[name=RoundCube, port="http,https"]
|
||||||
logpath = /var/log/roundcube/userlogins
|
logpath = /var/log/roundcube/userlogins
|
||||||
|
|
||||||
|
|
||||||
# Monitor SOGo groupware server
|
# Monitor SOGo groupware server
|
||||||
|
|
||||||
[sogo-iptables]
|
[sogo-iptables]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
filter = sogo-auth
|
filter = sogo-auth
|
||||||
# without proxy this would be:
|
# without proxy this would be:
|
||||||
# port = 20000
|
# port = 20000
|
||||||
action = iptables[name=SOGo, port="http,https"]
|
action = iptables-multiport[name=SOGo, port="http,https"]
|
||||||
logpath = /var/log/sogo/sogo.log
|
logpath = /var/log/sogo/sogo.log
|
||||||
|
|
||||||
|
|
||||||
# Ban attackers that try to use PHP's URL-fopen() functionality
|
# Ban attackers that try to use PHP's URL-fopen() functionality
|
||||||
# through GET/POST variables. - Experimental, with more than a year
|
# through GET/POST variables. - Experimental, with more than a year
|
||||||
# of usage in production environments.
|
# of usage in production environments.
|
||||||
|
|
||||||
[php-url-fopen]
|
[php-url-fopen]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
action = iptables[name=php-url-open, port="http,https"]
|
action = iptables-multiport[name=php-url-open, port="http,https"]
|
||||||
filter = php-url-fopen
|
filter = php-url-fopen
|
||||||
logpath = /var/www/*/logs/access_log
|
logpath = /var/www/*/logs/access_log
|
||||||
maxretry = 1
|
maxretry = 1
|
||||||
|
|
||||||
# A simple PHP-fastcgi jail which works with lighttpd.
|
|
||||||
# If you run a lighttpd server, then you probably will
|
|
||||||
# find these kinds of messages in your error_log:
|
|
||||||
# ALERT – tried to register forbidden variable ‘GLOBALS’
|
|
||||||
# through GET variables (attacker '1.2.3.4', file '/var/www/default/htdocs/index.php')
|
|
||||||
# This jail would block the IP 1.2.3.4.
|
|
||||||
|
|
||||||
[lighttpd-fastcgi]
|
[suhosin]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
filter = lighttpd-fastcgi
|
filter = suhosin
|
||||||
action = iptables[name=lighttpd-fastcgi, port="http,https"]
|
action = iptables-multiport[name=suhosin, port="http,https"]
|
||||||
# adapt the following two items as needed
|
# adapt the following two items as needed
|
||||||
logpath = /var/log/lighttpd/error.log
|
logpath = /var/log/lighttpd/error.log
|
||||||
maxretry = 2
|
maxretry = 2
|
||||||
|
|
||||||
# Same as above for mod_auth
|
|
||||||
# It catches wrong authentications
|
|
||||||
|
|
||||||
[lighttpd-auth]
|
[lighttpd-auth]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
filter = lighttpd-auth
|
filter = lighttpd-auth
|
||||||
action = iptables[name=lighttpd-auth, port="http,https"]
|
action = iptables-multiport[name=lighttpd-auth, port="http,https"]
|
||||||
# adapt the following two items as needed
|
# adapt the following two items as needed
|
||||||
logpath = /var/log/lighttpd/error.log
|
logpath = /var/log/lighttpd/error.log
|
||||||
maxretry = 2
|
maxretry = 2
|
||||||
|
|
||||||
|
|
||||||
# This jail uses ipfw, the standard firewall on FreeBSD. The "ignoreip"
|
# This jail uses ipfw, the standard firewall on FreeBSD. The "ignoreip"
|
||||||
# option is overridden in this jail. Moreover, the action "mail-whois" defines
|
# option is overridden in this jail. Moreover, the action "mail-whois" defines
|
||||||
# the variable "name" which contains a comma using "". The characters '' are
|
# the variable "name" which contains a comma using "". The characters '' are
|
||||||
# valid too.
|
# valid too.
|
||||||
|
|
||||||
[ssh-ipfw]
|
[ssh-ipfw]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -298,22 +313,6 @@ action = ipfw[localhost=192.168.0.1]
|
||||||
logpath = /var/log/auth.log
|
logpath = /var/log/auth.log
|
||||||
ignoreip = 168.192.0.1
|
ignoreip = 168.192.0.1
|
||||||
|
|
||||||
# These jails block attacks against named (bind9). By default, logging is off
|
|
||||||
# with bind9 installation. You will need something like this:
|
|
||||||
#
|
|
||||||
# logging {
|
|
||||||
# channel security_file {
|
|
||||||
# file "/var/log/named/security.log" versions 3 size 30m;
|
|
||||||
# severity dynamic;
|
|
||||||
# print-time yes;
|
|
||||||
# };
|
|
||||||
# category security {
|
|
||||||
# security_file;
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# in your named.conf to provide proper logging.
|
|
||||||
# This jail blocks UDP traffic for DNS requests.
|
|
||||||
|
|
||||||
# !!! WARNING !!!
|
# !!! WARNING !!!
|
||||||
# Since UDP is connection-less protocol, spoofing of IP and imitation
|
# Since UDP is connection-less protocol, spoofing of IP and imitation
|
||||||
|
@ -323,6 +322,8 @@ ignoreip = 168.192.0.1
|
||||||
# http://nion.modprobe.de/blog/archives/690-fail2ban-+-dns-fail.html
|
# http://nion.modprobe.de/blog/archives/690-fail2ban-+-dns-fail.html
|
||||||
# Please DO NOT USE this jail unless you know what you are doing.
|
# Please DO NOT USE this jail unless you know what you are doing.
|
||||||
#
|
#
|
||||||
|
# IMPORTANT: see filter.d/named-refused for instructions to enable logging
|
||||||
|
# This jail blocks UDP traffic for DNS requests.
|
||||||
# [named-refused-udp]
|
# [named-refused-udp]
|
||||||
#
|
#
|
||||||
# enabled = false
|
# enabled = false
|
||||||
|
@ -332,8 +333,8 @@ ignoreip = 168.192.0.1
|
||||||
# logpath = /var/log/named/security.log
|
# logpath = /var/log/named/security.log
|
||||||
# ignoreip = 168.192.0.1
|
# ignoreip = 168.192.0.1
|
||||||
|
|
||||||
|
# IMPORTANT: see filter.d/named-refused for instructions to enable logging
|
||||||
# This jail blocks TCP traffic for DNS requests.
|
# This jail blocks TCP traffic for DNS requests.
|
||||||
|
|
||||||
[named-refused-tcp]
|
[named-refused-tcp]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -343,8 +344,19 @@ action = iptables-multiport[name=Named, port="domain,953", protocol=tcp]
|
||||||
logpath = /var/log/named/security.log
|
logpath = /var/log/named/security.log
|
||||||
ignoreip = 168.192.0.1
|
ignoreip = 168.192.0.1
|
||||||
|
|
||||||
# Multiple jails, 1 per protocol, are necessary ATM:
|
|
||||||
# see https://github.com/fail2ban/fail2ban/issues/37
|
[asterisk]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = asterisk
|
||||||
|
action = iptables-multiport[name=asterisk-tcp, port="5060,5061", protocol=tcp]
|
||||||
|
iptables-multiport[name=asterisk-udp, port="5060,5061", protocol=udp]
|
||||||
|
sendmail-whois[name=Asterisk, dest=you@example.com, sender=fail2ban@example.com]
|
||||||
|
logpath = /var/log/asterisk/messages
|
||||||
|
maxretry = 10
|
||||||
|
|
||||||
|
# Historical support (before https://github.com/fail2ban/fail2ban/issues/37 was fixed )
|
||||||
|
# use [asterisk] for new jails
|
||||||
[asterisk-tcp]
|
[asterisk-tcp]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -354,6 +366,9 @@ action = iptables-multiport[name=asterisk-tcp, port="5060,5061", protocol=tcp]
|
||||||
logpath = /var/log/asterisk/messages
|
logpath = /var/log/asterisk/messages
|
||||||
maxretry = 10
|
maxretry = 10
|
||||||
|
|
||||||
|
|
||||||
|
# Historical support (before https://github.com/fail2ban/fail2ban/issues/37 was fixed )
|
||||||
|
# use [asterisk] for new jails
|
||||||
[asterisk-udp]
|
[asterisk-udp]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -363,9 +378,7 @@ action = iptables-multiport[name=asterisk-udp, port="5060,5061", protocol=udp]
|
||||||
logpath = /var/log/asterisk/messages
|
logpath = /var/log/asterisk/messages
|
||||||
maxretry = 10
|
maxretry = 10
|
||||||
|
|
||||||
# To log wrong MySQL access attempts add to /etc/my.cnf:
|
|
||||||
# log-error=/var/log/mysqld.log
|
|
||||||
# log-warning = 2
|
|
||||||
[mysqld-iptables]
|
[mysqld-iptables]
|
||||||
|
|
||||||
enabled = false
|
enabled = false
|
||||||
|
@ -376,6 +389,15 @@ logpath = /var/log/mysqld.log
|
||||||
maxretry = 5
|
maxretry = 5
|
||||||
|
|
||||||
|
|
||||||
|
[mysqld-syslog-iptables]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = mysqld-auth
|
||||||
|
action = iptables[name=mysql, port=3306, protocol=tcp]
|
||||||
|
logpath = /var/log/daemon.log
|
||||||
|
maxretry = 5
|
||||||
|
|
||||||
|
|
||||||
# Jail for more extended banning of persistent abusers
|
# Jail for more extended banning of persistent abusers
|
||||||
# !!! WARNING !!!
|
# !!! WARNING !!!
|
||||||
# Make sure that your loglevel specified in fail2ban.conf/.local
|
# Make sure that your loglevel specified in fail2ban.conf/.local
|
||||||
|
@ -392,13 +414,113 @@ bantime = 604800 ; 1 week
|
||||||
findtime = 86400 ; 1 day
|
findtime = 86400 ; 1 day
|
||||||
maxretry = 5
|
maxretry = 5
|
||||||
|
|
||||||
|
|
||||||
# PF is a BSD based firewall
|
# PF is a BSD based firewall
|
||||||
[ssh-pf]
|
[ssh-pf]
|
||||||
|
|
||||||
enabled=false
|
enabled = false
|
||||||
filter = sshd
|
filter = sshd
|
||||||
action = pf
|
action = pf
|
||||||
logpath = /var/log/sshd.log
|
logpath = /var/log/sshd.log
|
||||||
maxretry=5
|
maxretry = 5
|
||||||
|
|
||||||
|
|
||||||
|
[3proxy]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = 3proxy
|
||||||
|
action = iptables[name=3proxy, port=3128, protocol=tcp]
|
||||||
|
logpath = /var/log/3proxy.log
|
||||||
|
|
||||||
|
|
||||||
|
[exim]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = exim
|
||||||
|
action = iptables-multiport[name=exim,port="25,465,587"]
|
||||||
|
logpath = /var/log/exim/mainlog
|
||||||
|
|
||||||
|
|
||||||
|
[exim-spam]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = exim-spam
|
||||||
|
action = iptables-multiport[name=exim-spam,port="25,465,587"]
|
||||||
|
logpath = /var/log/exim/mainlog
|
||||||
|
|
||||||
|
|
||||||
|
[perdition]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = perdition
|
||||||
|
action = iptables-multiport[name=perdition,port="110,143,993,995"]
|
||||||
|
logpath = /var/log/maillog
|
||||||
|
|
||||||
|
|
||||||
|
[uwimap-auth]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = uwimap-auth
|
||||||
|
action = iptables-multiport[name=uwimap-auth,port="110,143,993,995"]
|
||||||
|
logpath = /var/log/maillog
|
||||||
|
|
||||||
|
|
||||||
|
[osx-ssh-ipfw]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = sshd
|
||||||
|
action = osx-ipfw
|
||||||
|
logpath = /var/log/secure.log
|
||||||
|
maxretry = 5
|
||||||
|
|
||||||
|
|
||||||
|
[ssh-apf]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = sshd
|
||||||
|
action = apf[name=SSH]
|
||||||
|
logpath = /var/log/secure
|
||||||
|
maxretry = 5
|
||||||
|
|
||||||
|
|
||||||
|
[osx-ssh-afctl]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = sshd
|
||||||
|
action = osx-afctl[bantime=600]
|
||||||
|
logpath = /var/log/secure.log
|
||||||
|
maxretry = 5
|
||||||
|
|
||||||
|
|
||||||
|
[webmin-auth]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = webmin-auth
|
||||||
|
action = iptables-multiport[name=webmin,port="10000"]
|
||||||
|
logpath = /var/log/auth.log
|
||||||
|
|
||||||
|
|
||||||
|
# dovecot defaults to logging to the mail syslog facility
|
||||||
|
# but can be set by syslog_facility in the dovecot configuration.
|
||||||
|
[dovecot]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = dovecot
|
||||||
|
action = iptables-multiport[name=dovecot, port="pop3,pop3s,imap,imaps,submission,smtps,sieve", protocol=tcp]
|
||||||
|
logpath = /var/log/mail.log
|
||||||
|
|
||||||
|
|
||||||
|
[dovecot-auth]
|
||||||
|
|
||||||
|
enabled = false
|
||||||
|
filter = dovecot
|
||||||
|
action = iptables-multiport[name=dovecot-auth, port="pop3,pop3s,imap,imaps,submission,smtps,sieve", protocol=tcp]
|
||||||
|
logpath = /var/log/secure
|
||||||
|
|
||||||
|
|
||||||
|
[selinux-ssh]
|
||||||
|
enabled = false
|
||||||
|
filter = selinux-ssh
|
||||||
|
action = iptables[name=SELINUX-SSH, port=ssh, protocol=tcp]
|
||||||
|
logpath = /var/log/audit/audit.log
|
||||||
|
maxretry = 5
|
||||||
|
|
|
@ -155,8 +155,9 @@ class Fail2banClient:
|
||||||
if showRet:
|
if showRet:
|
||||||
print beautifier.beautify(ret[1])
|
print beautifier.beautify(ret[1])
|
||||||
else:
|
else:
|
||||||
logSys.debug("NOK: " + `ret[1].args`)
|
logSys.error("NOK: " + `ret[1].args`)
|
||||||
print beautifier.beautifyError(ret[1])
|
if showRet:
|
||||||
|
print beautifier.beautifyError(ret[1])
|
||||||
return False
|
return False
|
||||||
except socket.error:
|
except socket.error:
|
||||||
if showRet:
|
if showRet:
|
||||||
|
@ -229,7 +230,7 @@ class Fail2banClient:
|
||||||
elif len(cmd) == 2 and cmd[0] == "reload":
|
elif len(cmd) == 2 and cmd[0] == "reload":
|
||||||
if self.__ping():
|
if self.__ping():
|
||||||
jail = cmd[1]
|
jail = cmd[1]
|
||||||
ret = self.__readJailConfig(jail)
|
ret = self.__readConfig(jail)
|
||||||
# Do not continue if configuration is not 100% valid
|
# Do not continue if configuration is not 100% valid
|
||||||
if not ret:
|
if not ret:
|
||||||
return False
|
return False
|
||||||
|
@ -336,13 +337,13 @@ class Fail2banClient:
|
||||||
logSys.setLevel(logging.INFO)
|
logSys.setLevel(logging.INFO)
|
||||||
else:
|
else:
|
||||||
logSys.setLevel(logging.DEBUG)
|
logSys.setLevel(logging.DEBUG)
|
||||||
# Add the default logging handler
|
# Add the default logging handler to dump to stderr
|
||||||
stdout = logging.StreamHandler(sys.stdout)
|
logout = logging.StreamHandler(sys.stderr)
|
||||||
# set a format which is simpler for console use
|
# set a format which is simpler for console use
|
||||||
formatter = logging.Formatter('%(levelname)-6s %(message)s')
|
formatter = logging.Formatter('%(levelname)-6s %(message)s')
|
||||||
# tell the handler to use this format
|
# tell the handler to use this format
|
||||||
stdout.setFormatter(formatter)
|
logout.setFormatter(formatter)
|
||||||
logSys.addHandler(stdout)
|
logSys.addHandler(logout)
|
||||||
|
|
||||||
# Set the configuration path
|
# Set the configuration path
|
||||||
self.__configurator.setBaseDir(self.__conf["conf"])
|
self.__configurator.setBaseDir(self.__conf["conf"])
|
||||||
|
@ -383,7 +384,10 @@ class Fail2banClient:
|
||||||
if cmd == "help":
|
if cmd == "help":
|
||||||
self.dispUsage()
|
self.dispUsage()
|
||||||
elif not cmd == "":
|
elif not cmd == "":
|
||||||
self.__processCommand(shlex.split(cmd))
|
try:
|
||||||
|
self.__processCommand(shlex.split(cmd))
|
||||||
|
except Exception, e:
|
||||||
|
logSys.error(e)
|
||||||
except (EOFError, KeyboardInterrupt):
|
except (EOFError, KeyboardInterrupt):
|
||||||
print
|
print
|
||||||
return True
|
return True
|
||||||
|
@ -394,19 +398,18 @@ class Fail2banClient:
|
||||||
return False
|
return False
|
||||||
return self.__processCommand(args)
|
return self.__processCommand(args)
|
||||||
|
|
||||||
def __readConfig(self):
|
def __readConfig(self, jail=None):
|
||||||
# Read the configuration
|
# Read the configuration
|
||||||
self.__configurator.readAll()
|
# TODO: get away from stew of return codes and exception
|
||||||
ret = self.__configurator.getOptions()
|
# handling -- handle via exceptions
|
||||||
self.__configurator.convertToProtocol()
|
try:
|
||||||
self.__stream = self.__configurator.getConfigStream()
|
self.__configurator.readAll()
|
||||||
return ret
|
ret = self.__configurator.getOptions(jail)
|
||||||
|
self.__configurator.convertToProtocol()
|
||||||
def __readJailConfig(self, jail):
|
self.__stream = self.__configurator.getConfigStream()
|
||||||
self.__configurator.readAll()
|
except Exception, e:
|
||||||
ret = self.__configurator.getOptions(jail)
|
logSys.error("Failed during configuration: %s" % e)
|
||||||
self.__configurator.convertToProtocol()
|
ret = False
|
||||||
self.__stream = self.__configurator.getConfigStream()
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
#@staticmethod
|
#@staticmethod
|
||||||
|
|
577
fail2ban-regex
577
fail2ban-regex
|
@ -17,12 +17,19 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Fail2Ban; if not, write to the Free Software
|
# along with Fail2Ban; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
"""
|
||||||
|
Fail2Ban reads log file that contains password failure report
|
||||||
|
and bans the corresponding IP addresses using firewall rules.
|
||||||
|
|
||||||
|
This tools can test regular expressions for "fail2ban".
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
__author__ = "Cyril Jaquier, Yaroslav Halchenko"
|
__author__ = "Cyril Jaquier, Yaroslav Halchenko"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2012 Yaroslav Halchenko"
|
__copyright__ = "Copyright (c) 2004-2008 Cyril Jaquier, 2012-2013 Yaroslav Halchenko"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
import getopt, sys, time, logging, os
|
import getopt, sys, time, logging, os, urllib
|
||||||
|
|
||||||
# Inserts our own modules path first in the list
|
# Inserts our own modules path first in the list
|
||||||
# fix for bug #343821
|
# fix for bug #343821
|
||||||
|
@ -32,231 +39,283 @@ except ImportError, e:
|
||||||
sys.path.insert(1, "/usr/share/fail2ban")
|
sys.path.insert(1, "/usr/share/fail2ban")
|
||||||
from common.version import version
|
from common.version import version
|
||||||
|
|
||||||
|
from optparse import OptionParser, Option
|
||||||
|
|
||||||
from client.configparserinc import SafeConfigParserWithIncludes
|
from client.configparserinc import SafeConfigParserWithIncludes
|
||||||
from ConfigParser import NoOptionError, NoSectionError, MissingSectionHeaderError
|
from ConfigParser import NoOptionError, NoSectionError, MissingSectionHeaderError
|
||||||
from server.filter import Filter
|
from server.filter import Filter
|
||||||
from server.failregex import RegexException
|
from server.failregex import RegexException
|
||||||
|
|
||||||
|
from testcases.utils import FormatterWithTraceBack
|
||||||
# Gets the instance of the logger.
|
# Gets the instance of the logger.
|
||||||
logSys = logging.getLogger("fail2ban.regex")
|
logSys = logging.getLogger("fail2ban")
|
||||||
|
|
||||||
class RegexStat:
|
def debuggexURL(sample, regex):
|
||||||
|
q = urllib.urlencode({ 're': regex.replace('<HOST>', '(?&.ipv4)'),
|
||||||
|
'str': sample,
|
||||||
|
'flavor': 'python' })
|
||||||
|
return 'http://www.debuggex.com/?' + q
|
||||||
|
|
||||||
|
def shortstr(s, l=53):
|
||||||
|
"""Return shortened string
|
||||||
|
"""
|
||||||
|
if len(s) > l:
|
||||||
|
return s[:l-3] + '...'
|
||||||
|
return s
|
||||||
|
|
||||||
|
def pprint_list(l, header=None):
|
||||||
|
if not len(l):
|
||||||
|
return
|
||||||
|
if header:
|
||||||
|
s = "|- %s\n" % header
|
||||||
|
else:
|
||||||
|
s = ''
|
||||||
|
print s + "| " + "\n| ".join(l) + '\n`-'
|
||||||
|
|
||||||
|
|
||||||
|
def get_opt_parser():
|
||||||
|
# use module docstring for help output
|
||||||
|
p = OptionParser(
|
||||||
|
usage="%s [OPTIONS] <LOG> <REGEX> [IGNOREREGEX]\n" % sys.argv[0] + __doc__
|
||||||
|
+ """
|
||||||
|
LOG:
|
||||||
|
string a string representing a log line
|
||||||
|
filename path to a log file (/var/log/auth.log)
|
||||||
|
|
||||||
|
REGEX:
|
||||||
|
string a string representing a 'failregex'
|
||||||
|
filename path to a filter file (filter.d/sshd.conf)
|
||||||
|
|
||||||
|
IGNOREREGEX:
|
||||||
|
string a string representing an 'ignoreregex'
|
||||||
|
filename path to a filter file (filter.d/sshd.conf)
|
||||||
|
|
||||||
|
Copyright (c) 2004-2008 Cyril Jaquier, 2008- Fail2Ban Contributors
|
||||||
|
Copyright of modifications held by their respective authors.
|
||||||
|
Licensed under the GNU General Public License v2 (GPL).
|
||||||
|
|
||||||
|
Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>.
|
||||||
|
Many contributions by Yaroslav O. Halchenko and Steven Hiscocks.
|
||||||
|
|
||||||
|
Report bugs to https://github.com/fail2ban/fail2ban/issues
|
||||||
|
""",
|
||||||
|
version="%prog " + version)
|
||||||
|
|
||||||
|
p.add_options([
|
||||||
|
Option('-l', "--log-level", type="choice",
|
||||||
|
dest="log_level",
|
||||||
|
choices=('heavydebug', 'debug', 'info', 'warning', 'error', 'fatal'),
|
||||||
|
default=None,
|
||||||
|
help="Log level for the Fail2Ban logger to use"),
|
||||||
|
Option("-v", "--verbose", action='store_true',
|
||||||
|
help="Be verbose in output"),
|
||||||
|
Option("-D", "--debuggex", action='store_true',
|
||||||
|
help="Produce debuggex.com urls for debugging there"),
|
||||||
|
Option("--print-all-missed", action='store_true',
|
||||||
|
help="Either to print all missed lines"),
|
||||||
|
Option("--print-all-ignored", action='store_true',
|
||||||
|
help="Either to print all ignored lines"),
|
||||||
|
Option("-t", "--log-traceback", action='store_true',
|
||||||
|
help="Enrich log-messages with compressed tracebacks"),
|
||||||
|
Option("--full-traceback", action='store_true',
|
||||||
|
help="Either to make the tracebacks full, not compressed (as by default)"),
|
||||||
|
])
|
||||||
|
|
||||||
|
return p
|
||||||
|
|
||||||
|
|
||||||
|
class RegexStat(object):
|
||||||
|
|
||||||
def __init__(self, failregex):
|
def __init__(self, failregex):
|
||||||
self.__stats = 0
|
self._stats = 0
|
||||||
self.__failregex = failregex
|
self._failregex = failregex
|
||||||
self.__ipList = list()
|
self._ipList = list()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s(%r) %d failed: %s" \
|
return "%s(%r) %d failed: %s" \
|
||||||
% (self.__class__, self.__failregex, self.__stats, self.__ipList)
|
% (self.__class__, self._failregex, self._stats, self._ipList)
|
||||||
|
|
||||||
def inc(self):
|
def inc(self):
|
||||||
self.__stats += 1
|
self._stats += 1
|
||||||
|
|
||||||
def getStats(self):
|
def getStats(self):
|
||||||
return self.__stats
|
return self._stats
|
||||||
|
|
||||||
def getFailRegex(self):
|
def getFailRegex(self):
|
||||||
return self.__failregex
|
return self._failregex
|
||||||
|
|
||||||
def appendIP(self, value):
|
def appendIP(self, value):
|
||||||
self.__ipList.extend(value)
|
self._ipList.append(value)
|
||||||
|
|
||||||
def getIPList(self):
|
def getIPList(self):
|
||||||
return self.__ipList
|
return self._ipList
|
||||||
|
|
||||||
class Fail2banRegex:
|
|
||||||
|
|
||||||
test = None
|
class LineStats(object):
|
||||||
|
"""Just a convenience container for stats
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
self.tested = self.matched = 0
|
||||||
|
self.missed_lines = []
|
||||||
|
self.missed_lines_timeextracted = []
|
||||||
|
self.ignored_lines = []
|
||||||
|
self.ignored_lines_timeextracted = []
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "%(tested)d lines, %(ignored)d ignored, %(matched)d matched, %(missed)d missed" % self
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ignored(self):
|
||||||
|
return len(self.ignored_lines)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def missed(self):
|
||||||
|
return self.tested - (self.ignored + self.matched)
|
||||||
|
|
||||||
|
# just for convenient str
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return getattr(self, key)
|
||||||
|
|
||||||
|
|
||||||
|
class Fail2banRegex(object):
|
||||||
|
|
||||||
CONFIG_DEFAULTS = {'configpath' : "/etc/fail2ban/"}
|
CONFIG_DEFAULTS = {'configpath' : "/etc/fail2ban/"}
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, opts):
|
||||||
self.__filter = Filter(None)
|
self._verbose = opts.verbose
|
||||||
self.__ignoreregex = list()
|
self._debuggex = opts.debuggex
|
||||||
self.__failregex = list()
|
self._print_all_missed = opts.print_all_missed
|
||||||
self.__verbose = False
|
self._print_all_ignored = opts.print_all_ignored
|
||||||
# Setup logging
|
|
||||||
logging.getLogger("fail2ban").handlers = []
|
|
||||||
self.__hdlr = logging.StreamHandler(Fail2banRegex.test)
|
|
||||||
# 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)
|
|
||||||
self.__logging_level = self.__verbose and logging.DEBUG or logging.WARN
|
|
||||||
logging.getLogger("fail2ban").addHandler(self.__hdlr)
|
|
||||||
logging.getLogger("fail2ban").setLevel(logging.ERROR)
|
|
||||||
|
|
||||||
#@staticmethod
|
self._filter = Filter(None)
|
||||||
def dispVersion():
|
self._ignoreregex = list()
|
||||||
print "Fail2Ban v" + version
|
self._failregex = list()
|
||||||
print
|
self._line_stats = LineStats()
|
||||||
print "Copyright (c) 2004-2008 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 <cyril.jaquier@fail2ban.org>."
|
|
||||||
print "Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>."
|
|
||||||
dispVersion = staticmethod(dispVersion)
|
|
||||||
|
|
||||||
#@staticmethod
|
|
||||||
def dispUsage():
|
|
||||||
print "Usage: "+sys.argv[0]+" [OPTIONS] <LOG> <REGEX> [IGNOREREGEX]"
|
|
||||||
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 regular expressions for \"fail2ban\"."
|
|
||||||
print
|
|
||||||
print "Options:"
|
|
||||||
print " -h, --help display this help message"
|
|
||||||
print " -V, --version print the version"
|
|
||||||
print " -v, --verbose verbose output"
|
|
||||||
print
|
|
||||||
print "Log:"
|
|
||||||
print " string a string representing a log line"
|
|
||||||
print " filename path to a log file (/var/log/auth.log)"
|
|
||||||
print
|
|
||||||
print "Regex:"
|
|
||||||
print " string a string representing a 'failregex'"
|
|
||||||
print " filename path to a filter file (filter.d/sshd.conf)"
|
|
||||||
print
|
|
||||||
print "IgnoreRegex:"
|
|
||||||
print " string a string representing an 'ignoreregex'"
|
|
||||||
print " filename path to a filter file (filter.d/sshd.conf)"
|
|
||||||
print
|
|
||||||
print "Report bugs to https://github.com/fail2ban/fail2ban/issues"
|
|
||||||
dispUsage = staticmethod(dispUsage)
|
|
||||||
|
|
||||||
def getCmdLineOptions(self, optList):
|
def readRegex(self, value, regextype):
|
||||||
""" Gets the command line options
|
assert(regextype in ('fail', 'ignore'))
|
||||||
"""
|
regex = regextype + 'regex'
|
||||||
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)
|
|
||||||
elif opt[0] in ["-v", "--verbose"]:
|
|
||||||
self.__verbose = True
|
|
||||||
|
|
||||||
#@staticmethod
|
|
||||||
def logIsFile(value):
|
|
||||||
return os.path.isfile(value)
|
|
||||||
logIsFile = staticmethod(logIsFile)
|
|
||||||
|
|
||||||
def readIgnoreRegex(self, value):
|
|
||||||
if os.path.isfile(value):
|
if os.path.isfile(value):
|
||||||
reader = SafeConfigParserWithIncludes(defaults=self.CONFIG_DEFAULTS)
|
reader = SafeConfigParserWithIncludes(defaults=self.CONFIG_DEFAULTS)
|
||||||
try:
|
try:
|
||||||
reader.read(value)
|
reader.read(value)
|
||||||
print "Use ignoreregex file : " + value
|
print "Use %11s file : %s" % (regex, value)
|
||||||
self.__ignoreregex = [RegexStat(m)
|
# TODO: reuse functionality in client
|
||||||
for m in reader.get("Definition", "ignoreregex").split('\n')]
|
regex_values = [
|
||||||
|
RegexStat(m)
|
||||||
|
for m in reader.get("Definition", regex).split('\n')
|
||||||
|
if m != ""]
|
||||||
except NoSectionError:
|
except NoSectionError:
|
||||||
print "No [Definition] section in " + value
|
print "No [Definition] section in %s" % value
|
||||||
print
|
|
||||||
return False
|
return False
|
||||||
except NoOptionError:
|
except NoOptionError:
|
||||||
print "No failregex option in " + value
|
print "No %s option in %s" % (regex, value)
|
||||||
print
|
|
||||||
return False
|
return False
|
||||||
except MissingSectionHeaderError:
|
except MissingSectionHeaderError:
|
||||||
print "No section headers in " + value
|
print "No section headers in %s" % value
|
||||||
print
|
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
if len(value) > 53:
|
print "Use %11s line : %s" % (regex, shortstr(value))
|
||||||
stripReg = value[0:50] + "..."
|
regex_values = [RegexStat(value)]
|
||||||
else:
|
|
||||||
stripReg = value
|
|
||||||
print "Use ignoreregex line : " + stripReg
|
|
||||||
self.__ignoreregex = [RegexStat(value)]
|
|
||||||
return True
|
|
||||||
|
|
||||||
def readRegex(self, value):
|
setattr(self, "_" + regex, regex_values)
|
||||||
if os.path.isfile(value):
|
for regex in regex_values:
|
||||||
reader = SafeConfigParserWithIncludes(defaults=self.CONFIG_DEFAULTS)
|
getattr(
|
||||||
try:
|
self._filter,
|
||||||
reader.read(value)
|
'add%sRegex' % regextype.title())(regex.getFailRegex())
|
||||||
print "Use regex file : " + value
|
|
||||||
self.__failregex = [RegexStat(m)
|
|
||||||
for m in reader.get("Definition", "failregex").split('\n')]
|
|
||||||
except NoSectionError:
|
|
||||||
print "No [Definition] section in " + value
|
|
||||||
print
|
|
||||||
return False
|
|
||||||
except NoOptionError:
|
|
||||||
print "No failregex option in " + value
|
|
||||||
print
|
|
||||||
return False
|
|
||||||
except MissingSectionHeaderError:
|
|
||||||
print "No section headers in " + value
|
|
||||||
print
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
if len(value) > 53:
|
|
||||||
stripReg = value[0:50] + "..."
|
|
||||||
else:
|
|
||||||
stripReg = value
|
|
||||||
print "Use regex line : " + stripReg
|
|
||||||
self.__failregex = [RegexStat(value)]
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def testIgnoreRegex(self, line):
|
def testIgnoreRegex(self, line):
|
||||||
found = False
|
found = False
|
||||||
for regex in self.__ignoreregex:
|
try:
|
||||||
logging.getLogger("fail2ban").setLevel(self.__logging_level)
|
ret = self._filter.ignoreLine(line)
|
||||||
try:
|
if ret is not None:
|
||||||
self.__filter.addIgnoreRegex(regex.getFailRegex())
|
found = True
|
||||||
try:
|
regex = self._ignoreregex[ret].inc()
|
||||||
ret = self.__filter.ignoreLine(line)
|
except RegexException, e:
|
||||||
if ret:
|
print e
|
||||||
regex.inc()
|
return False
|
||||||
except RegexException, e:
|
return found
|
||||||
print e
|
|
||||||
return False
|
|
||||||
finally:
|
|
||||||
self.__filter.delIgnoreRegex(0)
|
|
||||||
logging.getLogger("fail2ban").setLevel(self.__logging_level)
|
|
||||||
|
|
||||||
def testRegex(self, line):
|
def testRegex(self, line):
|
||||||
found = False
|
try:
|
||||||
for regex in self.__ignoreregex:
|
line, ret = self._filter.processLine(line, checkAllRegex=True)
|
||||||
self.__filter.addIgnoreRegex(regex.getFailRegex())
|
for match in ret:
|
||||||
for regex in self.__failregex:
|
# Append True/False flag depending if line was matched by
|
||||||
logging.getLogger("fail2ban").setLevel(logging.DEBUG)
|
# more than one regex
|
||||||
try:
|
match.append(len(ret)>1)
|
||||||
self.__filter.addFailRegex(regex.getFailRegex())
|
regex = self._failregex[match[0]]
|
||||||
try:
|
regex.inc()
|
||||||
ret = self.__filter.processLine(line)
|
regex.appendIP(match)
|
||||||
if not len(ret) == 0:
|
except RegexException, e:
|
||||||
if found == True:
|
print e
|
||||||
ret[0].append(True)
|
return False
|
||||||
else:
|
except IndexError:
|
||||||
found = True
|
print "Sorry, but no <HOST> found in regex"
|
||||||
ret[0].append(False)
|
return False
|
||||||
regex.inc()
|
return line, ret
|
||||||
regex.appendIP(ret)
|
|
||||||
except RegexException, e:
|
|
||||||
print e
|
def process(self, test_lines):
|
||||||
return False
|
|
||||||
except IndexError:
|
for line_no, line in enumerate(test_lines):
|
||||||
print "Sorry, but no <host> found in regex"
|
if line.startswith('#') or not line.strip():
|
||||||
return False
|
# skip comment and empty lines
|
||||||
finally:
|
continue
|
||||||
self.__filter.delFailRegex(0)
|
is_ignored = fail2banRegex.testIgnoreRegex(line)
|
||||||
logging.getLogger("fail2ban").setLevel(logging.CRITICAL)
|
line_datetimestripped, ret = fail2banRegex.testRegex(line)
|
||||||
for regex in self.__ignoreregex:
|
|
||||||
self.__filter.delIgnoreRegex(0)
|
if is_ignored:
|
||||||
|
self._line_stats.ignored_lines.append(line)
|
||||||
|
self._line_stats.ignored_lines_timeextracted.append(line_datetimestripped)
|
||||||
|
|
||||||
|
if len(ret) > 0:
|
||||||
|
assert(not is_ignored)
|
||||||
|
self._line_stats.matched += 1
|
||||||
|
else:
|
||||||
|
if not is_ignored:
|
||||||
|
self._line_stats.missed_lines.append(line)
|
||||||
|
self._line_stats.missed_lines_timeextracted.append(line_datetimestripped)
|
||||||
|
self._line_stats.tested += 1
|
||||||
|
|
||||||
|
if line_no % 10 == 0:
|
||||||
|
self._filter.dateDetector.sortTemplate()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def printLines(self, ltype):
|
||||||
|
lstats = self._line_stats
|
||||||
|
assert(len(lstats.missed_lines) == lstats.tested - (lstats.matched + lstats.ignored))
|
||||||
|
l = lstats[ltype + '_lines']
|
||||||
|
if len(l):
|
||||||
|
header = "%s line(s):" % (ltype.capitalize(),)
|
||||||
|
if self._debuggex:
|
||||||
|
if ltype == 'missed':
|
||||||
|
regexlist = self._failregex
|
||||||
|
else:
|
||||||
|
regexlist = self._ignoreregex
|
||||||
|
l = lstats[ltype + '_lines_timeextracted']
|
||||||
|
lines = len(l)*len(regexlist)
|
||||||
|
if lines < 20 or getattr(self, '_print_all_' + ltype):
|
||||||
|
ans = [[]]
|
||||||
|
for arg in [l, regexlist]:
|
||||||
|
ans = [ x + [y] for x in ans for y in arg ]
|
||||||
|
b = map(lambda a: a[0] + ' | ' + a[1].getFailRegex() + ' | ' + debuggexURL(a[0], a[1].getFailRegex()), ans)
|
||||||
|
pprint_list([x.rstrip() for x in b], header)
|
||||||
|
else:
|
||||||
|
print "%s: too many to print. Use --print-all-%s " \
|
||||||
|
"to print all %d lines" % (header, ltype, lines)
|
||||||
|
elif len(l) < 20 or getattr(self, '_print_all_' + ltype):
|
||||||
|
pprint_list([x.rstrip() for x in l], header)
|
||||||
|
else:
|
||||||
|
print "%s: too many to print. Use --print-all-%s " \
|
||||||
|
"to print all %d lines" % (header, ltype, len(l))
|
||||||
|
|
||||||
def printStats(self):
|
def printStats(self):
|
||||||
print
|
print
|
||||||
print "Results"
|
print "Results"
|
||||||
print "======="
|
print "======="
|
||||||
print
|
|
||||||
|
|
||||||
def print_failregexes(title, failregexes):
|
def print_failregexes(title, failregexes):
|
||||||
# Print title
|
# Print title
|
||||||
|
@ -264,106 +323,110 @@ class Fail2banRegex:
|
||||||
for cnt, failregex in enumerate(failregexes):
|
for cnt, failregex in enumerate(failregexes):
|
||||||
match = failregex.getStats()
|
match = failregex.getStats()
|
||||||
total += match
|
total += match
|
||||||
if (match or self.__verbose):
|
if (match or self._verbose):
|
||||||
out.append("| %d) [%d] %s" % (cnt+1, match, failregex.getFailRegex()))
|
out.append("%2d) [%d] %s" % (cnt+1, match, failregex.getFailRegex()))
|
||||||
print "%s: %d total" % (title, total)
|
|
||||||
if len(out):
|
if self._verbose and len(failregex.getIPList()):
|
||||||
print "|- #) [# of hits] regular expression"
|
for ip in failregex.getIPList():
|
||||||
print '\n'.join(out)
|
timeTuple = time.localtime(ip[2])
|
||||||
print '`-'
|
timeString = time.strftime("%a %b %d %H:%M:%S %Y", timeTuple)
|
||||||
print
|
out.append(
|
||||||
|
" %s %s%s" % (
|
||||||
|
ip[1],
|
||||||
|
timeString,
|
||||||
|
ip[3] and " (multiple regex matched)" or ""))
|
||||||
|
|
||||||
|
print "\n%s: %d total" % (title, total)
|
||||||
|
pprint_list(out, " #) [# of hits] regular expression")
|
||||||
return total
|
return total
|
||||||
|
|
||||||
# Print title
|
# Print title
|
||||||
total = print_failregexes("Failregex", self.__failregex)
|
total = print_failregexes("Failregex", self._failregex)
|
||||||
_ = print_failregexes("Ignoreregex", self.__ignoreregex)
|
_ = print_failregexes("Ignoreregex", self._ignoreregex)
|
||||||
|
|
||||||
print "Summary"
|
|
||||||
print "======="
|
|
||||||
print
|
|
||||||
|
|
||||||
if total == 0:
|
print "\nDate template hits:"
|
||||||
print "Sorry, no match"
|
out = []
|
||||||
print
|
for template in self._filter.dateDetector.getTemplates():
|
||||||
print "Look at the above section 'Running tests' which could contain important"
|
if self._verbose or template.getHits():
|
||||||
print "information."
|
out.append("[%d] %s" % (template.getHits(), template.getName()))
|
||||||
return False
|
pprint_list(out, "[# of hits] date format")
|
||||||
else:
|
|
||||||
# Print stats
|
|
||||||
print "Addresses found:"
|
|
||||||
for cnt, failregex in enumerate(self.__failregex):
|
|
||||||
if self.__verbose or len(failregex.getIPList()):
|
|
||||||
print "[%d]" % (cnt+1)
|
|
||||||
for ip in failregex.getIPList():
|
|
||||||
timeTuple = time.localtime(ip[1])
|
|
||||||
timeString = time.strftime("%a %b %d %H:%M:%S %Y", timeTuple)
|
|
||||||
print " %s (%s)%s" % (
|
|
||||||
ip[0], timeString, ip[2] and " (already matched)" or "")
|
|
||||||
print
|
|
||||||
|
|
||||||
print "Date template hits:"
|
print "\nLines: %s" % self._line_stats
|
||||||
for template in self.__filter.dateDetector.getTemplates():
|
|
||||||
if self.__verbose or template.getHits():
|
|
||||||
print `template.getHits()` + " hit(s): " + template.getName()
|
|
||||||
print
|
|
||||||
|
|
||||||
print "Success, the total number of match is " + str(total)
|
self.printLines('ignored')
|
||||||
print
|
self.printLines('missed')
|
||||||
print "However, look at the above section 'Running tests' which could contain important"
|
|
||||||
print "information."
|
return True
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
fail2banRegex = Fail2banRegex()
|
|
||||||
# Reads the command line options.
|
parser = get_opt_parser()
|
||||||
try:
|
(opts, args) = parser.parse_args()
|
||||||
cmdOpts = 'hVcv'
|
|
||||||
cmdLongOpts = ['help', 'version', 'verbose']
|
fail2banRegex = Fail2banRegex(opts)
|
||||||
optList, args = getopt.getopt(sys.argv[1:], cmdOpts, cmdLongOpts)
|
|
||||||
except getopt.GetoptError:
|
|
||||||
fail2banRegex.dispUsage()
|
|
||||||
sys.exit(-1)
|
|
||||||
# Process command line
|
|
||||||
fail2banRegex.getCmdLineOptions(optList)
|
|
||||||
|
|
||||||
# We need 2 or 3 parameters
|
# We need 2 or 3 parameters
|
||||||
if not len(args) in (2, 3):
|
if not len(args) in (2, 3):
|
||||||
fail2banRegex.dispUsage()
|
sys.stderr.write("ERROR: provide both <LOG> and <REGEX>.\n\n")
|
||||||
|
parser.print_help()
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
|
# TODO: taken from -testcases -- move common functionality somewhere
|
||||||
|
if opts.log_level is not None: # pragma: no cover
|
||||||
|
# so we had explicit settings
|
||||||
|
logSys.setLevel(getattr(logging, opts.log_level.upper()))
|
||||||
|
else: # pragma: no cover
|
||||||
|
# suppress the logging but it would leave unittests' progress dots
|
||||||
|
# ticking, unless like with '-l fatal' which would be silent
|
||||||
|
# unless error occurs
|
||||||
|
logSys.setLevel(getattr(logging, 'FATAL'))
|
||||||
|
|
||||||
|
# Add the default logging handler
|
||||||
|
stdout = logging.StreamHandler(sys.stdout)
|
||||||
|
|
||||||
|
fmt = 'D: %(message)s'
|
||||||
|
|
||||||
|
if opts.log_traceback:
|
||||||
|
Formatter = FormatterWithTraceBack
|
||||||
|
fmt = (opts.full_traceback and ' %(tb)s' or ' %(tbc)s') + fmt
|
||||||
else:
|
else:
|
||||||
print
|
Formatter = logging.Formatter
|
||||||
print "Running tests"
|
|
||||||
print "============="
|
|
||||||
print
|
|
||||||
|
|
||||||
cmd_log, cmd_regex = args[:2]
|
# Custom log format for the verbose tests runs
|
||||||
|
if opts.verbose > 1: # pragma: no cover
|
||||||
|
stdout.setFormatter(Formatter(' %(asctime)-15s %(thread)s' + fmt))
|
||||||
|
else: # pragma: no cover
|
||||||
|
# just prefix with the space
|
||||||
|
stdout.setFormatter(Formatter(fmt))
|
||||||
|
logSys.addHandler(stdout)
|
||||||
|
|
||||||
if len(args) == 3:
|
print
|
||||||
fail2banRegex.readIgnoreRegex(args[2]) or sys.exit(-1)
|
print "Running tests"
|
||||||
|
print "============="
|
||||||
|
print
|
||||||
|
|
||||||
fail2banRegex.readRegex(cmd_regex) or sys.exit(-1)
|
cmd_log, cmd_regex = args[:2]
|
||||||
|
|
||||||
if fail2banRegex.logIsFile(cmd_log):
|
if len(args) == 3:
|
||||||
try:
|
fail2banRegex.readRegex(args[2], 'ignore') or sys.exit(-1)
|
||||||
hdlr = open(cmd_log)
|
|
||||||
print "Use log file : " + cmd_log
|
|
||||||
print
|
|
||||||
for line in hdlr:
|
|
||||||
fail2banRegex.testIgnoreRegex(line)
|
|
||||||
fail2banRegex.testRegex(line)
|
|
||||||
except IOError, e:
|
|
||||||
print e
|
|
||||||
print
|
|
||||||
sys.exit(-1)
|
|
||||||
else:
|
|
||||||
if len(sys.argv[1]) > 53:
|
|
||||||
stripLog = cmd_log[0:50] + "..."
|
|
||||||
else:
|
|
||||||
stripLog = cmd_log
|
|
||||||
print "Use single line: " + stripLog
|
|
||||||
print
|
|
||||||
fail2banRegex.testIgnoreRegex(cmd_log)
|
|
||||||
fail2banRegex.testRegex(cmd_log)
|
|
||||||
|
|
||||||
fail2banRegex.printStats() or sys.exit(-1)
|
fail2banRegex.readRegex(cmd_regex, 'fail') or sys.exit(-1)
|
||||||
|
|
||||||
|
if os.path.isfile(cmd_log):
|
||||||
|
try:
|
||||||
|
hdlr = open(cmd_log)
|
||||||
|
print "Use log file : %s" % cmd_log
|
||||||
|
test_lines = hdlr # Iterable
|
||||||
|
except IOError, e:
|
||||||
|
print e
|
||||||
|
sys.exit(-1)
|
||||||
|
else:
|
||||||
|
print "Use single line : %s" % shortstr(cmd_log)
|
||||||
|
test_lines = [ cmd_log ]
|
||||||
|
print
|
||||||
|
|
||||||
|
fail2banRegex.process(test_lines)
|
||||||
|
|
||||||
|
fail2banRegex.printStats() or sys.exit(-1)
|
||||||
|
|
|
@ -27,6 +27,14 @@ __license__ = "GPL"
|
||||||
|
|
||||||
import unittest, logging, sys, time, os
|
import unittest, logging, sys, time, os
|
||||||
|
|
||||||
|
if sys.version_info >= (2, 6):
|
||||||
|
import json
|
||||||
|
else: # pragma: no cover
|
||||||
|
try:
|
||||||
|
import simplejson as json
|
||||||
|
except ImportError:
|
||||||
|
json = None
|
||||||
|
|
||||||
from common.version import version
|
from common.version import version
|
||||||
from testcases import banmanagertestcase
|
from testcases import banmanagertestcase
|
||||||
from testcases import clientreadertestcase
|
from testcases import clientreadertestcase
|
||||||
|
@ -37,8 +45,11 @@ from testcases import datedetectortestcase
|
||||||
from testcases import actiontestcase
|
from testcases import actiontestcase
|
||||||
from testcases import sockettestcase
|
from testcases import sockettestcase
|
||||||
from testcases import misctestcase
|
from testcases import misctestcase
|
||||||
|
if json:
|
||||||
|
from testcases import samplestestcase
|
||||||
|
|
||||||
from testcases.utils import FormatterWithTraceBack
|
from testcases.utils import FormatterWithTraceBack
|
||||||
|
from testcases import actionstestcase
|
||||||
from server.mytime import MyTime
|
from server.mytime import MyTime
|
||||||
|
|
||||||
from optparse import OptionParser, Option
|
from optparse import OptionParser, Option
|
||||||
|
@ -52,7 +63,7 @@ def get_opt_parser():
|
||||||
p.add_options([
|
p.add_options([
|
||||||
Option('-l', "--log-level", type="choice",
|
Option('-l', "--log-level", type="choice",
|
||||||
dest="log_level",
|
dest="log_level",
|
||||||
choices=('debug', 'info', 'warn', 'error', 'fatal'),
|
choices=('heavydebug', 'debug', 'info', 'warning', 'error', 'fatal'),
|
||||||
default=None,
|
default=None,
|
||||||
help="Log level for the logger to use during running tests"),
|
help="Log level for the logger to use during running tests"),
|
||||||
Option('-n', "--no-network", action="store_true",
|
Option('-n', "--no-network", action="store_true",
|
||||||
|
@ -76,9 +87,10 @@ parser = get_opt_parser()
|
||||||
logSys = logging.getLogger("fail2ban")
|
logSys = logging.getLogger("fail2ban")
|
||||||
|
|
||||||
# Numerical level of verbosity corresponding to a log "level"
|
# Numerical level of verbosity corresponding to a log "level"
|
||||||
verbosity = {'debug': 3,
|
verbosity = {'heavydebug': 4,
|
||||||
|
'debug': 3,
|
||||||
'info': 2,
|
'info': 2,
|
||||||
'warn': 1,
|
'warning': 1,
|
||||||
'error': 1,
|
'error': 1,
|
||||||
'fatal': 0,
|
'fatal': 0,
|
||||||
None: 1}[opts.log_level]
|
None: 1}[opts.log_level]
|
||||||
|
@ -97,7 +109,7 @@ stdout = logging.StreamHandler(sys.stdout)
|
||||||
|
|
||||||
fmt = ' %(message)s'
|
fmt = ' %(message)s'
|
||||||
|
|
||||||
if opts.log_traceback:
|
if opts.log_traceback or opts.full_traceback:
|
||||||
Formatter = FormatterWithTraceBack
|
Formatter = FormatterWithTraceBack
|
||||||
fmt = (opts.full_traceback and ' %(tb)s' or ' %(tbc)s') + fmt
|
fmt = (opts.full_traceback and ' %(tb)s' or ' %(tbc)s') + fmt
|
||||||
else:
|
else:
|
||||||
|
@ -142,6 +154,7 @@ else: # pragma: no cover
|
||||||
tests.addTest(unittest.makeSuite(servertestcase.Transmitter))
|
tests.addTest(unittest.makeSuite(servertestcase.Transmitter))
|
||||||
tests.addTest(unittest.makeSuite(servertestcase.JailTests))
|
tests.addTest(unittest.makeSuite(servertestcase.JailTests))
|
||||||
tests.addTest(unittest.makeSuite(actiontestcase.ExecuteAction))
|
tests.addTest(unittest.makeSuite(actiontestcase.ExecuteAction))
|
||||||
|
tests.addTest(unittest.makeSuite(actionstestcase.ExecuteActions))
|
||||||
# FailManager
|
# FailManager
|
||||||
tests.addTest(unittest.makeSuite(failmanagertestcase.AddFailure))
|
tests.addTest(unittest.makeSuite(failmanagertestcase.AddFailure))
|
||||||
# BanManager
|
# BanManager
|
||||||
|
@ -156,6 +169,7 @@ tests.addTest(unittest.makeSuite(sockettestcase.Socket))
|
||||||
tests.addTest(unittest.makeSuite(misctestcase.HelpersTest))
|
tests.addTest(unittest.makeSuite(misctestcase.HelpersTest))
|
||||||
tests.addTest(unittest.makeSuite(misctestcase.SetupTest))
|
tests.addTest(unittest.makeSuite(misctestcase.SetupTest))
|
||||||
tests.addTest(unittest.makeSuite(misctestcase.TestsUtilsTest))
|
tests.addTest(unittest.makeSuite(misctestcase.TestsUtilsTest))
|
||||||
|
tests.addTest(unittest.makeSuite(misctestcase.CustomDateFormatsTest))
|
||||||
|
|
||||||
# Filter
|
# Filter
|
||||||
if not opts.no_network:
|
if not opts.no_network:
|
||||||
|
@ -169,6 +183,11 @@ tests.addTest(unittest.makeSuite(filtertestcase.JailTests))
|
||||||
|
|
||||||
# DateDetector
|
# DateDetector
|
||||||
tests.addTest(unittest.makeSuite(datedetectortestcase.DateDetectorTest))
|
tests.addTest(unittest.makeSuite(datedetectortestcase.DateDetectorTest))
|
||||||
|
if json:
|
||||||
|
# Filter Regex tests with sample logs
|
||||||
|
tests.addTest(unittest.makeSuite(samplestestcase.FilterSamplesRegex))
|
||||||
|
else: # pragma: no cover
|
||||||
|
print "I: Skipping filter samples testing. No simplejson/json module"
|
||||||
|
|
||||||
#
|
#
|
||||||
# Extensive use-tests of different available filters backends
|
# Extensive use-tests of different available filters backends
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#-------------------------- =+- Shell script -+= --------------------------
|
||||||
|
#
|
||||||
|
# Yaroslav Halchenko CS@UNM, CS@NJIT
|
||||||
|
# web: http://www.onerussian.com & PSYCH@RUTGERS
|
||||||
|
# e-mail: yoh@onerussian.com ICQ#: 60653192
|
||||||
|
#
|
||||||
|
# DESCRIPTION (NOTES):
|
||||||
|
#
|
||||||
|
# Script to fetch list of agent strings from http://www.user-agents.org
|
||||||
|
# which are known to be from mailicious bots, and create apache-badbots.conf
|
||||||
|
# filter for fail2ban
|
||||||
|
#
|
||||||
|
# COPYRIGHT: Yaroslav Halchenko 2007-2013
|
||||||
|
#
|
||||||
|
# LICENSE:
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the
|
||||||
|
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||||
|
# MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# On Debian system see /usr/share/common-licenses/GPL for the full license.
|
||||||
|
#
|
||||||
|
#-----------------\____________________________________/------------------
|
||||||
|
|
||||||
|
url=http://www.user-agents.org/index.shtml
|
||||||
|
badbots=$(
|
||||||
|
for f in "" "?g_m" "?moz" "?n_s" "?t_z"; do
|
||||||
|
wget -q -O- $url$f;
|
||||||
|
done \
|
||||||
|
| grep -h -B4 '<td class="smallcell" nowrap>S </td>'\
|
||||||
|
| sed -e 's/ //g' \
|
||||||
|
| awk '/^--/{getline; gsub(" ",""); print $0}' \
|
||||||
|
| sed -e 's/\([.\:|()]\)/\\\1/g' \
|
||||||
|
| uniq \
|
||||||
|
| tr '\n' '|' \
|
||||||
|
| sed -e 's/|$//g'
|
||||||
|
)
|
||||||
|
|
||||||
|
echo $badbots >| /tmp/badbots.tmp
|
||||||
|
|
||||||
|
cat >| config/filter.d/apache-badbots.conf <<EOF
|
||||||
|
# Fail2Ban configuration file
|
||||||
|
#
|
||||||
|
# Regexp to catch known spambots and software alike. Please verify
|
||||||
|
# that it is your intent to block IPs which were driven by
|
||||||
|
# above mentioned bots.
|
||||||
|
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
badbotscustom = EmailCollector|WebEMailExtrac|TrackBack/1\.02|sogou music spider
|
||||||
|
badbots = $badbots
|
||||||
|
|
||||||
|
failregex = ^<HOST> -.*"(GET|POST).*HTTP.*"(?:%(badbots)s|%(badbotscustom)s)"$
|
||||||
|
|
||||||
|
ignoreregex =
|
||||||
|
|
||||||
|
# DEV Notes:
|
||||||
|
# List of bad bots fetched from http://www.user-agents.org
|
||||||
|
# Generated on `date` by $0.
|
||||||
|
#
|
||||||
|
# Author: Yaroslav Halchenko
|
||||||
|
EOF
|
|
@ -35,7 +35,7 @@ HELP:
|
||||||
/etc/init.d/fail2ban stop
|
/etc/init.d/fail2ban stop
|
||||||
|
|
||||||
2.) delete the socket if available
|
2.) delete the socket if available
|
||||||
rm /tmp/fail2ban.sock
|
rm /var/run/fail2ban/fail2ban.sock
|
||||||
|
|
||||||
3.) start the Service
|
3.) start the Service
|
||||||
/etc/init.d/fail2ban start
|
/etc/init.d/fail2ban start
|
||||||
|
|
|
@ -1,38 +1,42 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# chkconfig: 345 92 08
|
# chkconfig: 345 92 08
|
||||||
# description: Fail2ban daemon
|
# processname: fail2ban-server
|
||||||
# http://fail2ban.sourceforge.net/wiki/index.php/Main_Page
|
# config: /etc/fail2ban/fail2ban.conf
|
||||||
# process name: fail2ban-server
|
# pidfile: /var/run/fail2ban/fail2ban.pid
|
||||||
#
|
# description: fail2ban is a daemon to ban hosts that cause multiple authentication errors
|
||||||
#
|
|
||||||
# Author: Tyler Owen
|
|
||||||
#
|
#
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: fail2ban
|
||||||
|
# Required-Start: $local_fs $remote_fs
|
||||||
|
# Required-Stop: $local_fs $remote_fs
|
||||||
|
# Should-Start: $time $network $syslog iptables firehol shorewall ferm
|
||||||
|
# Should-Stop: $network $syslog iptables firehol shorewall ferm
|
||||||
|
# Default-Start: 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: Start/Stop fail2ban
|
||||||
|
# Description: Start/Stop fail2ban, a daemon to ban hosts that cause multiple authentication errors
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
# Source function library.
|
# Source function library.
|
||||||
. /etc/init.d/functions
|
. /etc/rc.d/init.d/functions
|
||||||
|
|
||||||
# Check that the config file exists
|
# Check that the config file exists
|
||||||
[ -f /etc/fail2ban/fail2ban.conf ] || exit 0
|
[ -f /etc/fail2ban/fail2ban.conf ] || exit 0
|
||||||
|
|
||||||
FAIL2BAN="/usr/bin/fail2ban-client"
|
FAIL2BAN="/usr/bin/fail2ban-client"
|
||||||
|
prog=fail2ban-server
|
||||||
|
lockfile=${LOCKFILE-/var/lock/subsys/fail2ban}
|
||||||
|
socket=${SOCKET-/var/run/fail2ban/fail2ban.sock}
|
||||||
|
pidfile=${PIDFILE-/var/run/fail2ban/fail2ban.pid}
|
||||||
RETVAL=0
|
RETVAL=0
|
||||||
|
|
||||||
getpid() {
|
|
||||||
pid=`ps -eo pid,comm | grep fail2ban- | awk '{ print $1 }'`
|
|
||||||
}
|
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
echo -n $"Starting fail2ban: "
|
echo -n $"Starting fail2ban: "
|
||||||
getpid
|
${FAIL2BAN} -x start > /dev/null
|
||||||
if [ -z "$pid" ]; then
|
RETVAL=$?
|
||||||
rm -rf /var/run/fail2ban/fail2ban.sock # in case of unclean shutdown
|
if [ $RETVAL = 0 ]; then
|
||||||
$FAIL2BAN start > /dev/null
|
touch ${lockfile}
|
||||||
RETVAL=$?
|
|
||||||
fi
|
|
||||||
if [ $RETVAL -eq 0 ]; then
|
|
||||||
touch /var/lock/subsys/fail2ban
|
|
||||||
echo_success
|
echo_success
|
||||||
else
|
else
|
||||||
echo_failure
|
echo_failure
|
||||||
|
@ -43,51 +47,50 @@ start() {
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
echo -n $"Stopping fail2ban: "
|
echo -n $"Stopping fail2ban: "
|
||||||
getpid
|
${FAIL2BAN} stop > /dev/null
|
||||||
RETVAL=$?
|
RETVAL=$?
|
||||||
if [ -n "$pid" ]; then
|
if [ $RETVAL = 0 ]; then
|
||||||
$FAIL2BAN stop > /dev/null
|
rm -f ${lockfile} ${pidfile}
|
||||||
sleep 1
|
|
||||||
getpid
|
|
||||||
if [ -z "$pid" ]; then
|
|
||||||
rm -f /var/lock/subsys/fail2ban
|
|
||||||
echo_success
|
echo_success
|
||||||
else
|
else
|
||||||
echo_failure
|
echo_failure
|
||||||
fi
|
fi
|
||||||
else
|
echo
|
||||||
echo_failure
|
return $RETVAL
|
||||||
fi
|
}
|
||||||
|
|
||||||
|
reload() {
|
||||||
|
echo "Reloading fail2ban: "
|
||||||
|
${FAIL2BAN} reload
|
||||||
|
RETVAL=$?
|
||||||
echo
|
echo
|
||||||
return $RETVAL
|
return $RETVAL
|
||||||
}
|
}
|
||||||
|
|
||||||
# See how we were called.
|
# See how we were called.
|
||||||
case "$1" in
|
case "$1" in
|
||||||
start)
|
start)
|
||||||
|
status -p ${pidfile} ${prog} >/dev/null 2>&1 && exit 0
|
||||||
start
|
start
|
||||||
;;
|
;;
|
||||||
stop)
|
stop)
|
||||||
stop
|
stop
|
||||||
;;
|
;;
|
||||||
status)
|
reload)
|
||||||
getpid
|
reload
|
||||||
if [ -n "$pid" ]; then
|
|
||||||
echo "Fail2ban (pid $pid) is running..."
|
|
||||||
$FAIL2BAN status
|
|
||||||
else
|
|
||||||
RETVAL=1
|
|
||||||
echo "Fail2ban is stopped"
|
|
||||||
fi
|
|
||||||
;;
|
;;
|
||||||
restart)
|
restart)
|
||||||
stop
|
stop
|
||||||
start
|
start
|
||||||
;;
|
;;
|
||||||
*)
|
status)
|
||||||
echo $"Usage: $0 {start|stop|status|restart}"
|
status -p ${pidfile} ${prog}
|
||||||
exit 1
|
RETVAL=$?
|
||||||
|
[ $RETVAL = 0 ] && ${FAIL2BAN} status
|
||||||
;;
|
;;
|
||||||
|
*)
|
||||||
|
echo $"Usage: fail2ban {start|stop|restart|reload|status}"
|
||||||
|
RETVAL=2
|
||||||
esac
|
esac
|
||||||
|
|
||||||
exit $RETVAL
|
exit $RETVAL
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.2.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.12.
|
||||||
.TH FAIL2BAN-CLIENT "1" "June 2013" "fail2ban-client v0.8.10" "User Commands"
|
.TH FAIL2BAN-CLIENT "1" "October 2013" "fail2ban-client v0.8.11.pre1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
fail2ban-client \- configure and control the server
|
fail2ban-client \- configure and control the server
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B fail2ban-client
|
.B fail2ban-client
|
||||||
[\fIOPTIONS\fR] \fI<COMMAND>\fR
|
[\fIOPTIONS\fR] \fI<COMMAND>\fR
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Fail2Ban v0.8.10 reads log file that contains password failure report
|
Fail2Ban v0.8.11.pre1 reads log file that contains password failure report
|
||||||
and bans the corresponding IP addresses using firewall rules.
|
and bans the corresponding IP addresses using firewall rules.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
|
@ -274,3 +274,4 @@ Licensed under the GNU General Public License v2 (GPL).
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.br
|
.br
|
||||||
fail2ban-server(1)
|
fail2ban-server(1)
|
||||||
|
jail.conf(5)
|
||||||
|
|
|
@ -10,3 +10,4 @@ fail2ban-client \- configure and control the server
|
||||||
[see also]
|
[see also]
|
||||||
.br
|
.br
|
||||||
fail2ban-server(1)
|
fail2ban-server(1)
|
||||||
|
jail.conf(5)
|
||||||
|
|
|
@ -1,53 +1,72 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.2.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.12.
|
||||||
.TH FAIL2BAN-REGEX "1" "June 2013" "fail2ban-regex v0.8.10" "User Commands"
|
.TH FAIL2BAN-REGEX "1" "October 2013" "fail2ban-regex 0.8.11.pre1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
fail2ban-regex \- test Fail2ban "failregex" option
|
fail2ban-regex \- test Fail2ban "failregex" option
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B fail2ban-regex
|
.B fail2ban-regex
|
||||||
[\fIOPTIONS\fR] \fI<LOG> <REGEX> \fR[\fIIGNOREREGEX\fR]
|
[\fIOPTIONS\fR] \fI<LOG> <REGEX> \fR[\fIIGNOREREGEX\fR]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Fail2Ban v0.8.10 reads log file that contains password failure report
|
Fail2Ban reads log file that contains password failure report
|
||||||
and bans the corresponding IP addresses using firewall rules.
|
and bans the corresponding IP addresses using firewall rules.
|
||||||
.PP
|
.PP
|
||||||
This tools can test regular expressions for "fail2ban".
|
This tools can test regular expressions for "fail2ban".
|
||||||
.SH OPTIONS
|
.SS "LOG:"
|
||||||
.TP
|
.TP
|
||||||
\fB\-h\fR, \fB\-\-help\fR
|
string
|
||||||
display this help message
|
|
||||||
.TP
|
|
||||||
\fB\-V\fR, \fB\-\-version\fR
|
|
||||||
print the version
|
|
||||||
.TP
|
|
||||||
\fB\-v\fR, \fB\-\-verbose\fR
|
|
||||||
verbose output
|
|
||||||
.SH LOG
|
|
||||||
.TP
|
|
||||||
\fBstring\fR
|
|
||||||
a string representing a log line
|
a string representing a log line
|
||||||
.TP
|
.TP
|
||||||
\fBfilename\fR
|
filename
|
||||||
path to a log file (\fI/var/log/auth.log\fP)
|
path to a log file (/var/log/auth.log)
|
||||||
.SH REGEX
|
.SS "REGEX:"
|
||||||
.TP
|
.TP
|
||||||
\fBstring\fR
|
string
|
||||||
a string representing a 'failregex'
|
a string representing a 'failregex'
|
||||||
.TP
|
.TP
|
||||||
\fBfilename\fR
|
filename
|
||||||
path to a filter file (filter.d/sshd.conf)
|
path to a filter file (filter.d/sshd.conf)
|
||||||
.SS "IgnoreRegex:"
|
.SS "IGNOREREGEX:"
|
||||||
.TP
|
.TP
|
||||||
\fBstring\fR
|
string
|
||||||
a string representing an 'ignoreregex'
|
a string representing an 'ignoreregex'
|
||||||
.TP
|
.TP
|
||||||
\fBfilename\fR
|
filename
|
||||||
path to a filter file (filter.d/sshd.conf)
|
path to a filter file (filter.d/sshd.conf)
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
\fB\-\-version\fR
|
||||||
|
show program's version number and exit
|
||||||
|
.TP
|
||||||
|
\fB\-h\fR, \fB\-\-help\fR
|
||||||
|
show this help message and exit
|
||||||
|
.TP
|
||||||
|
\fB\-l\fR LOG_LEVEL, \fB\-\-log\-level\fR=\fILOG_LEVEL\fR
|
||||||
|
Log level for the Fail2Ban logger to use
|
||||||
|
.TP
|
||||||
|
\fB\-v\fR, \fB\-\-verbose\fR
|
||||||
|
Be verbose in output
|
||||||
|
.TP
|
||||||
|
\fB\-D\fR, \fB\-\-debuggex\fR
|
||||||
|
Produce debuggex.com urls for debugging there
|
||||||
|
.TP
|
||||||
|
\fB\-\-print\-all\-missed\fR
|
||||||
|
Either to print all missed lines
|
||||||
|
.TP
|
||||||
|
\fB\-\-print\-all\-ignored\fR
|
||||||
|
Either to print all ignored lines
|
||||||
|
.TP
|
||||||
|
\fB\-t\fR, \fB\-\-log\-traceback\fR
|
||||||
|
Enrich log\-messages with compressed tracebacks
|
||||||
|
.TP
|
||||||
|
\fB\-\-full\-traceback\fR
|
||||||
|
Either to make the tracebacks full, not compressed (as
|
||||||
|
by default)
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>.
|
Written by Cyril Jaquier <cyril.jaquier@fail2ban.org>.
|
||||||
Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>.
|
Many contributions by Yaroslav O. Halchenko and Steven Hiscocks.
|
||||||
.SH "REPORTING BUGS"
|
.SH "REPORTING BUGS"
|
||||||
Report bugs to https://github.com/fail2ban/fail2ban/issues
|
Report bugs to https://github.com/fail2ban/fail2ban/issues
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
Copyright \(co 2004\-2008 Cyril Jaquier
|
Copyright \(co 2004\-2008 Cyril Jaquier, 2008\- Fail2Ban Contributors
|
||||||
.br
|
.br
|
||||||
Copyright of modifications held by their respective authors.
|
Copyright of modifications held by their respective authors.
|
||||||
Licensed under the GNU General Public License v2 (GPL).
|
Licensed under the GNU General Public License v2 (GPL).
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.2.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.12.
|
||||||
.TH FAIL2BAN-SERVER "1" "June 2013" "fail2ban-server v0.8.10" "User Commands"
|
.TH FAIL2BAN-SERVER "1" "October 2013" "fail2ban-server v0.8.11.pre1" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
fail2ban-server \- start the server
|
fail2ban-server \- start the server
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B fail2ban-server
|
.B fail2ban-server
|
||||||
[\fIOPTIONS\fR]
|
[\fIOPTIONS\fR]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Fail2Ban v0.8.10 reads log file that contains password failure report
|
Fail2Ban v0.8.11.pre1 reads log file that contains password failure report
|
||||||
and bans the corresponding IP addresses using firewall rules.
|
and bans the corresponding IP addresses using firewall rules.
|
||||||
.PP
|
.PP
|
||||||
Only use this command for debugging purpose. Start the server with
|
Only use this command for debugging purpose. Start the server with
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
.TH JAIL.CONF "5" "March 2013" "Fail2Ban" "Fail2Ban Configuration"
|
.TH JAIL.CONF "10" "October 2013" "Fail2Ban" "Fail2Ban Configuration"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
jail.conf \- configuration for the fail2ban server
|
jail.conf \- configuration for the fail2ban server
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
|
||||||
|
.I fail2ban.conf fail2ban.d/*.conf fail2ban.d/*.local
|
||||||
|
|
||||||
.I jail.conf / jail.local
|
.I jail.conf / jail.local
|
||||||
|
|
||||||
.I action.d/*.conf action.d/*.local
|
.I action.d/*.conf action.d/*.local
|
||||||
|
@ -45,6 +48,18 @@ identical entries, parsed alphabetically, e.g.
|
||||||
.RE
|
.RE
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
The order \fIjail\fR configuration is parsed is:
|
||||||
|
|
||||||
|
jail.conf ,
|
||||||
|
jail.d/*.conf (in alphabetical order),
|
||||||
|
jail.local, followed by
|
||||||
|
jail.d/*.local (in alphabetical order).
|
||||||
|
|
||||||
|
Likewise for fail2ban configuration.
|
||||||
|
|
||||||
|
Comments: use '#' for comment lines and ';' (following a space) for inline comments
|
||||||
|
|
||||||
|
|
||||||
.SH DEFAULT
|
.SH DEFAULT
|
||||||
The following options are applicable to all jails. Their meaning is described in the default \fIjail.conf\fR file.
|
The following options are applicable to all jails. Their meaning is described in the default \fIjail.conf\fR file.
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -359,6 +359,10 @@ class Action:
|
||||||
#@staticmethod
|
#@staticmethod
|
||||||
def executeCmd(realCmd):
|
def executeCmd(realCmd):
|
||||||
logSys.debug(realCmd)
|
logSys.debug(realCmd)
|
||||||
|
if not realCmd:
|
||||||
|
logSys.debug("Nothing to do")
|
||||||
|
return True
|
||||||
|
|
||||||
_cmd_lock.acquire()
|
_cmd_lock.acquire()
|
||||||
try: # Try wrapped within another try needed for python version < 2.5
|
try: # Try wrapped within another try needed for python version < 2.5
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -46,13 +46,13 @@ class DateDetector:
|
||||||
def addDefaultTemplate(self):
|
def addDefaultTemplate(self):
|
||||||
self.__lock.acquire()
|
self.__lock.acquire()
|
||||||
try:
|
try:
|
||||||
# standard
|
# asctime with subsecond
|
||||||
template = DateStrptime()
|
template = DateStrptime()
|
||||||
template.setName("MONTH Day Hour:Minute:Second")
|
template.setName("WEEKDAY MONTH Day Hour:Minute:Second[.subsecond] Year")
|
||||||
template.setRegex("\S{3}\s{1,2}\d{1,2} \d{2}:\d{2}:\d{2}")
|
template.setRegex("\S{3} \S{3}\s{1,2}\d{1,2} \d{2}:\d{2}:\d{2}\.\d+ \d{4}")
|
||||||
template.setPattern("%b %d %H:%M:%S")
|
template.setPattern("%a %b %d %H:%M:%S.%f %Y")
|
||||||
self._appendTemplate(template)
|
self._appendTemplate(template)
|
||||||
# asctime
|
# asctime without no subsecond
|
||||||
template = DateStrptime()
|
template = DateStrptime()
|
||||||
template.setName("WEEKDAY MONTH Day Hour:Minute:Second Year")
|
template.setName("WEEKDAY MONTH Day Hour:Minute:Second Year")
|
||||||
template.setRegex("\S{3} \S{3}\s{1,2}\d{1,2} \d{2}:\d{2}:\d{2} \d{4}")
|
template.setRegex("\S{3} \S{3}\s{1,2}\d{1,2} \d{2}:\d{2}:\d{2} \d{4}")
|
||||||
|
@ -64,6 +64,12 @@ class DateDetector:
|
||||||
template.setRegex("\S{3} \S{3}\s{1,2}\d{1,2} \d{2}:\d{2}:\d{2}")
|
template.setRegex("\S{3} \S{3}\s{1,2}\d{1,2} \d{2}:\d{2}:\d{2}")
|
||||||
template.setPattern("%a %b %d %H:%M:%S")
|
template.setPattern("%a %b %d %H:%M:%S")
|
||||||
self._appendTemplate(template)
|
self._appendTemplate(template)
|
||||||
|
# standard - most loose from above 3 so by default follows after
|
||||||
|
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._appendTemplate(template)
|
||||||
# simple date
|
# simple date
|
||||||
template = DateStrptime()
|
template = DateStrptime()
|
||||||
template.setName("Year/Month/Day Hour:Minute:Second")
|
template.setName("Year/Month/Day Hour:Minute:Second")
|
||||||
|
@ -151,7 +157,7 @@ class DateDetector:
|
||||||
self._appendTemplate(template)
|
self._appendTemplate(template)
|
||||||
# MySQL: 130322 11:46:11
|
# MySQL: 130322 11:46:11
|
||||||
template = DateStrptime()
|
template = DateStrptime()
|
||||||
template.setName("MonthDayYear Hour:Minute:Second")
|
template.setName("YearMonthDay Hour:Minute:Second")
|
||||||
template.setRegex("^\d{2}\d{2}\d{2} +\d{1,2}:\d{2}:\d{2}")
|
template.setRegex("^\d{2}\d{2}\d{2} +\d{1,2}:\d{2}:\d{2}")
|
||||||
template.setPattern("%y%m%d %H:%M:%S")
|
template.setPattern("%y%m%d %H:%M:%S")
|
||||||
self._appendTemplate(template)
|
self._appendTemplate(template)
|
||||||
|
@ -174,6 +180,7 @@ class DateDetector:
|
||||||
match = template.matchDate(line)
|
match = template.matchDate(line)
|
||||||
if not match is None:
|
if not match is None:
|
||||||
logSys.debug("Matched time template %s" % template.getName())
|
logSys.debug("Matched time template %s" % template.getName())
|
||||||
|
template.incHits()
|
||||||
return match
|
return match
|
||||||
return None
|
return None
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -59,11 +59,15 @@ class DateTemplate:
|
||||||
|
|
||||||
def getHits(self):
|
def getHits(self):
|
||||||
return self.__hits
|
return self.__hits
|
||||||
|
|
||||||
|
def incHits(self):
|
||||||
|
self.__hits += 1
|
||||||
|
|
||||||
|
def resetHits(self):
|
||||||
|
self.__hits = 0
|
||||||
|
|
||||||
def matchDate(self, line):
|
def matchDate(self, line):
|
||||||
dateMatch = self.__cRegex.search(line)
|
dateMatch = self.__cRegex.search(line)
|
||||||
if not dateMatch is None:
|
|
||||||
self.__hits += 1
|
|
||||||
return dateMatch
|
return dateMatch
|
||||||
|
|
||||||
def getDate(self, line):
|
def getDate(self, line):
|
||||||
|
@ -74,8 +78,7 @@ class DateEpoch(DateTemplate):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
DateTemplate.__init__(self)
|
DateTemplate.__init__(self)
|
||||||
# We already know the format for TAI64N
|
self.setRegex("(?:^|(?P<selinux>(?<=audit\()))\d{10}(?:\.\d{3,6})?(?(selinux)(?=:\d+\)))")
|
||||||
self.setRegex("^\d{10}(\.\d{6})?")
|
|
||||||
|
|
||||||
def getDate(self, line):
|
def getDate(self, line):
|
||||||
date = None
|
date = None
|
||||||
|
|
|
@ -41,7 +41,7 @@ class Regex:
|
||||||
self._matchCache = None
|
self._matchCache = None
|
||||||
# Perform shortcuts expansions.
|
# Perform shortcuts expansions.
|
||||||
# Replace "<HOST>" with default regular expression for host.
|
# Replace "<HOST>" with default regular expression for host.
|
||||||
regex = regex.replace("<HOST>", "(?:::f{4,6}:)?(?P<host>[\w\-.^_]+)")
|
regex = regex.replace("<HOST>", "(?:::f{4,6}:)?(?P<host>[\w\-.^_]*\w)")
|
||||||
if regex.lstrip() == '':
|
if regex.lstrip() == '':
|
||||||
raise RegexException("Cannot add empty regex")
|
raise RegexException("Cannot add empty regex")
|
||||||
try:
|
try:
|
||||||
|
@ -50,7 +50,8 @@ class Regex:
|
||||||
except sre_constants.error:
|
except sre_constants.error:
|
||||||
raise RegexException("Unable to compile regular expression '%s'" %
|
raise RegexException("Unable to compile regular expression '%s'" %
|
||||||
regex)
|
regex)
|
||||||
|
def __str__(self):
|
||||||
|
return "%s(%r)" % (self.__class__.__name__, self._regex)
|
||||||
##
|
##
|
||||||
# Gets the regular expression.
|
# Gets the regular expression.
|
||||||
#
|
#
|
||||||
|
|
|
@ -21,6 +21,8 @@ __author__ = "Cyril Jaquier and Fail2Ban Contributors"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
from failmanager import FailManagerEmpty
|
from failmanager import FailManagerEmpty
|
||||||
from failmanager import FailManager
|
from failmanager import FailManager
|
||||||
from ticket import FailTicket
|
from ticket import FailTicket
|
||||||
|
@ -282,7 +284,7 @@ class Filter(JailThread):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def processLine(self, line):
|
def processLine(self, line, returnRawHost=False, checkAllRegex=False):
|
||||||
"""Split the time portion from log msg and return findFailures on them
|
"""Split the time portion from log msg and return findFailures on them
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
@ -291,6 +293,8 @@ class Filter(JailThread):
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
l = line
|
l = line
|
||||||
l = l.rstrip('\r\n')
|
l = l.rstrip('\r\n')
|
||||||
|
|
||||||
|
logSys.log(7, "Working on line %r", l)
|
||||||
timeMatch = self.dateDetector.matchTime(l)
|
timeMatch = self.dateDetector.matchTime(l)
|
||||||
if timeMatch:
|
if timeMatch:
|
||||||
# Lets split into time part and log part of the line
|
# Lets split into time part and log part of the line
|
||||||
|
@ -302,14 +306,15 @@ class Filter(JailThread):
|
||||||
else:
|
else:
|
||||||
timeLine = l
|
timeLine = l
|
||||||
logLine = l
|
logLine = l
|
||||||
return self.findFailure(timeLine, logLine)
|
return logLine, self.findFailure(timeLine, logLine, returnRawHost, checkAllRegex)
|
||||||
|
|
||||||
def processLineAndAdd(self, line):
|
def processLineAndAdd(self, line):
|
||||||
"""Processes the line for failures and populates failManager
|
"""Processes the line for failures and populates failManager
|
||||||
"""
|
"""
|
||||||
for element in self.processLine(line):
|
for element in self.processLine(line)[1]:
|
||||||
ip = element[0]
|
failregex = element[0]
|
||||||
unixTime = element[1]
|
ip = element[1]
|
||||||
|
unixTime = element[2]
|
||||||
logSys.debug("Processing line with time:%s and ip:%s"
|
logSys.debug("Processing line with time:%s and ip:%s"
|
||||||
% (unixTime, ip))
|
% (unixTime, ip))
|
||||||
if unixTime < MyTime.time() - self.getFindTime():
|
if unixTime < MyTime.time() - self.getFindTime():
|
||||||
|
@ -320,6 +325,7 @@ class Filter(JailThread):
|
||||||
logSys.debug("Ignore %s" % ip)
|
logSys.debug("Ignore %s" % ip)
|
||||||
continue
|
continue
|
||||||
logSys.debug("Found %s" % ip)
|
logSys.debug("Found %s" % ip)
|
||||||
|
## print "D: Adding a ticket for %s" % ((ip, unixTime, [line]),)
|
||||||
self.failManager.addFailure(FailTicket(ip, unixTime, [line]))
|
self.failManager.addFailure(FailTicket(ip, unixTime, [line]))
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -330,11 +336,11 @@ class Filter(JailThread):
|
||||||
# @return: a boolean
|
# @return: a boolean
|
||||||
|
|
||||||
def ignoreLine(self, line):
|
def ignoreLine(self, line):
|
||||||
for ignoreRegex in self.__ignoreRegex:
|
for ignoreRegexIndex, ignoreRegex in enumerate(self.__ignoreRegex):
|
||||||
ignoreRegex.search(line)
|
ignoreRegex.search(line)
|
||||||
if ignoreRegex.hasMatched():
|
if ignoreRegex.hasMatched():
|
||||||
return True
|
return ignoreRegexIndex
|
||||||
return False
|
return None
|
||||||
|
|
||||||
##
|
##
|
||||||
# Finds the failure in a line given split into time and log parts.
|
# Finds the failure in a line given split into time and log parts.
|
||||||
|
@ -343,18 +349,22 @@ class Filter(JailThread):
|
||||||
# to find the logging time.
|
# to find the logging time.
|
||||||
# @return a dict with IP and timestamp.
|
# @return a dict with IP and timestamp.
|
||||||
|
|
||||||
def findFailure(self, timeLine, logLine):
|
def findFailure(self, timeLine, logLine,
|
||||||
|
returnRawHost=False, checkAllRegex=False):
|
||||||
|
logSys.log(5, "Date: %r, message: %r", timeLine, logLine)
|
||||||
failList = list()
|
failList = list()
|
||||||
# Checks if we must ignore this line.
|
# Checks if we must ignore this line.
|
||||||
if self.ignoreLine(logLine):
|
if self.ignoreLine(logLine) is not None:
|
||||||
# The ignoreregex matched. Return.
|
# The ignoreregex matched. Return.
|
||||||
|
logSys.log(7, "Matched ignoreregex and was ignored")
|
||||||
return failList
|
return failList
|
||||||
|
date = self.dateDetector.getUnixTime(timeLine)
|
||||||
# Iterates over all the regular expressions.
|
# Iterates over all the regular expressions.
|
||||||
for failRegex in self.__failRegex:
|
for failRegexIndex, failRegex in enumerate(self.__failRegex):
|
||||||
failRegex.search(logLine)
|
failRegex.search(logLine)
|
||||||
if failRegex.hasMatched():
|
if failRegex.hasMatched():
|
||||||
# The failregex matched.
|
# The failregex matched.
|
||||||
date = self.dateDetector.getUnixTime(timeLine)
|
logSys.log(7, "Matched %s", failRegex)
|
||||||
if date is None:
|
if date is None:
|
||||||
logSys.debug("Found a match for %r but no valid date/time "
|
logSys.debug("Found a match for %r but no valid date/time "
|
||||||
"found for %r. Please file a detailed issue on"
|
"found for %r. Please file a detailed issue on"
|
||||||
|
@ -364,12 +374,17 @@ class Filter(JailThread):
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
host = failRegex.getHost()
|
host = failRegex.getHost()
|
||||||
ipMatch = DNSUtils.textToIp(host, self.__useDns)
|
if returnRawHost:
|
||||||
if ipMatch:
|
failList.append([failRegexIndex, host, date])
|
||||||
for ip in ipMatch:
|
if not checkAllRegex:
|
||||||
failList.append([ip, date])
|
break
|
||||||
# We matched a regex, it is enough to stop.
|
else:
|
||||||
break
|
ipMatch = DNSUtils.textToIp(host, self.__useDns)
|
||||||
|
if ipMatch:
|
||||||
|
for ip in ipMatch:
|
||||||
|
failList.append([failRegexIndex, ip, date])
|
||||||
|
if not checkAllRegex:
|
||||||
|
break
|
||||||
except RegexException, e: # pragma: no cover - unsure if reachable
|
except RegexException, e: # pragma: no cover - unsure if reachable
|
||||||
logSys.error(e)
|
logSys.error(e)
|
||||||
return failList
|
return failList
|
||||||
|
@ -473,7 +488,7 @@ class FileFilter(Filter):
|
||||||
return False
|
return False
|
||||||
# Try to open log file.
|
# Try to open log file.
|
||||||
try:
|
try:
|
||||||
container.open()
|
has_content = container.open()
|
||||||
# see http://python.org/dev/peps/pep-3151/
|
# see http://python.org/dev/peps/pep-3151/
|
||||||
except IOError, e:
|
except IOError, e:
|
||||||
logSys.error("Unable to open %s" % filename)
|
logSys.error("Unable to open %s" % filename)
|
||||||
|
@ -488,7 +503,12 @@ class FileFilter(Filter):
|
||||||
logSys.exception(e)
|
logSys.exception(e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
while True:
|
# yoh: has_content is just a bool, so do not expect it to
|
||||||
|
# change -- loop is exited upon break, and is not entered at
|
||||||
|
# all if upon container opening that one was empty. If we
|
||||||
|
# start reading tested to be empty container -- race condition
|
||||||
|
# might occur leading at least to tests failures.
|
||||||
|
while has_content:
|
||||||
line = container.readline()
|
line = container.readline()
|
||||||
if (line == "") or not self._isActive():
|
if (line == "") or not self._isActive():
|
||||||
# The jail reached the bottom or has been stopped
|
# The jail reached the bottom or has been stopped
|
||||||
|
@ -551,10 +571,20 @@ class FileContainer:
|
||||||
fd = self.__handler.fileno()
|
fd = self.__handler.fileno()
|
||||||
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||||
fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
|
fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
|
||||||
|
# Stat the file before even attempting to read it
|
||||||
|
stats = os.fstat(self.__handler.fileno())
|
||||||
|
if not stats.st_size:
|
||||||
|
# yoh: so it is still an empty file -- nothing should be
|
||||||
|
# read from it yet
|
||||||
|
# print "D: no content -- return"
|
||||||
|
return False
|
||||||
firstLine = self.__handler.readline()
|
firstLine = self.__handler.readline()
|
||||||
# Computes the MD5 of the first line.
|
# Computes the MD5 of the first line.
|
||||||
myHash = md5sum(firstLine).digest()
|
myHash = md5sum(firstLine).digest()
|
||||||
stats = os.fstat(self.__handler.fileno())
|
## print "D: fn=%s hashes=%s/%s inos=%s/%s pos=%s rotate=%s" % (
|
||||||
|
## self.__filename, self.__hash, myHash, stats.st_ino, self.__ino, self.__pos,
|
||||||
|
## self.__hash != myHash or self.__ino != stats.st_ino)
|
||||||
|
## sys.stdout.flush()
|
||||||
# Compare hash and inode
|
# Compare hash and inode
|
||||||
if self.__hash != myHash or self.__ino != stats.st_ino:
|
if self.__hash != myHash or self.__ino != stats.st_ino:
|
||||||
logSys.debug("Log rotation detected for %s" % self.__filename)
|
logSys.debug("Log rotation detected for %s" % self.__filename)
|
||||||
|
@ -563,6 +593,7 @@ class FileContainer:
|
||||||
self.__pos = 0
|
self.__pos = 0
|
||||||
# Sets the file pointer to the last position.
|
# Sets the file pointer to the last position.
|
||||||
self.__handler.seek(self.__pos)
|
self.__handler.seek(self.__pos)
|
||||||
|
return True
|
||||||
|
|
||||||
def readline(self):
|
def readline(self):
|
||||||
if self.__handler is None:
|
if self.__handler is None:
|
||||||
|
@ -576,6 +607,8 @@ class FileContainer:
|
||||||
# Closes the file.
|
# Closes the file.
|
||||||
self.__handler.close()
|
self.__handler.close()
|
||||||
self.__handler = None
|
self.__handler = None
|
||||||
|
## print "D: Closed %s with pos %d" % (handler, self.__pos)
|
||||||
|
## sys.stdout.flush()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -598,9 +631,9 @@ class DNSUtils:
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return socket.gethostbyname_ex(dns)[2]
|
return socket.gethostbyname_ex(dns)[2]
|
||||||
except socket.gaierror:
|
except socket.error, e:
|
||||||
logSys.warn("Unable to find a corresponding IP address for %s"
|
logSys.warn("Unable to find a corresponding IP address for %s: %s"
|
||||||
% dns)
|
% (dns, e))
|
||||||
return list()
|
return list()
|
||||||
dnsToIp = staticmethod(dnsToIp)
|
dnsToIp = staticmethod(dnsToIp)
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue