使用fail2ban进行攻击防范

最近总有一些无聊的人,会来扫描一下我的服务器,看有没有啥漏洞可以利用的。。。

可以看到类似这样的404访问日志:

[W 2017-06-07 08:32:32 web:1728] 404 GET //pluse7xue.php (103.229.125.236) 0.55ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //plusmybak.php (103.229.125.236) 0.57ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //plusxsvip.php (103.229.125.236) 0.60ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //pluslaobiao.php (103.229.125.236) 0.60ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //xiaolei.php (103.229.125.236) 0.45ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //dxyylcmd5.php (103.229.125.236) 0.45ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //UserFilesx.aspx (103.229.125.236) 0.52ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //UserFilesx.aspx (103.229.125.236) 0.38ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //UserFilesx.aspx (103.229.125.236) 0.44ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //datacachefuck.php.parse_search_.inc (103.229.125.236) 0.47ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //datacachefuck.php.parse_search_.inc (103.229.125.236) 0.49ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //datacachefuck.php.parse_search_.inc (103.229.125.236) 0.43ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //utilityconvertdataconfig.inc.php (103.229.125.236) 0.43ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //configAspCms_Config.asp (103.229.125.236) 0.42ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //plusbakup.php (103.229.125.236) 0.43ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //includecodemp.php (103.229.125.236) 0.59ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //templetsplussky.php (103.229.125.236) 0.57ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //plusmytag_j.php?aid=6022 (103.229.125.236) 0.60ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //plusmytag_j.php?aid=6022 (103.229.125.236) 0.47ms
[W 2017-06-07 08:32:32 web:1728] 404 GET //plusmytag_j.php?aid=6022 (103.229.125.236) 0.49ms

.....

这种攻击的特点就是短时间内会大量的404请求,可以利用这一特点,用工具进行拦截,检测到多少时间内,404请求数超过了多少,就把这个ip给封掉。

于是就从网上搜索到了这个工具:fail2ban,官方主页:https://www.fail2ban.org/wiki/index.php/MANUAL_0_8

在Ubuntu中安装fail2ban很简单:

sudo apt-get install fail2ban

安装好后,配置文件在 /etc/fail2ban 里面。

首先我们需要配置一个filter规则,以便检测我们的日志文件中404的目标。

vim /etc/fail2ban/filters.d/web-404.conf

[INCLUDES]

before = common.conf

[Definition]

failregex = web:1728\] 404 GET .*?\(<HOST>\)

写好规则后,可以用命令行测试一下能不能命中:

fail2ban-regex 2017060708.log /etc/fail2ban/filter.d/web-404.conf 

有一点必须注意,你的日志文件中,行的开头一定要先命中时间戳,格式可以是系统能识别的时间格式,如果没有命中时间,那么你写的filter规则是永远不会被命中的。

比如我刚开始的日志格式是这样的:

W 20170607 08:32:32 web:1728] 404 GET //plusxsvip.php (103.229.125.236) 0.60ms

日期格式 20170607 不能被识别,所以我写的filter规则死活命中不了。。。

官方文档有解释:https://www.fail2ban.org/wiki/index.php/MANUAL_0_8

In order for a log line to match your failregex, it actually has to match in two parts: the beginning of the line has to match a timestamp pattern or regex, 
and the remainder of the line has to match your failregex. 
If the failregex is anchored with a leading ^, then the anchor refers to the start of the remainder of the line, after the timestamp and intervening whitespace.

The pattern or regex to match the time stamp is currently not documented, and not available for users to read or set. 
See Debian bug #491253. This is a problem if your log has a timestamp format that fail2ban doesn't expect, since it will then fail to match any lines. 
Because of this, you should test any new failregex against a sample log line, as in the examples below, to be sure that it will match. 
If fail2ban doesn't recognize your log timestamp, then you have two options: either reconfigure your daemon to log with a timestamp in a more common format, 
such as in the example log line above; or file a bug report asking to have your timestamp format included.

如果要自定义时间格式,可以在filter的配置中设置 datepattern 参数,详情见官方文档:https://manpages.debian.org/testing/fail2ban/jail.conf.5.en.html

定义好filter后,就可以写ban的规则:

cat /etc/fail2ban/jail.local


[web-404]

enabled = true
port = http,https
filter  = web-404
logpath  = /var/log/supervisor/web.log tail
maxretry = 10
bantime = 86400
findtime = 60

上面配置的含义就是,使用 moviex_web-404 这一个filter配置,检测日志文件logpath,在findtime时间内,匹配到 maxretry 次数后,就ban掉对方的ip,在有效时间 bantime 内,拒绝对方连接 port 参数指定的端口。

logpath 的第二个参数可以是 head 或 tail,默认为head,从日志的开头进行匹配,这样有个不好的地方就是每次重启fail2ban后,都要从日志开头匹配一遍。

如果有多个logpath,则换行写,一行写一条。

可以在 jail.local 中定义忽略ip,比如说google 爬虫的ip地址,在jail.local文件中加上配置:

[DEFAULT]
# 以空格分隔的列表,可以是 IP 地址、CIDR 前缀或者 DNS 主机名
# 用于指定哪些地址可以忽略 fail2ban 防御
ignoreip = 127.0.0.1 172.31.0.0/24 10.10.0.0/24 192.168.0.0/24

如果想要让ip白名单只针对某些jail规则生效,则可以使用fail2ban-client命令来设置。例如:

fail2ban-client set web-404 addignoreip 123.45.67.89   

重启fail2ban生效后,可以查看日志 /var/log/fail2ban.log 来看检测情况,也可以通过命令行来查看状态:

# 查看所有jail状态
sudo fail2ban-client status

# 查看web-404 这个jail的状态
sudo fail2ban-client status web-404

# 解封ip
sudo fail2ban-client set web-404 unbanip 192.168.1.8

fail2ban-client 还有很多其它命令,可以参考文档说明: fail2ban-client –help