1
1
mirror of https://github.com/jrbrtsn/ban2fail synced 2024-06-16 03:48:03 +00:00
ban2fail/README.md

146 lines
4.3 KiB
Markdown
Raw Normal View History

2019-11-23 03:40:23 +00:00
# ban2fail
(C) 2019 John D. Robertson <john@rrci.com>
**ban2fail** is a simple and efficient tool to coordinate log file scanning and
iptables filtering. As the name implies, *ban2fail* was inspired by the popular
*fail2ban* project (http://fail2ban.org).
2019-11-24 22:50:11 +00:00
*ban2fail* started with a few hours of frenzied C hacking after my mail server
was exploited to deliver spam for others who had cracked a user's SMTP send
password. After inspecting the log files I realized that crackers are now using
widely distributed attacks, and that I would need an app that could run several
times a minute on my rather modest Linode virtual server to have a chance of
2019-11-25 02:55:28 +00:00
stopping them. Here are the timing results for a typical scan on my wimpy server:
2019-11-25 02:38:45 +00:00
```
real 0m0.119s
user 0m0.073s
sys 0m0.047s
```
2019-11-25 02:55:28 +00:00
Currently I am running *fail2ban* every 5 seconds. I hope you find this code useful.
2019-11-23 03:40:23 +00:00
2019-11-23 04:25:22 +00:00
## Configuration
2019-11-23 04:16:05 +00:00
2019-11-23 03:40:23 +00:00
*ban2fail* works from a configuration file found at
"/etc/ban2fail/ban2fail.cfg". The overarching premise is that if any REGEX
appearing in a LOGTYPE clause matches a line in an associated log file, then by
default that IP will be blocked.
2019-11-23 04:16:05 +00:00
2019-11-23 04:23:18 +00:00
```
2019-11-23 04:16:05 +00:00
LOGTYPE auth {
DIR= /var/log
PREFIX= auth.log
2019-11-25 14:12:53 +00:00
# imapd[20193]= Login failed user=redacted auth=redacted@nowhere.com host=[186.179.170.12]
REGEX= imapd.*Login failed.*\[([0-9.a-f:]+)\]$
2019-11-23 04:16:05 +00:00
2019-11-25 14:12:53 +00:00
# sshd[6165]= Failed password for invalid user user from 185.224.137.201 port 44865 ssh2
REGEX= sshd.*Failed password.*from ([0-9.a-f:]+) port [0-9]+ ssh2$
2019-11-23 04:16:05 +00:00
2019-11-25 14:12:53 +00:00
# Unable to negotiate with 193.188.22.188 port ...
# REGEX= Unable to negotiate with ([0-9.]+) port
REGEX= Unable to negotiate with ([0-9.a-f:]+) port
2019-11-23 04:16:05 +00:00
}
2019-11-23 04:23:18 +00:00
```
2019-11-23 04:16:05 +00:00
2019-11-23 03:40:23 +00:00
Syntax in the config file is pretty much the same as the nftables syntax. All
2019-11-23 15:38:59 +00:00
keywords must be in upper case. Any values in the key=value pairs have
2019-11-23 03:40:23 +00:00
whitespace stripped from the beginning and end of the line. Since there is no
escaping of characters going on, regular expressions are WYSIWYG.
2019-11-23 15:46:02 +00:00
Finding typos and so forth in the config file is easy; use the -v command flag
to print all unrecognized content (besides comments).
`ban2fail -v`
2019-11-23 03:40:23 +00:00
The only way to alter the default blocking behavior is with a MAX\_OFFENSES
clause. This clause allows you specify how many offenses are tolerated before an
IP is blocked. Offenses will naturally disappear as old logfiles are deleted by
*logrotate*.
2019-11-23 04:23:18 +00:00
```
2019-11-23 04:16:05 +00:00
# Take it easy on home boys
MAX_OFFENSES 5 {
COUNTRY= US
}
# GeoIP doesn't know the location of every IP address
MAX_OFFENSES 3 {
COUNTRY= unknown
}
# This is your whitelist: -1 means no limit.
MAX_OFFENSES -1 {
# me from home
IP= 205.144.171.37
# Some user
IP= 173.236.196.36
}
2019-11-23 04:23:18 +00:00
```
2019-11-23 03:40:23 +00:00
If you recieve a complaint about an address unjustly getting blocked, place it
in one of the MAX\_OFFENSES blocks, and the IP will be unblocked the next time
2019-11-23 15:55:06 +00:00
*ban2fail* runs in production mode.
2019-11-23 03:40:23 +00:00
2019-11-23 04:25:22 +00:00
## Working with *ban2fail*
2019-11-23 04:16:05 +00:00
2019-11-23 03:40:23 +00:00
There are two primary modes in which *ban2fail* is used:
* Production mode, where iptables rules are modified.
* Testing mode, where modifications to blocking rules are indicated.
2019-11-23 04:25:22 +00:00
### Production
2019-11-23 04:16:05 +00:00
2019-11-23 03:40:23 +00:00
In production mode it is expected that *ban2fail* is running from a cron job,
and no output is printed unless addresses are (un)blocked. It is also possible
to generate a listing of addresses, offense counts, and status with the -a
command flag. Likewise, a listing of countries and offense counts is available
with the -c flag.
2019-11-23 04:25:22 +00:00
### Testing
2019-11-23 04:16:05 +00:00
2019-11-23 15:38:59 +00:00
In test mode (-t flag) the presumption is that you are testing a modified
2019-11-23 03:40:23 +00:00
configuration which is not yet in place, and that you don't want to disturb the
production setup. This is how you might do that:
2019-11-23 04:16:05 +00:00
`ban2fail -t myNew.cfg -a`
2019-11-23 03:40:23 +00:00
2019-11-23 04:29:27 +00:00
No iptables rules will be modified. You will be shown in the listing which
2019-11-23 15:38:59 +00:00
addresses would be (un)blocked if the contents of "myNew.cfg" was in place, and
*ban2fail* was running in production mode.
2019-11-23 03:40:23 +00:00
When you are happy with the new configuration, copy it into place, and the the
2019-11-23 15:58:18 +00:00
iptable rule changes will be realized the next time *ban2fail* runs in
production mode.
2019-11-23 03:40:23 +00:00
2019-11-23 04:25:22 +00:00
## Building the Project
2019-11-23 04:16:05 +00:00
2019-11-23 15:55:06 +00:00
I've tested *ban2fail* only on Debian Buster, but it should compile on just
about any modern Linux distro. It uses the following libraries:
2019-11-23 15:38:59 +00:00
2019-11-23 15:55:06 +00:00
+ *libcrypto* for md5 checksums
2019-11-23 15:38:59 +00:00
2019-11-23 15:55:06 +00:00
+ *libgeoip* to identify the country of origin for IP addresses
2019-11-23 15:38:59 +00:00
2019-11-23 15:55:06 +00:00
+ *libz* to read compressed log files
2019-11-23 15:38:59 +00:00
Build and install like so:
2019-11-23 03:40:23 +00:00
2019-11-23 04:23:18 +00:00
```
2019-11-23 04:16:05 +00:00
make release
sudo make install
2019-11-23 04:23:18 +00:00
```
2019-11-23 03:40:23 +00:00
The executable will be placed in "/usr/local/bin".