Fail2Ban Behind A Proxy/Load Balancer

You’ve users that you want to ban / block from your web servers using Fail2Ban but your web servers are behind a proxy so all traffic appears to be coming from the proxy server IP/Interface.

Ideally you should have learning rules on your proxy or load balancer where you can automatically filter/rate/take actions, but this may not always be the case.

Most people that come across this problem get as far as the first part of the solution but then are baffled when they use Fail2Ban and it still doesn’t work.

For the rest of this post I’ll refer to the Proxy/Load Balancer simply as the LB, mainly as this solution was developed for three web servers behind a load balancer.

Modify Your LB

Ensure your LB is set up to add the http header “X-Forwarded-For”.

How you enable this will depend on your LB and is outside the scope of this post.

Modify Your Web Server Apache Configs

Specifically around logging.  We want to ensure that Fail2Ban can identify the “correct” IP in order to successfully ban it.

I usually use a custom log format and add the X-Forwarded-For details at the end in an easy to identify block, this appears in the logs at the end as “[XF www.xxx.yyy.zzz\]”

To do this I use the following directives in the vhost definition in Apache:

CustomLog /path/to/logs/access_log "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\" \"[XF %{X-Forwarded-For}i]\""

You’ll then start seeing the logs as follows:

192.168.1.2 - - [29/Sep/2014:10:56:31 +0100] "POST /login.php HTTP/1.1" 200 15 "-" "curl/7.19.7 " "[XF 10.10.1.1]"

So what we’re interested in here is that the request is coming from the external IP 10.10.1.1 (yes, I know that’s private address space but for this post I’m not going to use “real” IP addresses)

Create Your Fail2Ban Filter Recipe

There’s three parts of this, the filter, the “jail” and the custom IPTable action.

Filter

Create your filter in fail2ban/filter.d accordingly:

# Fail2Ban configuration file

Author: Centos.Tips

$Revision: 1$

[Definition]

Option:  failregex

Notes.:  Regexp to catch Apache brute force login attempts (using X-Forwarded-For)

Values:  TEXT

failregex = POST .*/login.php.*\[XF <HOST>

Option:  ignoreregex

Notes.:  regex to ignore. If this regex matches, the line is ignored.

Values:  TEXT

ignoreregex =

Action

Create your custom IPTables action in fail2ban/action.d accordingly:

# Fail2Ban configuration file

Author: Centos.Tips

[INCLUDES]

before = iptables-blocktype.conf

[Definition]

Option:  actionstart

Notes.:  command executed once at the start of Fail2Ban.

Values:  CMD

actionstart = iptables -N fail2ban-               iptables -A fail2ban- -j RETURN               iptables -I -p --dport -j fail2ban-

Option:  actionstop

Notes.:  command executed once at the end of Fail2Ban

Values:  CMD

actionstop = iptables -D -p --dport -j fail2ban-              iptables -F fail2ban-              iptables -X fail2ban-

Option:  actioncheck

Notes.:  command executed once before each actionban command

Values:  CMD

actioncheck = iptables -n -L | grep -q 'fail2ban-[ \t]'

Option:  actionban

Notes.:  command executed when banning an IP. Take care that the

#          command is executed with Fail2Ban user rights.

Tags:    See jail.conf(5) man page

Values:  CMD

actionban = iptables -I fail2ban- 1 -p tcp --dport 80 -m string --algo bm --string 'X-Forwarded-For: ' -j DROP

Option:  actionunban

Notes.:  command executed when unbanning an IP. Take care that the

#          command is executed with Fail2Ban user rights.

Tags:    See jail.conf(5) man page

Values:  CMD

actionunban = iptables -D fail2ban- -p tcp --dport 80 -m string --algo bm --string 'X-Forwarded-For: ' -j DROP

[Init]

Default name of the chain

name = default

Option:  port

Notes.:  specifies port to monitor

Values:  [ NUM | STRING ]  Default:

port = http

Option:  protocol

Notes.:  internally used by config reader for interpolations.

Values:  [ tcp | udp | icmp | all ] Default: tcp

protocol = tcp

Option:  chain

Notes    specifies the iptables chain to which the fail2ban rules should be

#          added

Values:  STRING  Default: INPUT

chain = INPUT

The difference between this and a normal IPTables DROP is that we have to do packet inspection  where we look for the X-Forwarded-For and the relevant IP address in the packet before we drop it.  This should generally work but your mileage may vary.

Jail

Now you can mix together your recipe and stick it in your fail2ban/jail.local file

[apache-proxy] enabled = true filter = apache-proxy action = iptables-proxy[name = apache-proxy, port = http, protocol = tcp]          sendmail-whois[name=LoginDetect, dest=yourname@yourdomain.com, sender=fail2ban@yourdomain.com, sendername="Fail2Ban"] port = http logpath = /path/to/your/access_log maxretry = 5 findtime = 60 bantime = 900

So here we’ll allow 5 login attempts in a minute, after that you’re blocked from the server for 15 minutes.

Reload fail2ban and you’re done!

首页 - Wiki
Copyright © 2011-2024 iteam. Current version is 2.124.0. UTC+08:00, 2024-05-02 22:33
浙ICP备14020137号-1 $访客地图$