fail2ban with jails

Haven't tried with jails but seems like it would be straightforward. Install, make a configuration for each service, and start it up. Here is an example for /usr/local/etc/fail2ban/jail.d/bsdftp.conf on mine. Changing the log path to point inside a jail would be easy. Doing a search for specifying multiple "logpath" files showed this as the first result so it would seem like it's just a matter of specifying one for each jail: http://serverfault.com/questions/486301/how-to-set-up-fail2ban-to-read-multi-log-in-a-jail
Code:
[bsdftp]

enabled  = true
filter   = bsdftp
action   = pf
logpath  = /var/log/auth.log
bantime  = 1800
findtime = 1800
maxretry = 5
 
Yep, just run fail2ban on the host and reference the files inside the jails (/jails/myjail/var/log/auth.log for example).
 
BTW, my next goal: multiple actions for a given jail.d entry. Anyone done that? e.g. if something is doing nasty stuff on the website, block them from both http and ssh.
 
  • Thanks
Reactions: Oko
I use fail2ban extensively with PF to block SSH, SASL, Dovecot, and Postfix brute-force and DoS attacks. I also have custom-made scripts to log all permanent banned IP addresses so PF can reload the blacklist when restarted. It works very well. I plan to add Nginx to block scanners, spiders or requests for sensitive or missing files.

Need to be careful about http as http requests could be legitimate. You can limit concurrent connections to single IP address via PF or Nginx config to block http DoS attacks. Once that concurrent connection reaches its max then you can permanent ban that IP address.
 
I use fail2ban extensively with PF to block SSH, SASL, Dovecot, and Postfix brute-force and DoS attacks. I also have custom-made scripts to log all permanent banned IP addresses so PF can reload the blacklist when restarted. It works very well. I plan to add Nginx to block scanners, spiders or requests for sensitive or missing files.

Need to be careful about http as http requests could be legitimate. You can limit concurrent connections to single IP address via PF or Nginx config to block http DoS attacks. Once that concurrent connection reaches its max then you can permanent ban that IP address.

Could you please post the configuration files or a link to your blog when you explain things? Thank you!
 
BTW, my next goal: multiple actions for a given jail.d entry. Anyone done that? e.g. if something is doing nasty stuff on the website, block them from both http and ssh.

I've just been blocking all traffic once someone hits it enough to trigger an action by Fail2Ban. That is accomplishing what you mentioned. It's just the pf.conf rule below. Are you currently doing something more more fine grained than this?

Code:
block drop in log quick on $wan_ifs from <fail2ban> to any
 
... I also have custom-made scripts to log all permanent banned IP addresses so PF can reload the blacklist when restarted. ...

For this in particular, security/py-fail2ban gained support for using a SQLite database for persistent storage of banned addresses. I just checked the Freshports change log and that was introduced in the 0.9.0 update in May of 2014. So you may be able to save some effort not duplicating that functionality with a custom script.
 
Could you please post the configuration files or a link to your blog when you explain things? Thank you!

My scripts are still in development but it works for now. Feel free to modify or improve them if you wish.

Need to include this otherwise it will not work.
/etc/pf.conf
Code:
# Tables
table <fail2ban> persist file "/etc/pf.blacklist"

# Fail2ban
block in log quick on $ext_if from <fail2ban> to any

SSH - use custom pf to temporary ban and unban IP addresses.
pf-offender - IP address permanently banned after 3 temporary bans.
/usr/local/etc/fail2ban/jail.local
Code:
[DEFAULT]
bantime = 3600
findtime = 604800
maxretry = 3

[sshd]
enabled  = true
filter  = bsd-sshd
action  = pf
logpath  = /var/log/auth.log
  /jails/web/var/log/auth.log

[pf-offender]
enabled  = true
filter  = pf-offender
action  = pf-offender
logpath  = /var/log/fail2ban.log
bantime  = -1

Custom pf script to ban and unban IP addresses.
/usr/local/etc/fail2ban/action.d/pf.local
Code:
[Definition]

actionban  = /usr/local/etc/fail2ban/scripts/pf-offender.sh add <ip>
actionunban  = /usr/local/etc/fail2ban/scripts/pf-offender.sh delete <ip>

Custom script to add IP to blacklist
/usr/local/etc/fail2ban/action.d/pf-offender.local
Code:
[Definition]

actionban  = /usr/local/etc/fail2ban/scripts/pf-offender.sh blacklist <ip>

This script monitors fail2ban's temporary bans from ssh, sasl, postfix, dovecot, etc.
/usr/local/etc/fail2ban/filter.d/pf-offender.local
Code:
[INCLUDES]

before  = common.conf

[Definition]

_daemon  = pf-offender
failregex  = NOTICE  \[\S*\] Ban <HOST>

ignoreregex =

This script is still in development and it works. It creates two pf blacklist files in /etc directory. Text file pf.blacklist is used by PF to repopulate PF table after restart or reload. Another text file pf.blacklist.txt is created for logging history of permanent banned IP addresses. The reason why I created separate blacklist file is because PF needs clean IP list to repopulate the PF table without the dates. Don't forget to chmod +x pf-offender.sh.
/usr/local/etc/fail2ban/scripts/pf-offender.sh
Code:
#!/bin/tcsh

set cmd  = $1
set ip  = $2
set file  = `grep -c $ip /etc/pf.blacklist`
set table  = `pfctl -t fail2ban -T show | grep -c $ip`
set date  = `date +"%Y-%m-%d"`

# add temp banned ip to pf table
if ( $cmd == "add" && "$table" == "0" ) then
  pfctl -t fail2ban -T add $ip
endif

# delete temp banned ip from pf table
if ( $cmd == "delete" && "$file" == "0" ) then
  pfctl -t fail2ban -T delete $ip
endif

# add permanent banned ip to pf table and blacklisted file
if ( $cmd == "blacklist" && "$file" == "0" ) then
  # add ip if not found in table
  if ( "$table" == "0" ) then
  pfctl -t fail2ban -T add $ip
  endif
  echo $ip >> /etc/pf.blacklist
  echo $date - $ip >> /etc/pf.blacklist.txt
endif

# populate permanent banned ip to pf table from blacklist file
# this is not needed as pf uses the blacklist file
if ( $cmd == "populate" ) then
  foreach line ( "`cat /etc/pf.blacklist`" )
  pfctl -t fail2ban -T add $line
  end
endif

Hope this helps.
 
For this in particular, security/py-fail2ban gained support for using a SQLite database for persistent storage of banned addresses. I just checked the Freshports change log and that was introduced in the 0.9.0 update in May of 2014. So you may be able to save some effort not duplicating that functionality with a custom script.

I'm not aware of this changes but my script does more and gives me the flexibility to modify the blacklist file if needed. I do get many IP addresses that are similar so I modify the blacklist with a blanket ban on IP addresses to keep the list short.
 
Back
Top