Merge remote-tracking branch 'origin/master' into debian-releases/experimental

* origin/master:
  Clean up setup.py
  ENH: adding pruned with previous merge trailing \s* in nginx filter
  nginx-http-auth: match when "referrer" is present
  DOC: Update ChangeLog
  DOC: Fix jail.conf(5) man page which had duplicate {fail,ignore}regex
  Correct grammar
  DOC: add thanks for last commit
  DOC: nginx-http-auth filter
  nginx-http-auth filter: match server_name = ""
  ENH: Suppress configuration warnings if non-critical options are not set
  Update comments in shorewall.conf for new settings
  DOC: Improve error logging when specific backend set and fails
  BF: Fix getting jail name from exceptions in beautifier for Python 3+
  DOC: sphinx documentation
  BF: On jail restart reinstatement of bans, fetch one ticket per IP
  Fix 2 more typos that codespell didn't catch
  Add documentation link to systemd service file
debian-releases/experimental
Yaroslav Halchenko 2014-04-12 11:32:02 -04:00
commit 87703c4cfe
73 changed files with 1195 additions and 355 deletions

View File

@ -17,12 +17,15 @@ ver. 0.9.1 (2014/xx/xx) - better, faster, stronger
* journalmatch for recidive incorrect PRIORITY * journalmatch for recidive incorrect PRIORITY
* loglevel couldn't be changed in fail2ban.conf * loglevel couldn't be changed in fail2ban.conf
* Handle case when no sqlite library is available for persistent database * Handle case when no sqlite library is available for persistent database
* Only reban once per IP from database on fail2ban restart
* Nginx filter to support missing server_name. Closes gh-676
- New features: - New features:
- Enhancements - Enhancements
* Fail2ban-regex - add print-all-matched option. Closes gh-652 * Fail2ban-regex - add print-all-matched option. Closes gh-652
* Suppress fail2ban-client warnings for non-critical config options
ver. 0.9.0 (2014/03/14 - beta ver. 0.9.0 (2014/03/14 - beta
---------- ----------

17
DEVELOP
View File

@ -1,4 +1,4 @@
__ _ _ ___ _ .. __ _ _ ___ _
/ _|__ _(_) |_ ) |__ __ _ _ _ / _|__ _(_) |_ ) |__ __ _ _ _
| _/ _` | | |/ /| '_ \/ _` | ' \ | _/ _` | | |/ /| '_ \/ _` | ' \
|_| \__,_|_|_/___|_.__/\__,_|_||_| |_| \__,_|_|_/___|_.__/\__,_|_||_|
@ -25,6 +25,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 administrators * Don't introduce regressions that will make it hard for systems administrators
to update; to update;
@ -52,7 +53,7 @@ for more details.
Install the package python-coverage to visualise your test coverage. Run the Install the package python-coverage to visualise your test coverage. Run the
following (note: on Debian-based systems, the script is called following (note: on Debian-based systems, the script is called
`python-coverage`): `python-coverage`)::
coverage run bin/fail2ban-testcases coverage run bin/fail2ban-testcases
coverage html coverage html
@ -62,11 +63,11 @@ 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.
Manual Execution. To run in a development environment do: Manual Execution. To run in a development environment do::
./fail2ban-client -c config/ -s /tmp/f2b.sock -i start ./fail2ban-client -c config/ -s /tmp/f2b.sock -i start
some quick commands: some quick commands::
status status
add test pyinotify add test pyinotify
@ -130,10 +131,10 @@ Git
Use the following tags in your commit messages: Use the following tags in your commit messages:
'BF:' for bug fixes * 'BF:' for bug fixes
'DOC:' for documentation fixes * 'DOC:' for documentation fixes
'ENH:' for enhancements * 'ENH:' for enhancements
'TST:' for commits concerning tests only (thus not touching the main code-base) * 'TST:' for commits concerning tests only (thus not touching the main code-base)
Multiple tags could be joined with +, e.g. "BF+TST:". Multiple tags could be joined with +, e.g. "BF+TST:".

129
FILTERS
View File

@ -1,4 +1,4 @@
__ _ _ ___ _ .. __ _ _ ___ _
/ _|__ _(_) |_ ) |__ __ _ _ _ / _|__ _(_) |_ ) |__ __ _ _ _
| _/ _` | | |/ /| '_ \/ _` | ' \ | _/ _` | | |/ /| '_ \/ _` | ' \
|_| \__,_|_|_/___|_.__/\__,_|_||_| |_| \__,_|_|_/___|_.__/\__,_|_||_|
@ -7,10 +7,8 @@
Developing Filters Developing Filters
================================================================================ ================================================================================
Filters
=======
Filters are tricky. They need to: Filters are tricky. They need to:
* work with a variety of the versions of the software that generates the logs; * work with a variety of the versions of the software that generates the logs;
* work with the range of logging configuration options available in the * work with the range of logging configuration options available in the
software; software;
@ -31,10 +29,11 @@ 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 will be automagically updated with future commits you would push to
complete it). complete it).
Filter test cases Filter Test Cases
----------------- =================
Purpose: Purpose
-------
Start by finding the log messages that the application generates related to 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 some form of authentication failure. If you are adding to an existing filter
@ -49,7 +48,8 @@ and exim-spam at log messages related to spam.
Even if it is a new filter you may consider separating the log messages into Even if it is a new filter you may consider separating the log messages into
different filters based on purpose. different filters based on purpose.
Cause: Cause
-----
Are some of the log lines a result of the same action? For example, is a PAM 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 failure log message, followed by an application specific failure message the
@ -65,7 +65,8 @@ 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 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. these are true make a note of this in the jail.conf example that you provide.
Samples: Samples
-------
It is important to include log file samples so any future change in the regular 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. expression will still work with the log lines you have identified.
@ -93,10 +94,11 @@ If the mechanism to create the log message isn't obvious provide a
configuration and/or sample scripts testcases/files/config/{filtername} and configuration and/or sample scripts testcases/files/config/{filtername} and
reference these in the comments above the log line. reference these in the comments above the log line.
FailJSON metadata: FailJSON metadata
-----------------
A failJSON metadata is a comment immediately above the log message. It will A failJSON metadata is a comment immediately above the log message. It will
look like: look like::
# failJSON: { "time": "2013-06-10T10:10:59", "match": true , "host": "93.184.216.119" } # failJSON: { "time": "2013-06-10T10:10:59", "match": true , "host": "93.184.216.119" }
@ -104,7 +106,7 @@ 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-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 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 Aug 14 10am UTC, and 2004 if afterwards. Here is an example failJSON
line preceding a sample log line: line preceding a sample log line::
# failJSON: { "time": "2005-03-24T15:25:51", "match": true , "host": "198.51.100.87" } # 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 Mar 24 15:25:51 buffalo1 dropbear[4092]: bad password attempt for 'root' from 198.51.100.87:5543
@ -116,23 +118,24 @@ 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. "match": false in the failJSON and describe the reason in the comment above.
After developing regexes, the following command will test all failJSON metadata After developing regexes, the following command will test all failJSON metadata
against the log lines in all sample log files against the log lines in all sample log files::
./fail2ban-testcases testSampleRegex ./fail2ban-testcases testSampleRegex
Developing Filter Regular Expressions Developing Filter Regular Expressions
------------------------------------- =====================================
Date/Time: Date/Time
---------
At the moment, Fail2Ban depends on log lines to have time stamps. That is why 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 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 Fail2Ban. Copy the time component from the log line and append an IP address to
test with following command: test with following command::
./fail2ban-regex "2013-09-19 02:46:12 1.2.3.4" "<HOST>" ./fail2ban-regex "2013-09-19 02:46:12 1.2.3.4" "<HOST>"
Output of such command should contain something like: Output of such command should contain something like::
Date template hits: Date template hits:
|- [# of hits] date format |- [# of hits] date format
@ -144,10 +147,11 @@ 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 that more specific matches occur first and that there is no confusion between a
Day and a Month. Day and a Month.
Filter file: Filter file
-----------
The filter is specified in a config/filter.d/{filtername}.conf file. 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: can have sections INCLUDES (optional) and Definition as follows::
[INCLUDES] [INCLUDES]
@ -166,7 +170,8 @@ 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) through string Interpolations (see http://docs.python.org/2.7/library/configparser.html)
General rules: General rules
-------------
Use "before" if you need to include a common set of rules, like syslog or if 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. there is a common set of regexes for multiple filters.
@ -178,10 +183,11 @@ 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 would use it is if in trying to avoid using it, you end up with an unreadable
failregex. failregex.
Syslog: Syslog
------
If your application logs to syslog you can take advantage of log line prefix If your application logs to syslog you can take advantage of log line prefix
definitions present in common.conf. So as a base use: definitions present in common.conf. So as a base use::
[INCLUDES] [INCLUDES]
@ -197,14 +203,15 @@ In this example common.conf defines __prefix_line which also contains the
_daemon name (in syslog terms the service) you have just specified. _daemon _daemon name (in syslog terms the service) you have just specified. _daemon
can also be a regex. can also be a regex.
For example, to capture following line _daemon should be set to "dovecot" 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 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: and then ``^%(__prefix_line)s`` would match "Dec 12 11:19:11 dunnart dovecot:
". Note it matches the trailing space(s) as well. ". Note it matches the trailing space(s) as well.
Substitutions (AKA string interpolations): Substitutions (AKA string interpolations)
-----------------------------------------
We have used string interpolations in above examples. They are useful for We have used string interpolations in above examples. They are useful for
making the regexes more readable, reuse generic patterns in multiple failregex making the regexes more readable, reuse generic patterns in multiple failregex
@ -213,7 +220,8 @@ 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 occurrences of %(_name)s within the same section or anywhere in the config file
if defined in [DEFAULT] section. if defined in [DEFAULT] section.
Regular Expressions: Regular Expressions
-------------------
Regular expressions (failregex, ignoreregex) assume that the date/time has been Regular expressions (failregex, ignoreregex) assume that the date/time has been
removed from the log line (this is just how fail2ban works internally ATM). removed from the log line (this is just how fail2ban works internally ATM).
@ -236,29 +244,33 @@ 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 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. remind you e.g. which characters you need to escape and which you don't.
Developing/testing a regex: Developing/testing a regex
--------------------------
You can develop a regex in a file or using command line depending on your 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 preference. You can also use samples you have already created in the test cases
or test them one at a time. or test them one at a time.
The general tool for testing Fail2Ban regexes is fail2ban-regex. To see how to The general tool for testing Fail2Ban regexes is fail2ban-regex. To see how to
use it run: use it run::
./fail2ban-regex --help ./fail2ban-regex --help
Take note of -l heavydebug / -l debug and -v as they might be very useful. 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 .. 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 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 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 parts are constrained and different formats depending on configuration or
less common usages. less common usages.
TIP: For looking through source code - http://sourcecodebrowser.com/ . It has .. TIP::
For looking through source code - http://sourcecodebrowser.com/ . It has
call graphs and can browse different versions. call graphs and can browse different versions.
TIP: Some applications log spaces at the end. If you are not sure add \s*$ as .. TIP::
Some applications log spaces at the end. If you are not sure add \s*$ as
the end part of the regex. the end part of the regex.
If your regex is not matching, http://www.debuggex.com/?flavor=python can help If your regex is not matching, http://www.debuggex.com/?flavor=python can help
@ -277,13 +289,15 @@ 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 Please spread the good word about Debuggex - Serge Toarca is kindly continuing
its free availability to Open Source developers. its free availability to Open Source developers.
Finishing up: Finishing up
------------
If you've added a new filter, add a new entry in config/jail.conf. The theory 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 here is that a user will create a jail.local with [filtername]\nenable=true to
enable your jail. enable your jail.
So more specifically in the [filter] section in jail.conf: So more specifically in the [filter] section in jail.conf:
* ensure that you have "enabled = false" (users will enable as needed); * ensure that you have "enabled = false" (users will enable as needed);
* use "filter =" set to your filter name; * use "filter =" set to your filter name;
* use a typical action to disable ports associated with the application; * use a typical action to disable ports associated with the application;
@ -295,7 +309,7 @@ Submit github pull request (See "Pull Requests" above) for
github.com/fail2ban/fail2ban containing your great work. github.com/fail2ban/fail2ban containing your great work.
Filter Security Filter Security
--------------- ===============
Poor filter regular expressions are susceptible to DoS attacks. Poor filter regular expressions are susceptible to DoS attacks.
@ -321,33 +335,33 @@ Examples of poor filters
1. Too restrictive 1. Too restrictive
We find a log message: We find a log message::
Apr-07-13 07:08:36 Invalid command fial2ban from 1.2.3.4 Apr-07-13 07:08:36 Invalid command fial2ban from 1.2.3.4
We make a failregex We make a failregex::
^Invalid command \S+ from <HOST> ^Invalid command \S+ from <HOST>
Now think evil. The user does the command 'blah from 1.2.3.44' Now think evil. The user does the command 'blah from 1.2.3.44'
The program diligently logs: The program diligently logs::
Apr-07-13 07:08:36 Invalid command blah from 1.2.3.44 from 1.2.3.4 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. 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. The fix here is that the command can be anything so .* is appropriate::
^Invalid command .* from <HOST> ^Invalid command .* from <HOST>
Here the .* will match until the end of the string. Then realise it has more to 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 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 $. 1.2.3.4 correctly. Since the <HOST> is always at the end, end the regex with a $::
^Invalid command .* from <HOST>$ ^Invalid command .* from <HOST>$
Note if we'd just had the expression: Note if we'd just had the expression::
^Invalid command \S+ from <HOST>$ ^Invalid command \S+ from <HOST>$
@ -359,16 +373,16 @@ banned.
From the Apache vulnerability CVE-2013-2178 From the Apache vulnerability CVE-2013-2178
( original ref: https://vndh.net/note:fail2ban-089-denial-service ). ( original ref: https://vndh.net/note:fail2ban-089-denial-service ).
An example bad regex for Apache: An example bad regex for Apache::
failregex = [[]client <HOST>[]] user .* not found failregex = [[]client <HOST>[]] user .* not found
Since the user can do a get request on: Since the user can do a get request on::
GET /[client%20192.168.0.1]%20user%20root%20not%20found HTTP/1.0 GET /[client%20192.168.0.1]%20user%20root%20not%20found HTTP/1.0
Host: remote.site Host: remote.site
Now the log line will be: 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 [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
@ -379,27 +393,27 @@ regex and blocks 192.168.33.1 as a denial of service from the HTTP requester.
From: https://github.com/fail2ban/fail2ban/pull/426 From: https://github.com/fail2ban/fail2ban/pull/426
An example ssh log (simplified) An example ssh log (simplified)::
Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser remoteuser Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser remoteuser
As we assume username can include anything including spaces its prudent to put As we assume username can include anything including spaces its prudent to put
.* here. The remote user can also exist as anything so lets not make assumptions again. .* here. The remote user can also exist as anything so lets not make assumptions again::
failregex = ^%(__prefix_line)sFailed \S+ for .* from <HOST>( port \d*)?( ssh\d+)?(: ruser .*)?$ failregex = ^%(__prefix_line)sFailed \S+ for .* from <HOST>( port \d*)?( ssh\d+)?(: ruser .*)?$
So this works. The problem is if the .* after remote user is injected by the So this works. The problem is if the .* after remote user is injected by the
user to be 'from 1.2.3.4'. The resultant log line is. user to be 'from 1.2.3.4'. The resultant log line is::
Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser from 1.2.3.4 Sep 29 17:15:02 spaceman sshd[12946]: Failed password for user from 127.0.0.1 port 20000 ssh1: ruser from 1.2.3.4
Testing with: Testing with::
fail2ban-regex -v 'Sep 29 17:15:02 Failed password for user from 127.0.0.1 port 20000 ssh1: ruser from 1.2.3.4' '^ Failed \S+ for .* from <HOST>( port \d*)?( ssh\d+)?(: ruser .*)?$' fail2ban-regex -v 'Sep 29 17:15:02 Failed password for user from 127.0.0.1 port 20000 ssh1: ruser from 1.2.3.4' '^ Failed \S+ for .* from <HOST>( port \d*)?( ssh\d+)?(: ruser .*)?$'
TIP: I've removed the bit that matches __prefix_line from the regex and log. .. TIP:: I've removed the bit that matches __prefix_line from the regex and log.
Shows: Shows::
1) [1] ^ Failed \S+ for .* from <HOST>( port \d*)?( ssh\d+)?(: ruser .*)?$ 1) [1] ^ Failed \S+ for .* from <HOST>( port \d*)?( ssh\d+)?(: ruser .*)?$
1.2.3.4 Sun Sep 29 17:15:02 2013 1.2.3.4 Sun Sep 29 17:15:02 2013
@ -412,14 +426,14 @@ The result was that 1.2.3.4 was matched, injected by the user, and the wrong IP
was banned. was banned.
The solution here is to make the first .* non-greedy with .*?. Here it matches The solution here is to make the first .* non-greedy with .*?. Here it matches
as little as required and the fail2ban-regex tool shows the output: as little as required and the fail2ban-regex tool shows the output::
fail2ban-regex -v 'Sep 29 17:15:02 Failed password for user from 127.0.0.1 port 20000 ssh1: ruser from 1.2.3.4' '^ Failed \S+ for .*? from <HOST>( port \d*)?( ssh\d+)?(: ruser .*)?$' fail2ban-regex -v 'Sep 29 17:15:02 Failed password for user from 127.0.0.1 port 20000 ssh1: ruser from 1.2.3.4' '^ Failed \S+ for .*? from <HOST>( port \d*)?( ssh\d+)?(: ruser .*)?$'
1) [1] ^ Failed \S+ for .*? from <HOST>( port \d*)?( ssh\d+)?(: ruser .*)?$ 1) [1] ^ Failed \S+ for .*? from <HOST>( port \d*)?( ssh\d+)?(: ruser .*)?$
127.0.0.1 Sun Sep 29 17:15:02 2013 127.0.0.1 Sun Sep 29 17:15:02 2013
So the general case here is a log line that contains: So the general case here is a log line that contains::
(fixed_data_1)<HOST>(fixed_data_2)(user_injectable_data) (fixed_data_1)<HOST>(fixed_data_2)(user_injectable_data)
@ -427,20 +441,21 @@ Where the regex that matches fixed_data_1 is gready and matches the entire
string, before moving backwards and user_injectable_data can match the entire string, before moving backwards and user_injectable_data can match the entire
string. string.
Another case: Another case
------------
ref: https://www.debuggex.com/r/CtAbeKMa2sDBEfA2/0 ref: https://www.debuggex.com/r/CtAbeKMa2sDBEfA2/0
A webserver logs the following without URL escaping: A webserver logs the following without URL escaping::
[error] 2865#0: *66647 user "xyz" was not found in "/file", client: 1.2.3.1, server: www.host.com, request: "GET ", client: 3.2.1.1, server: fake.com, request: "GET exploited HTTP/3.3", host: "injected.host", host: "www.myhost.com" [error] 2865#0: *66647 user "xyz" was not found in "/file", client: 1.2.3.1, server: www.host.com, request: "GET ", client: 3.2.1.1, server: fake.com, request: "GET exploited HTTP/3.3", host: "injected.host", host: "www.myhost.com"
regex: regex::
failregex = ^ \[error\] \d+#\d+: \*\d+ user "\S+":? (?:password mismatch|was not found in ".*"), client: <HOST>, server: \S+, request: "\S+ .+ HTTP/\d+\.\d+", host: "\S+" failregex = ^ \[error\] \d+#\d+: \*\d+ user "\S+":? (?:password mismatch|was not found in ".*"), client: <HOST>, server: \S+, request: "\S+ .+ HTTP/\d+\.\d+", host: "\S+"
The .* matches to the end of the string. Finds that it can't continue to match The .* matches to the end of the string. Finds that it can't continue to match
", client ... so it moves from the back and find that the user injected web URL: ", client ... so it moves from the back and find that the user injected web URL::
", client: 3.2.1.1, server: fake.com, request: "GET exploited HTTP/3.3", host: "injected.host ", client: 3.2.1.1, server: fake.com, request: "GET exploited HTTP/3.3", host: "injected.host
@ -453,14 +468,14 @@ beyond <HOST>.
4. Application generates two identical log messages with different meanings 4. Application generates two identical log messages with different meanings
If the application generates the following two messages under different If the application generates the following two messages under different
circumstances: circumstances::
client <IP>: authentication failed client <IP>: authentication failed
client <USER>: authentication failed client <USER>: authentication failed
Then it's obvious that a regex of "^client <HOST>: authentication Then it's obvious that a regex of ``^client <HOST>: authentication
failed$" will still cause problems if the user can trigger the second failed$`` will still cause problems if the user can trigger the second
log message with a <USER> of 123.1.1.1. log message with a <USER> of 123.1.1.1.
Here there's nothing to do except request/change the application so it logs Here there's nothing to do except request/change the application so it logs

