How to Setup Fail2ban (Intrusion Prevention Framework)

Ⓒ Hak cipta foto di atas dikembalikan sesungguhnya kepada pemilik foto

Ilustration of Fail2ban. PHOTO/Cyberpunk

ADVERTISEMENTS

Introduction

Fail2ban is an Intrusion Detection/Prevention System (IDS/IPS), a great tool that helps you keep “unwanted” guests at bay. It’s mainly used to stop, prevent or slow down bruteforce attacks, but can be used to limit the number of requests per unit of time (backend, API,..).

ADVETISEMENTS

It scans/monitor log files and bans IPs that show malicious signs, like too many password failures, probing, bruteforcing attempts, etc. You can specify which service and log to monitor, how many attempts per unit of time (second/hour…), define regex (regular expression) patterns, etc.

ADVERTISEMENTS
ADVERTISEMENTS

Out of the box it comes with filters for various services: Apache, ssh, nginx, asterisk, proftp, mysql… Here we’ll quickly go through Fail2ban setup.

ADVERTISEMENTS
ADVETISEMENTS

Fail2Ban Setup

Install process it is relatively straightforward.

ADVERTISEMENTS

RedHat (CentOS)

Update, Install with EPEL repository:

ADVERTISEMENTS
yum update yum install epel-release  yum install fail2ban

Debian (Ubuntu)

Update & install:

$ apt-get update  $ apt-get install fail2ban  

Fail2ban Configuration Files

Relevant File2Ban Configuration files and dirs:

Fail2ban Definitions

Before we continue, it’s probably good idea to define what’s what:

Fail2ban Server is multi-threaded, listens on a Unix socket for commands. Knows nothing about configuration files.

-b start in background  -f start in foreground  -s <FILE> socket path  -x force execution of the server  -h, --help display this help message  -V, --version print the version  

Fail2ban Client is basically the frontend, operate the servers. Reads the configuration files, or accept individual commands via interactive mode.

-c <DIR> configuration directory  -s <FILE> socket path  -d dump configuration. For debugging  -i interactive mode  -v increase verbosity  -q decrease verbosity  -x force execution of the server  -h, --help display this help message  -V, --version print the version  

Examples:

$ fail2ban-client set loglevel 1  $ fail2ban-client set logtarget STDERR    $ fail2ban-client status  |- Number of jails: 1  `- Jail list: sshd    $ fail2ban-client status sshd  Status for the jail: sshd  |- Filter  |  |- Currently failed: 2  |  |- Total failed: 42635  |  |- File list: /var/log/auth.log  `- Actions     |- Currently banned: 0     |- Total banned: 863     |- Banned IP list:  

Fail2ban Main Configuration

Fail2ban Jail Options

Let’s explain one example:

/etc/fail2ban/jail.local    [sshd]  enabled = true  port = ssh  filter = sshd  action = iptables[name=SSH, port=ssh, protocol=tcp]  logpath = /var/log/secure  findtime = 120  maxretry = 5  bantime = 3600  

Log path can vary, adjust it on your system (OS). Based on rules above, we’re monitoring SSH log (/var/log/secure), and we’re banning anyone (for 1 hour, 3600 seconds) who fails to log 5 times within 2 minutes (120 seconds). Rules are pretty straight forward. We’ve specified “sshd” filter, so if you go to /etc/fail2ban/filter.d/sshd.conf, you’ll se a number of failregex rules, used to match login attempts from log file.

To whitelist (ignore) an IP, add them to the ignoreip line:

ignoreip = 127.0.0.1/8
Note: Depending on the amount of traffic specific service has (website, wordpress, etc.) fail2ban can generate CPU concerns/load.

Custom Fail2ban PhpMyAdmin filter (Jail & Regex)

The best way to learn is to try and write your own filters. I’ll show you an example for Custom Fail2ban PhpMyAdmin filter. First, we need the jail in our jail.local file:

[phpmyadmin]    enabled = true  port = http,https  filter = phpmyadmin  action = iptables-multiport[name=PHPMYADMIN, port="http,https", protocol=tcp]  logpath = /var/log/nginx/access.log  bantime = 3600  findtime = 60  maxretry = 3

