一、遇到的问题

防火墙、反向代理或者负载均衡这些设备,为了提供服务,会安装在用户和服务器之间,作为中间人转发用户的流量给服务器。服务器只与这些设备通信,在不经过配置的情况下拿不到客户的真实ip,导致无法通过iptables限制ip访问,同时其他需要客户真实ip的服务也会受到影响。

二、解决方法

对于7层的http服务来说,防火墙/代理通过设置X-Forwarded-For参数,可以将用户的ip转给后端web服务器。对于恶意的攻击流量,通过iptables匹配字符串功能,将包含X-Forwarded-For:ip的流量丢掉,从而达到限制ip访问的目的

屏蔽规则:

iptables -I  INPUT 1 -p tcp --dport 80 -m string --algo bm --string 'X-Forwarded-For: <ip>' -j DROP

解除屏蔽:

iptables -D  INPUT -p tcp --dport 80 -m string --algo bm --string 'X-Forwarded-For: <ip>' -j DROP

有了这两个规则,就可以用fail2ban来检测恶意流量了。
对于4层的应用,能不能简单的通过配置让后端拿到客户的真实ip?答案是不能,目前没有4层的tcp代理能实现保持源ip的功能,至少开源的软件中没有
能不能实现?答案是可以,需要tcp代理在转发流量时更改ip报头,要自己编程写,这里只说7层的情况

三、配置方法

3.1 配置防火墙、反向代理、负载均衡

增加http头:X-Forwarded-For,基本上这类软件都都支持,配置方法要看所用的软件

3.2 安装配置fail2ban

fail2ban安装、配置filer和jail:
见:https://opswill.com/articles/nginx-anti-ddos-setting-2.html
根据上面的两条iptables规则,新建fail2ban的action,参考自带的iptables规则文件,改一下:

[INCLUDES]

before = iptables-blocktype.conf

[Definition]

actionstart = iptables -N fail2ban-<name>
          iptables -A fail2ban-<name> -j RETURN
          iptables -I <chain> -p <protocol> --dport <port> -j fail2ban-<name>

actionstop = iptables -D <chain> -p <protocol> --dport <port> -j fail2ban-<name>
         iptables -F fail2ban-<name>
         iptables -X fail2ban-<name>

actioncheck = iptables -n -L <chain> | grep -q 'fail2ban-<name>[ \t]'

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

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

[Init]
name = default
port = http
protocol = tcp
chain = INPUT

保存为action.d/iptables-proxy.conf

jail的配置文件中指定action:

[iptables-proxy]
enabled = true
filter = iptables-proxy-filter
action = iptables-proxy[name = iptables-proxy , port = http, protocol = tcp]
port = http
logpath = /path/to/your/log
maxretry = 5
findtime = 60
bantime = 3600

上面的配置按照实际情况修改,fail2ban的用法不多说了,主要就是action文件

参考文章:
http://centos.tips/fail2ban-behind-a-proxyload-balancer/