139
RELEASE
View File

@ -1,4 +1,4 @@
__ _ _ ___ _ .. __ _ _ ___ _
/ _|__ _(_) |_ ) |__ __ _ _ _ / _|__ _(_) |_ ) |__ __ _ _ _
| _/ _` | | |/ /| '_ \/ _` | ' \ | _/ _` | | |/ /| '_ \/ _` | ' \
|_| \__,_|_|_/___|_.__/\__,_|_||_| |_| \__,_|_|_/___|_.__/\__,_|_||_|
@ -7,7 +7,10 @@
How to do a release for Fail2Ban How to do a release for Fail2Ban
================================================================================ ================================================================================
# Check distribution patches and see if they can be included Preparation
===========
* Check distribution patches and see if they can be included
* https://apps.fedoraproject.org/packages/fail2ban/sources * https://apps.fedoraproject.org/packages/fail2ban/sources
* http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/net-analyzer/fail2ban/ * http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/net-analyzer/fail2ban/
@ -16,7 +19,8 @@ How to do a release for Fail2Ban
* http://sophie.zarb.org/sources/fail2ban (Mageia) * http://sophie.zarb.org/sources/fail2ban (Mageia)
* https://trac.macports.org/browser/trunk/dports/security/fail2ban * https://trac.macports.org/browser/trunk/dports/security/fail2ban
# Check distribution outstanding bugs
* Check distribution outstanding bugs
* https://github.com/fail2ban/fail2ban/issues?sort=updated&state=open * https://github.com/fail2ban/fail2ban/issues?sort=updated&state=open
* http://bugs.debian.org/cgi-bin/pkgreport.cgi?dist=unstable;package=fail2ban * http://bugs.debian.org/cgi-bin/pkgreport.cgi?dist=unstable;package=fail2ban
@ -29,132 +33,153 @@ How to do a release for Fail2Ban
* https://bugs.mageia.org/buglist.cgi?quicksearch=fail2ban * https://bugs.mageia.org/buglist.cgi?quicksearch=fail2ban
* https://build.opensuse.org/package/requests/openSUSE:Factory/fail2ban * https://build.opensuse.org/package/requests/openSUSE:Factory/fail2ban
# Make sure the tests pass
* Make sure the tests pass::
./fail2ban-testcases-all ./fail2ban-testcases-all
# Ensure the version is correct * Ensure the version is correct in:
in:
* ./fail2ban/version.py * ./fail2ban/version.py
* top of ChangeLog * top of ChangeLog
* README.md * README.md
# Ensure the MANIFEST is complete
Run: * Ensure the MANIFEST is complete
* Run::
python setup.py sdist python setup.py sdist
Look for errors like: * Look for errors like::
'testcases/files/logs/mysqld.log' not a regular file -- skipping '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 * Which indicates that testcases/files/logs/mysqld.log has been moved or is a directory::
tar -C /tmp -jxf dist/fail2ban-0.9.0.tar.bz2 tar -C /tmp -jxf dist/fail2ban-0.9.0.tar.bz2
# clean up current direcory * clean up current direcory::
diff -rul --exclude \*.pyc . /tmp/fail2ban-0.9.0/ diff -rul --exclude \*.pyc . /tmp/fail2ban-0.9.0/
# Only differences should be files that you don't want distributed. * Only differences should be files that you don't want distributed.
# Ensure the tests work from the tarball
* Ensure the tests work from the tarball::
cd /tmp/fail2ban-0.9.0/ && export PYTHONPATH=`pwd` && bin/fail2ban-testcases cd /tmp/fail2ban-0.9.0/ && export PYTHONPATH=`pwd` && bin/fail2ban-testcases
# 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.12.. | sed -e 's,^[ 0-9\t]*,,g' | tr '\n' '\|' | sed -e 's:|:, :g' git shortlog -sn 0.8.12.. | 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.
* Ensure the top entry of the ChangeLog has the right version and current date.
Ensure the top entry of the ChangeLog has the right version and current date. * Update man pages::
# Update man pages
(cd man ; ./generate-man ) (cd man ; ./generate-man )
git commit -m 'DOC/ENH: update man pages for release' man/* git commit -m 'DOC/ENH: update man pages for release' man/*
# Cleanout TODO file with the finished stuff * Cleanout TODO file with the finished stuff
# Prepare source and rpm binary distributions * Prepare source and rpm binary distributions::
python setup.py sdist python setup.py sdist
* Broken for now: python setup.py bdist_rpm
* Broken for now: python setup.py upload
Broken for now: python setup.py bdist_rpm
Broken for now: python setup.py upload
# Tag the release by using a signed (and annotated) tag. Cut/paste * Tag the release by using a signed (and annotated) tag. Cut/paste
release ChangeLog entry as tag annotation release ChangeLog entry as tag annotation::
git tag -s 0.9.1 git tag -s 0.9.1
# Prerelease (option) Pre Release
===========
# Provide a release sample to distributors * Provide a release sample to distributors
* Arch Linux: * Arch Linux:
https://www.archlinux.org/packages/community/any/fail2ban/
* https://www.archlinux.org/packages/community/any/fail2ban/
* Debian: Yaroslav Halchenko <debian@onerussian.com> * Debian: Yaroslav Halchenko <debian@onerussian.com>
http://packages.qa.debian.org/f/fail2ban.html
* http://packages.qa.debian.org/f/fail2ban.html
* FreeBSD: Christoph Theis theis@gmx.at>, Nick Hilliard <nick@foobar.org> * 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 * 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> * Fedora: Axel Thimm <Axel.Thimm@atrpms.net>
https://apps.fedoraproject.org/packages/fail2ban
http://pkgs.fedoraproject.org/cgit/fail2ban.git * https://apps.fedoraproject.org/packages/fail2ban
https://admin.fedoraproject.org/pkgdb/acls/bugs/fail2ban * http://pkgs.fedoraproject.org/cgit/fail2ban.git
* https://admin.fedoraproject.org/pkgdb/acls/bugs/fail2ban
* Gentoo: netmon@gentoo.org * 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 * 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> * openSUSE: Stephan Kulow <coolo@suse.com>
https://build.opensuse.org/package/show/openSUSE:Factory/fail2ban
* https://build.opensuse.org/package/show/openSUSE:Factory/fail2ban
* Mac Ports: @Malbrouck on github (gh-49) * Mac Ports: @Malbrouck on github (gh-49)
https://trac.macports.org/browser/trunk/dports/security/fail2ban/Portfile
* https://trac.macports.org/browser/trunk/dports/security/fail2ban/Portfile
* Mageia: * Mageia:
https://bugs.mageia.org/buglist.cgi?quicksearch=fail2ban
An potentially to the fail2ban-users email list. * https://bugs.mageia.org/buglist.cgi?quicksearch=fail2ban
# Wait for feedback from distributors * An potentially to the fail2ban-users email list.
# 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 * Wait for feedback from distributors
# Upload source/binaries to sourceforge http://sourceforge.net/projects/fail2ban/ * 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::
# Run the following and update the wiki with output:
python -c 'import fail2ban.protocol; fail2ban.protocol.printWiki()' python -c 'import fail2ban.protocol; fail2ban.protocol.printWiki()'
page: http://www.fail2ban.org/wiki/index.php/Commands * page: http://www.fail2ban.org/wiki/index.php/Commands
* Update: * Update:
http://www.fail2ban.org/wiki/index.php?title=Template:Fail2ban_Versions&action=edit
http://www.fail2ban.org/wiki/index.php?title=Template:Fail2ban_News&action=edit * http://www.fail2ban.org/wiki/index.php?title=Template:Fail2ban_Versions&action=edit
move old bits to:
http://www.fail2ban.org/wiki/index.php?title=Template:Fail2ban_OldNews&action=edit
http://www.fail2ban.org/wiki/index.php/ChangeLog * http://www.fail2ban.org/wiki/index.php?title=Template:Fail2ban_News&action=edit
http://www.fail2ban.org/wiki/index.php/Requirements (Check requirement) * move old bits to http://www.fail2ban.org/wiki/index.php?title=Template:Fail2ban_OldNews&action=edit
http://www.fail2ban.org/wiki/index.php/Features
* 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/Features
* See if any filters are upgraded: * See if any filters are upgraded:
http://www.fail2ban.org/wiki/index.php/Special:AllPages 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
Post Release Post Release
============ ============
Add the following to the top of the ChangeLog Add the following to the top of the ChangeLog::
ver. 0.9.1 (2014/XX/XXX) - wanna-be-released ver. 0.9.1 (2014/XX/XXX) - wanna-be-released
----------- -----------
@ -168,5 +193,5 @@ ver. 0.9.1 (2014/XX/XXX) - wanna-be-released
Alter the git shortlog command in the previous section to refer to the just Alter the git shortlog command in the previous section to refer to the just
released version. released version.
and adjust common/version.py to carry .dev suffix to signal and adjust fail2ban/version.py to carry .dev suffix to signal
a version under development. a version under development.

3
THANKS
View File

@ -100,8 +100,9 @@ Vaclav Misek
Vincent Deffontaines Vincent Deffontaines
Yaroslav Halchenko Yaroslav Halchenko
Winston Smith Winston Smith
ykimon
Yehuda Katz Yehuda Katz
ykimon
Yung-Chin Oei
Zbigniew Jędrzejewski-Szmek Zbigniew Jędrzejewski-Szmek
zugeschmiert zugeschmiert
Zurd Zurd

View File

@ -5,7 +5,7 @@
# offending IP address. # offending IP address.
# This uses the https://abusix.com/contactdb.html to lookup abuse contacts. # This uses the https://abusix.com/contactdb.html to lookup abuse contacts.
# #
# DEPENDANCIES: # DEPENDENCIES:
# This requires the dig command from bind-utils # This requires the dig command from bind-utils
# #
# You should provide the <logpath> in the jail config - lines from the log # You should provide the <logpath> in the jail config - lines from the log

View File

@ -9,7 +9,9 @@
# connections. So if the attempter goes on trying using the same connection # connections. So if the attempter goes on trying using the same connection
# he could even log in. In order to get the same behavior of the iptable # he could even log in. In order to get the same behavior of the iptable
# action (so that the ban is immediate) the /etc/shorewall/shorewall.conf # action (so that the ban is immediate) the /etc/shorewall/shorewall.conf
# file should me modified with "BLACKLISTNEWONLY=No". # file should me modified with "BLACKLISTNEWONLY=No". Note that as of
# Shorewall 4.5.13 BLACKLISTNEWONLY is deprecated; however the equivalent
# of BLACKLISTNEWONLY=No can now be achieved by setting BLACKLIST="ALL".
# #
[Definition] [Definition]

View File

@ -10,7 +10,7 @@
# password incorrectly. # password incorrectly.
# * For filters that have a low likelihood of receiving human errors # * For filters that have a low likelihood of receiving human errors
# #
# DEPENDANCIES: # DEPENDENCIES:
# #
# This requires the dig command from bind-utils # This requires the dig command from bind-utils
# #

View File

@ -52,7 +52,7 @@ pidfile = /var/run/fail2ban/fail2ban.pid
# Options: dbfile # Options: dbfile
# Notes.: Set the file for the fail2ban persistent data to be stored. # Notes.: Set the file for the fail2ban persistent data to be stored.
# A value of ":memory:" means database is only stored in memory # A value of ":memory:" means database is only stored in memory
# and data is lost once fail2ban is stops. # and data is lost when fail2ban is stopped.
# A value of "None" disables the database. # A value of "None" disables the database.
# Values: [ None :memory: FILE ] Default: /var/lib/fail2ban/fail2ban.sqlite3 # Values: [ None :memory: FILE ] Default: /var/lib/fail2ban/fail2ban.sqlite3
dbfile = /var/lib/fail2ban/fail2ban.sqlite3 dbfile = /var/lib/fail2ban/fail2ban.sqlite3

View File

@ -4,7 +4,7 @@
[Definition] [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+"\s*$ 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+"(, referrer: "\S+")?\s*$
ignoreregex = ignoreregex =

177
doc/Makefile Normal file
View File

@ -0,0 +1,177 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build2
PAPER =
BUILDDIR = ""build
# User-friendly check for sphinx-build2
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Fail2Ban.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Fail2Ban.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/Fail2Ban"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Fail2Ban"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."

260
doc/conf.py Normal file
View File

@ -0,0 +1,260 @@
# -*- coding: utf-8 -*-
import sys
import os
sys.path.insert(0, ".")
sys.path.insert(0, "..")
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'numpydoc',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Fail2Ban'
copyright = u'2014'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
from fail2ban.version import version as fail2ban_version
from distutils.version import LooseVersion
fail2ban_loose_version = LooseVersion(fail2ban_version)
# The short X.Y version.
version = ".".join(str(_) for _ in fail2ban_loose_version.version[:2])
# The full version, including alpha/beta/rc tags.
release = fail2ban_version
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['build']
# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'Fail2Bandoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'Fail2Ban.tex', u'Fail2Ban Developers\' Documentation',
u'', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'fail2ban', u'Fail2Ban Developers\' Documentation',
[u''], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'Fail2Ban', u'Fail2Ban Developers\' Documentation',
u'', 'Fail2Ban', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
autodoc_default_flags = ['members', 'inherited-members', 'undoc-members', 'show-inheritance']

1
doc/develop.rst Normal file
View File

@ -0,0 +1 @@
.. include:: ../DEVELOP

View File

@ -0,0 +1,7 @@
fail2ban.client.actionreader module
===================================
.. automodule:: fail2ban.client.actionreader
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.client.beautifier module
=================================
.. automodule:: fail2ban.client.beautifier
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.client.configparserinc module
======================================
.. automodule:: fail2ban.client.configparserinc
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.client.configreader module
===================================
.. automodule:: fail2ban.client.configreader
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.client.configurator module
===================================
.. automodule:: fail2ban.client.configurator
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.client.csocket module
==============================
.. automodule:: fail2ban.client.csocket
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.client.fail2banreader module
=====================================
.. automodule:: fail2ban.client.fail2banreader
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.client.filterreader module
===================================
.. automodule:: fail2ban.client.filterreader
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.client.jailreader module
=================================
.. automodule:: fail2ban.client.jailreader
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.client.jailsreader module
==================================
.. automodule:: fail2ban.client.jailsreader
:members:
:undoc-members:
:show-inheritance:

15
doc/fail2ban.client.rst Normal file
View File

@ -0,0 +1,15 @@
fail2ban.client package
=======================
.. toctree::
fail2ban.client.actionreader
fail2ban.client.beautifier
fail2ban.client.configparserinc
fail2ban.client.configreader
fail2ban.client.configurator
fail2ban.client.csocket
fail2ban.client.fail2banreader
fail2ban.client.filterreader
fail2ban.client.jailreader
fail2ban.client.jailsreader

View File

@ -0,0 +1,7 @@
fail2ban.exceptions module
==========================
.. automodule:: fail2ban.exceptions
:members:
:undoc-members:
:show-inheritance:

7
doc/fail2ban.helpers.rst Normal file
View File

@ -0,0 +1,7 @@
fail2ban.helpers module
=======================
.. automodule:: fail2ban.helpers
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.protocol module
========================
.. automodule:: fail2ban.protocol
:members:
:undoc-members:
:show-inheritance:

12
doc/fail2ban.rst Normal file
View File

@ -0,0 +1,12 @@
fail2ban package
================
.. toctree::
fail2ban.client
fail2ban.server
fail2ban.exceptions
fail2ban.helpers
fail2ban.protocol
fail2ban.version

View File

@ -0,0 +1,7 @@
fail2ban.server.action module
=============================
.. automodule:: fail2ban.server.action
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.actions module
==============================
.. automodule:: fail2ban.server.actions
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.asyncserver module
==================================
.. automodule:: fail2ban.server.asyncserver
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.banmanager module
=================================
.. automodule:: fail2ban.server.banmanager
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.database module
===============================
.. automodule:: fail2ban.server.database
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.datedetector module
===================================
.. automodule:: fail2ban.server.datedetector
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.datetemplate module
===================================
.. automodule:: fail2ban.server.datetemplate
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.faildata module
===============================
.. automodule:: fail2ban.server.faildata
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.failmanager module
==================================
.. automodule:: fail2ban.server.failmanager
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.failregex module
================================
.. automodule:: fail2ban.server.failregex
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.filter module
=============================
.. automodule:: fail2ban.server.filter
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.filtergamin module
==================================
.. automodule:: fail2ban.server.filtergamin
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.filterpoll module
=================================
.. automodule:: fail2ban.server.filterpoll
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.filterpyinotify module
======================================
.. automodule:: fail2ban.server.filterpyinotify
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.filtersystemd module
====================================
.. automodule:: fail2ban.server.filtersystemd
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.jail module
===========================
.. automodule:: fail2ban.server.jail
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.jails module
============================
.. automodule:: fail2ban.server.jails
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.jailthread module
=================================
.. automodule:: fail2ban.server.jailthread
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.mytime module
=============================
.. automodule:: fail2ban.server.mytime
:members:
:undoc-members:
:show-inheritance:

28
doc/fail2ban.server.rst Normal file
View File

@ -0,0 +1,28 @@
fail2ban.server package
=======================
.. toctree::
fail2ban.server.action
fail2ban.server.actions
fail2ban.server.asyncserver
fail2ban.server.banmanager
fail2ban.server.database
fail2ban.server.datedetector
fail2ban.server.datetemplate
fail2ban.server.faildata
fail2ban.server.failmanager
fail2ban.server.failregex
fail2ban.server.filter
fail2ban.server.filtergamin
fail2ban.server.filterpoll
fail2ban.server.filterpyinotify
fail2ban.server.filtersystemd
fail2ban.server.jail
fail2ban.server.jails
fail2ban.server.jailthread
fail2ban.server.mytime
fail2ban.server.server
fail2ban.server.strptime
fail2ban.server.ticket
fail2ban.server.transmitter

View File

@ -0,0 +1,7 @@
fail2ban.server.server module
=============================
.. automodule:: fail2ban.server.server
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.strptime module
===============================
.. automodule:: fail2ban.server.strptime
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.ticket module
=============================
.. automodule:: fail2ban.server.ticket
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,7 @@
fail2ban.server.transmitter module
==================================
.. automodule:: fail2ban.server.transmitter
:members:
:undoc-members:
:show-inheritance:

7
doc/fail2ban.version.rst Normal file
View File

@ -0,0 +1,7 @@
fail2ban.version module
=======================
.. automodule:: fail2ban.version
:members:
:undoc-members:
:show-inheritance:

1
doc/filters.rst Normal file
View File

@ -0,0 +1 @@
.. include:: ../FILTERS

19
doc/index.rst Normal file
View File

@ -0,0 +1,19 @@
Welcome to Fail2Ban's developers documentation!
===============================================
Contents:
.. toctree::
:maxdepth: 2
develop
filters
release
fail2ban
Indices and tables
==================
* :ref:`genindex`
* :ref:`search`

1
doc/release.rst Normal file
View File

@ -0,0 +1 @@
.. include:: ../RELEASE

1
doc/requirements.txt Normal file
View File

@ -0,0 +1 @@
numpydoc

View File

@ -34,11 +34,11 @@ logSys = logging.getLogger(__name__)
class ActionReader(DefinitionInitConfigReader): class ActionReader(DefinitionInitConfigReader):
_configOpts = [ _configOpts = [
["string", "actionstart", ""], ["string", "actionstart", None],
["string", "actionstop", ""], ["string", "actionstop", None],
["string", "actioncheck", ""], ["string", "actioncheck", None],
["string", "actionban", ""], ["string", "actionban", None],
["string", "actionunban", ""], ["string", "actionunban", None],
] ]
def __init__(self, file_, jailName, initOpts, **kwargs): def __init__(self, file_, jailName, initOpts, **kwargs):

View File

@ -188,9 +188,9 @@ class Beautifier:
logSys.debug("Beautify (error) " + `response` + " with " + `self.__inputCmd`) logSys.debug("Beautify (error) " + `response` + " with " + `self.__inputCmd`)
msg = response msg = response
if isinstance(response, UnknownJailException): if isinstance(response, UnknownJailException):
msg = "Sorry but the jail '" + response[0] + "' does not exist" msg = "Sorry but the jail '" + response.args[0] + "' does not exist"
elif isinstance(response, IndexError): elif isinstance(response, IndexError):
msg = "Sorry but the command is invalid" msg = "Sorry but the command is invalid"
elif isinstance(response, DuplicateJailException): elif isinstance(response, DuplicateJailException):
msg = "The jail '" + response[0] + "' already exists" msg = "The jail '" + response.args[0] + "' already exists"
return msg return msg

View File

@ -120,6 +120,10 @@ class ConfigReader(SafeConfigParserWithIncludes):
logSys.warning("'%s' not defined in '%s'. Using default one: %r" logSys.warning("'%s' not defined in '%s'. Using default one: %r"
% (option[1], sec, option[2])) % (option[1], sec, option[2]))
values[option[1]] = option[2] values[option[1]] = option[2]
else:
logSys.debug(
"Non essential option '%s' not defined in '%s'.",
option[1], sec)
except ValueError: except ValueError:
logSys.warning("Wrong value for '" + option[1] + "' in '" + sec + logSys.warning("Wrong value for '" + option[1] + "' in '" + sec +
"'. Using default one: '" + `option[2]` + "'") "'. Using default one: '" + `option[2]` + "'")

View File

@ -35,7 +35,7 @@ logSys = logging.getLogger(__name__)
class FilterReader(DefinitionInitConfigReader): class FilterReader(DefinitionInitConfigReader):
_configOpts = [ _configOpts = [
["string", "ignoreregex", ""], ["string", "ignoreregex", None],
["string", "failregex", ""], ["string", "failregex", ""],
] ]

View File

@ -68,7 +68,8 @@ class JailReader(ConfigReader):
return out return out
def isEnabled(self): def isEnabled(self):
return self.__force_enable or ( self.__opts and self.__opts["enabled"] ) return self.__force_enable or (
self.__opts and self.__opts.get("enabled", False))
@staticmethod @staticmethod
def _glob(path): def _glob(path):
@ -85,14 +86,14 @@ class JailReader(ConfigReader):
return pathList return pathList
def getOptions(self): def getOptions(self):
opts = [["bool", "enabled", "false"], opts = [["bool", "enabled", False],
["string", "logpath", "/var/log/messages"], ["string", "logpath", None],
["string", "logencoding", "auto"], ["string", "logencoding", None],
["string", "backend", "auto"], ["string", "backend", "auto"],
["int", "maxretry", 3], ["int", "maxretry", None],
["int", "findtime", 600], ["int", "findtime", None],
["int", "bantime", 600], ["int", "bantime", None],
["string", "usedns", "warn"], ["string", "usedns", None],
["string", "failregex", None], ["string", "failregex", None],
["string", "ignoreregex", None], ["string", "ignoreregex", None],
["string", "ignorecommand", None], ["string", "ignorecommand", None],

View File

@ -62,9 +62,7 @@ class CallingMap(MutableMapping):
Attributes Attributes
---------- ----------
data : dict data : dict
The dictionary data which can be accessed to obtain items The dictionary data which can be accessed to obtain items uncalled
without callable values being called.
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):

View File

@ -361,7 +361,10 @@ class Fail2BanDb(object):
ticket : BanTicket ticket : BanTicket
Ticket of the ban to be added. Ticket of the ban to be added.
""" """
self._bansMergedCache = {} try:
del self._bansMergedCache[(ticket.getIP(), jail)]
except KeyError:
pass
#TODO: Implement data parts once arbitrary match keys completed #TODO: Implement data parts once arbitrary match keys completed
cur.execute( cur.execute(
"INSERT INTO bans(jail, ip, timeofban, data) VALUES(?, ?, ?, ?)", "INSERT INTO bans(jail, ip, timeofban, data) VALUES(?, ?, ?, ?)",
@ -383,7 +386,7 @@ class Fail2BanDb(object):
if ip is not None: if ip is not None:
query += " AND ip=?" query += " AND ip=?"
queryArgs.append(ip) queryArgs.append(ip)
query += " ORDER BY timeofban" query += " ORDER BY ip, timeofban"
return cur.execute(query, queryArgs) return cur.execute(query, queryArgs)
@ -412,7 +415,7 @@ class Fail2BanDb(object):
tickets[-1].setAttempt(data['failures']) tickets[-1].setAttempt(data['failures'])
return tickets return tickets
def getBansMerged(self, ip, jail=None, **kwargs): def getBansMerged(self, ip=None, jail=None, bantime=None):
"""Get bans from the database, merged into single ticket. """Get bans from the database, merged into single ticket.
This is the same as `getBans`, but bans merged into single This is the same as `getBans`, but bans merged into single
@ -430,22 +433,44 @@ class Fail2BanDb(object):
Returns Returns
------- -------
Ticket list or Ticket
Single ticket representing bans stored in database. Single ticket representing bans stored in database per IP
in a list. When `ip` argument passed, a single `Ticket` is
returned.
""" """
cacheKey = ip if jail is None else "%s|%s" % (ip, jail.name) if bantime is None:
cacheKey = (ip, jail)
if cacheKey in self._bansMergedCache: if cacheKey in self._bansMergedCache:
return self._bansMergedCache[cacheKey] return self._bansMergedCache[cacheKey]
tickets = []
ticket = None
results = list(self._getBans(ip=ip, jail=jail, bantime=bantime))
if results:
prev_banip = results[0][0]
matches = [] matches = []
failures = 0 failures = 0
for ip, timeofban, data in self._getBans(ip=ip, jail=jail, **kwargs): for banip, timeofban, data in results:
#TODO: Implement data parts once arbitrary match keys completed #TODO: Implement data parts once arbitrary match keys completed
if banip != prev_banip:
ticket = FailTicket(prev_banip, prev_timeofban, matches)
ticket.setAttempt(failures)
tickets.append(ticket)
# Reset variables
prev_banip = banip
matches = []
failures = 0
matches.extend(data['matches']) matches.extend(data['matches'])
failures += data['failures'] failures += data['failures']
ticket = FailTicket(ip, timeofban, matches) prev_timeofban = timeofban
ticket = FailTicket(banip, prev_timeofban, matches)
ticket.setAttempt(failures) ticket.setAttempt(failures)
self._bansMergedCache[cacheKey] = ticket tickets.append(ticket)
return ticket
if bantime is None:
self._bansMergedCache[cacheKey] = tickets if ip is None else ticket
return tickets if ip is None else ticket
@commitandrollback @commitandrollback
def purge(self, cur): def purge(self, cur):

View File

@ -63,7 +63,7 @@ class Filter(JailThread):
## Use DNS setting ## Use DNS setting
self.setUseDns(useDns) self.setUseDns(useDns)
## The amount of time to look back. ## The amount of time to look back.
self.__findTime = 6000 self.__findTime = 600
## The ignore IP list. ## The ignore IP list.
self.__ignoreIpList = [] self.__ignoreIpList = []
## Size of line buffer ## Size of line buffer

View File

@ -104,7 +104,9 @@ class Jail:
self.__actions = Actions(self) self.__actions = Actions(self)
return # we are done return # we are done
except ImportError, e: except ImportError, e:
logSys.debug( # Log debug if auto, but error if specific
logSys.log(
logging.DEBUG if backend == "auto" else logging.ERROR,
"Backend %r failed to initialize due to %s" % (b, e)) "Backend %r failed to initialize due to %s" % (b, e))
# log error since runtime error message isn't printed, INVALID COMMAND # log error since runtime error message isn't printed, INVALID COMMAND
logSys.error( logSys.error(
@ -209,7 +211,7 @@ class Jail:
self.actions.start() self.actions.start()
# Restore any previous valid bans from the database # Restore any previous valid bans from the database
if self.database is not None: if self.database is not None:
for ticket in self.database.getBans( for ticket in self.database.getBansMerged(
jail=self, bantime=self.actions.getBanTime()): jail=self, bantime=self.actions.getBanTime()):
if not self.filter.inIgnoreIPList(ticket.getIP()): if not self.filter.inIgnoreIPList(ticket.getIP()):
self.__queue.put(ticket) self.__queue.put(ticket)

View File

@ -349,31 +349,9 @@ class JailsReaderTest(LogCaptureTestCase):
self.maxDiff = None self.maxDiff = None
self.assertEqual(sorted(comm_commands), self.assertEqual(sorted(comm_commands),
sorted([['add', 'emptyaction', 'auto'], sorted([['add', 'emptyaction', 'auto'],
['set', 'emptyaction', 'usedns', 'warn'],
['set', 'emptyaction', 'maxretry', 3],
['set', 'emptyaction', 'findtime', 600],
['set', 'emptyaction', 'logencoding', 'auto'],
['set', 'emptyaction', 'bantime', 600],
['add', 'special', 'auto'],
['set', 'special', 'usedns', 'warn'],
['set', 'special', 'maxretry', 3],
['set', 'special', 'addfailregex', '<IP>'],
['set', 'special', 'findtime', 600],
['set', 'special', 'logencoding', 'auto'],
['set', 'special', 'bantime', 600],
['add', 'missinglogfiles', 'auto'], ['add', 'missinglogfiles', 'auto'],
['set', 'missinglogfiles', 'usedns', 'warn'],
['set', 'missinglogfiles', 'maxretry', 3],
['set', 'missinglogfiles', 'findtime', 600],
['set', 'missinglogfiles', 'logencoding', 'auto'],
['set', 'missinglogfiles', 'bantime', 600],
['set', 'missinglogfiles', 'addfailregex', '<IP>'], ['set', 'missinglogfiles', 'addfailregex', '<IP>'],
['add', 'brokenaction', 'auto'], ['add', 'brokenaction', 'auto'],
['set', 'brokenaction', 'usedns', 'warn'],
['set', 'brokenaction', 'maxretry', 3],
['set', 'brokenaction', 'findtime', 600],
['set', 'brokenaction', 'logencoding', 'auto'],
['set', 'brokenaction', 'bantime', 600],
['set', 'brokenaction', 'addfailregex', '<IP>'], ['set', 'brokenaction', 'addfailregex', '<IP>'],
['set', 'brokenaction', 'addaction', 'brokenaction'], ['set', 'brokenaction', 'addaction', 'brokenaction'],
['set', ['set',
@ -382,23 +360,9 @@ class JailsReaderTest(LogCaptureTestCase):
'brokenaction', 'brokenaction',
'actionban', 'actionban',
'hit with big stick <ip>'], 'hit with big stick <ip>'],
['set', 'brokenaction', 'action', 'brokenaction',
'actionstop', ''],
['set', 'brokenaction', 'action', 'brokenaction',
'actionstart', ''],
['set', 'brokenaction', 'action', 'brokenaction',
'actionunban', ''],
['set', 'brokenaction', 'action', 'brokenaction',
'actioncheck', ''],
['add', 'parse_to_end_of_jail.conf', 'auto'], ['add', 'parse_to_end_of_jail.conf', 'auto'],
['set', 'parse_to_end_of_jail.conf', 'usedns', 'warn'],
['set', 'parse_to_end_of_jail.conf', 'maxretry', 3],
['set', 'parse_to_end_of_jail.conf', 'findtime', 600],
['set', 'parse_to_end_of_jail.conf', 'logencoding', 'auto'],
['set', 'parse_to_end_of_jail.conf', 'bantime', 600],
['set', 'parse_to_end_of_jail.conf', 'addfailregex', '<IP>'], ['set', 'parse_to_end_of_jail.conf', 'addfailregex', '<IP>'],
['start', 'emptyaction'], ['start', 'emptyaction'],
['start', 'special'],
['start', 'missinglogfiles'], ['start', 'missinglogfiles'],
['start', 'brokenaction'], ['start', 'brokenaction'],
['start', 'parse_to_end_of_jail.conf'],])) ['start', 'parse_to_end_of_jail.conf'],]))
@ -572,6 +536,7 @@ class JailsReaderTest(LogCaptureTestCase):
jailfd = open(os.path.join(basedir, "jail.conf"), 'w') jailfd = open(os.path.join(basedir, "jail.conf"), 'w')
jailfd.write(""" jailfd.write("""
[testjail1] [testjail1]
enabled = true
action = testaction1[actname=test1] action = testaction1[actname=test1]
testaction1[actname=test2] testaction1[actname=test2]
testaction.py testaction.py

View File

@ -14,6 +14,7 @@ ignoreregex =
ignoreip = ignoreip =
[missinglogfiles] [missinglogfiles]
enabled = true
logpath = /weapons/of/mass/destruction logpath = /weapons/of/mass/destruction
[brokenactiondef] [brokenactiondef]
@ -25,6 +26,7 @@ enabled = true
action = brokenaction action = brokenaction
[missingbitsjail] [missingbitsjail]
enabled = true
filter = catchallthebadies filter = catchallthebadies
action = thefunkychickendance action = thefunkychickendance

View File

@ -190,16 +190,16 @@ class DatabaseTest(unittest.TestCase):
jail2 = DummyJail() jail2 = DummyJail()
self.db.addJail(jail2) self.db.addJail(jail2)
ticket = FailTicket("127.0.0.1", 10, ["abc\n"]) ticket = FailTicket("127.0.0.1", MyTime.time() - 40, ["abc\n"])
ticket.setAttempt(10) ticket.setAttempt(10)
self.db.addBan(self.jail, ticket) self.db.addBan(self.jail, ticket)
ticket = FailTicket("127.0.0.1", 20, ["123\n"]) ticket = FailTicket("127.0.0.1", MyTime.time() - 30, ["123\n"])
ticket.setAttempt(20) ticket.setAttempt(20)
self.db.addBan(self.jail, ticket) self.db.addBan(self.jail, ticket)
ticket = FailTicket("127.0.0.2", 30, ["ABC\n"]) ticket = FailTicket("127.0.0.2", MyTime.time() - 20, ["ABC\n"])
ticket.setAttempt(30) ticket.setAttempt(30)
self.db.addBan(self.jail, ticket) self.db.addBan(self.jail, ticket)
ticket = FailTicket("127.0.0.1", 40, ["ABC\n"]) ticket = FailTicket("127.0.0.1", MyTime.time() - 10, ["ABC\n"])
ticket.setAttempt(40) ticket.setAttempt(40)
self.db.addBan(jail2, ticket) self.db.addBan(jail2, ticket)
@ -220,7 +220,15 @@ class DatabaseTest(unittest.TestCase):
id(ticket), id(ticket),
id(self.db.getBansMerged("127.0.0.1", jail=self.jail))) id(self.db.getBansMerged("127.0.0.1", jail=self.jail)))
newTicket = FailTicket("127.0.0.1", 40, ["ABC\n"]) newTicket = FailTicket("127.0.0.2", MyTime.time() - 20, ["ABC\n"])
ticket.setAttempt(40)
# Add ticket, but not for same IP, so cache still valid
self.db.addBan(self.jail, newTicket)
self.assertEqual(
id(ticket),
id(self.db.getBansMerged("127.0.0.1", jail=self.jail)))
newTicket = FailTicket("127.0.0.1", MyTime.time() - 10, ["ABC\n"])
ticket.setAttempt(40) ticket.setAttempt(40)
self.db.addBan(self.jail, newTicket) self.db.addBan(self.jail, newTicket)
# Added ticket, so cache should have been cleared # Added ticket, so cache should have been cleared
@ -228,6 +236,22 @@ class DatabaseTest(unittest.TestCase):
id(ticket), id(ticket),
id(self.db.getBansMerged("127.0.0.1", jail=self.jail))) id(self.db.getBansMerged("127.0.0.1", jail=self.jail)))
tickets = self.db.getBansMerged()
self.assertEqual(len(tickets), 2)
self.assertEqual(
sorted(list(set(ticket.getIP() for ticket in tickets))),
sorted([ticket.getIP() for ticket in tickets]))
tickets = self.db.getBansMerged(jail=jail2)
self.assertEqual(len(tickets), 1)
tickets = self.db.getBansMerged(bantime=25)
self.assertEqual(len(tickets), 2)
tickets = self.db.getBansMerged(bantime=15)
self.assertEqual(len(tickets), 1)
tickets = self.db.getBansMerged(bantime=5)
self.assertEqual(len(tickets), 0)
def testPurge(self): def testPurge(self):
if Fail2BanDb is None: # pragma: no cover if Fail2BanDb is None: # pragma: no cover
return return

View File

@ -3,4 +3,8 @@
2012/04/09 11:53:29 [error] 2865#0: *66647 user "xyz" was not found in "/var/www/.htpasswd", client: 192.0.43.10, server: www.myhost.com, request: "GET / HTTP/1.1", host: "www.myhost.com" 2012/04/09 11:53:29 [error] 2865#0: *66647 user "xyz" was not found in "/var/www/.htpasswd", client: 192.0.43.10, server: www.myhost.com, request: "GET / HTTP/1.1", host: "www.myhost.com"
# failJSON: { "time": "2012-04-09T11:53:36", "match": true , "host": "192.0.43.10" } # failJSON: { "time": "2012-04-09T11:53:36", "match": true , "host": "192.0.43.10" }
2012/04/09 11:53:36 [error] 2865#0: *66647 user "xyz": password mismatch, client: 192.0.43.10, server: www.myhost.com, request: "GET / HTTP/1.1", host: "www.myhost.com" 2012/04/09 11:53:36 [error] 2865#0: *66647 user "xyz": password mismatch, client: 192.0.43.10, server: www.myhost.com, request: "GET / HTTP/1.1", host: "www.myhost.com"
# failJSON: { "time": "2014-04-01T22:20:38", "match": true, "host": "10.0.2.2" }
2014/04/01 22:20:38 [error] 30708#0: *3 user "scribendio": password mismatch, client: 10.0.2.2, server: , request: "GET / HTTP/1.1", host: "localhost:8443"
# failJSON: { "time": "2014-04-02T12:37:58", "match": true, "host": "10.0.2.2" }
2014/04/02 12:37:58 [error] 6563#0: *1861 user "scribendio": password mismatch, client: 10.0.2.2, server: scribend.io, request: "GET /admin HTTP/1.1", host: "scribend.io", referrer: "https://scribend.io/admin"

View File

@ -1,5 +1,6 @@
[Unit] [Unit]
Description=Fail2Ban Service Description=Fail2Ban Service
Documentation=man:fail2ban(1)
After=network.target iptables.service firewalld.service After=network.target iptables.service firewalld.service
[Service] [Service]

View File

@ -297,12 +297,12 @@ There are two filter definitions used in the [Definition] section:
.TP .TP
.B failregex .B failregex
is the regex (\fBreg\fRular \fBex\fRpression) that will match failed attempts. The tag \fI<HOST>\fR is used as part of the regex and is itself a regex is the regex (\fBreg\fRular \fBex\fRpression) that will match failed attempts. The tag \fI<HOST>\fR is used as part of the regex and is itself a regex
for IPv4 addresses and hostnames. fail2ban will work out which one of these it actually is. for IPv4 addresses (and hostnames if \fBusedns\fR). Fail2Ban will work out which one of these it actually is.
For multiline regexs the tag \fI<SKIPLINES>\fR should be used to separate lines. This allows lines between the matched lines to continue to be searched for other failures. The tag can be used multiple times. For multiline regexs the tag \fI<SKIPLINES>\fR should be used to separate lines. This allows lines between the matched lines to continue to be searched for other failures. The tag can be used multiple times.
.TP .TP
.B ignoreregex .B ignoreregex
is the regex to identify log entries that should be ignored by fail2ban, even if they match failregex. is the regex to identify log entries that should be ignored by Fail2Ban, even if they match failregex.
.PP .PP
@ -331,13 +331,6 @@ indicates that this file is read before the [Definition] section.
\fBafter\fR \fBafter\fR
indicates that this file is read after the [Definition] section. indicates that this file is read after the [Definition] section.
.B failregex
regex that will match failed attempts. The tag <HOST> is used as part of the regex and is itself a regex
for IPv4 addresses (and hostnames if \fBusedns\fR). Fail2Ban will work out which one of these it actually is.
.TP
.B ignoreregex
regex to identify log entries that should be ignored by Fail2Ban, even if they match failregex.
.SH AUTHOR .SH AUTHOR
Fail2ban was originally written by Cyril Jaquier <cyril.jaquier@fail2ban.org>. Fail2ban was originally written by Cyril Jaquier <cyril.jaquier@fail2ban.org>.
At the moment it is maintained and further developed by Yaroslav O. Halchenko <debian@onerussian.com>, Daniel Black <daniel.subs@internode.on.net> and Steven Hiscocks <steven-fail2ban@hiscocks.me.uk> along with a number of contributors. See \fBTHANKS\fR file shipped with Fail2Ban for a full list. At the moment it is maintained and further developed by Yaroslav O. Halchenko <debian@onerussian.com>, Daniel Black <daniel.subs@internode.on.net> and Steven Hiscocks <steven-fail2ban@hiscocks.me.uk> along with a number of contributors. See \fBTHANKS\fR file shipped with Fail2Ban for a full list.