Next we need that filter. Check your web server (Apache/nginx) logs:

/var/log/nginx/access.log.1:121.169.192.227 - - [19/Sep/2018:01:41:23 +0000] "GET /phpmyadmin/index.php?pma_username=root&pma_password=root&server=1 HTTP/1.1" 200 10050 "-" "Mozilla/5.0"  /var/log/nginx/access.log.1:121.169.192.227 - - [19/Sep/2018:01:41:23 +0000] "GET /phpmyadmin/index.php?pma_username=root&pma_password=toor&server=1 HTTP/1.1" 200 10050 "-" "Mozilla/5.0"  /var/log/nginx/access.log.1:121.169.192.227 - - [19/Sep/2018:01:41:23 +0000] "GET /phpmyadmin/index.php?pma_username=root&pma_password=r00t&server=1 HTTP/1.1" 200 10050 "-" "Mozilla/5.0"

The IP 121.169.192.227 is trying to bruteforce its way in (well known malicious IP). We’ll try to make their life a bit more difficult. Make a file in your /etc/fail2ban/filter.d/phpmyadmin.conf, and insert:

[Definition]  failregex = ^<HOST> -.*"(GET|POST).*/phpmyadmin/index\.php\?pma_username=root&pma_password=.*$  ignoreregex =

The above regex is matching the lines we’ve seen in the logs. This will ban anyone for 1 hour if they fail to login more than 3x in 60 seonds. When done, restart fail2ban:

$ service fail2ban restart

or reload:

$ fail2ban-client reload phpmyadmin

Fail2ban testing regex

When you finish creating some filter it’s good idea to test it before activating it. For that we have fail2ban-regex:

$ fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/phpmyadmin.conf    Running tests  =============    Use   failregex filter file : phpmyadmin, basedir: /etc/fail2ban  Use         log file : /var/log/nginx/access.log  Use         encoding : UTF-8      Results  =======    Failregex: 56 total  |-  #) [# of hits] regular expression  |   1) [56] ^<HOST> -.*"(GET|POST).*/phpmyadmin/index\.php\?pma_username=root&pma_password=.*$  `-    Ignoreregex: 0 total    Date template hits:  |- [# of hits] date format  |  [4078] Day(?P<_sep>[-/])MON(?P=_sep)Year[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?  `-    Lines: 4078 lines, 0 ignored, 56 matched, 4022 missed [processed in 0.33 sec]  Missed line(s): too many to print.  Use --print-all-missed to print all 4022 lines

We have a match. In case filter/regex is wrong, we’ll probably end up with no matches:

Lines: 3315 lines, 0 ignored, 0 matched, 3315 missed [processed in 0.23 sec]  Missed line(s): too many to print. Use --print-all-missed to print all 3315 lines

Fail2ban Email Alerts

I didn’t experiment with this much, but its probably worth mentioning that you have Email Alert option. Adjust email setings:

Use fail2ban predefined actions.d/sendmail-whois:

[sendmail]  enabled = true  filter = sendmail  action = iptables-multiport[name=sendmail, port="pop3,imap,smtp,pop3s,imaps,smtps", protocol=tcp]  sendmail-whois[name=sendmail, dest=user@domain.com]  logpath = /var/log/maillog

Another example:

[ssh]  enabled  = true  port     = ssh  filter   = sshd  action   = iptables-multiport[name=ssh,port=["ssh"|”22,4422”],protocol=tcp]           mail[name=SSH,dest=dstEmail@domain.com,sender="info@domain.com"]  logpath  = /var/log/auth.log  maxretry = 3  bantime = 600

Conclusion

I hope we managed to clarify more than a few things with this Fail2ban setup tutorial. Fail2ban is a great IDS/IPS tool, doing its job well. Depending on the traffic and findtime span it can cause significant load on CPU. Personally I didn’t experiance significant problems. If CPU load increases, try changing the backend parameter to to pooling or similar. Experiment. Since fail2ban relies on log file parsing, it doesn’t do anything to “prevent” initial attack, it only responds to predefined conditions and rules. It’s actively maintaned and we’re definitely recomending you to try it out.

ADVERTISEMENTS
x
ADVERTISEMENTS
Exit mobile version