fail2ban
使用fail2ban保护服务器
把坏人关进监狱!
大量异常请求
搭建服务器后,本来觉得高枕勿忧了。可是一看apache的日志,发现一天就有3k访问记录。
sudo less /var/log/apache2/access.log
sudo tail -n <num> /var/log/apache2/access.log
其中的异常记录有几种:
- 访问敏感端口,如cloudflare 2053
- wordpress,特征wp-xxx、wordpress、php
- git,试图访问.git目录
- 短时间内大量访问其他不存在的位置
在下一步之前,需要配置apache日志显示真实ip,参见另一篇。
屏蔽2053端口
sudo ufw deny in to any port 2053
sudo iptables -A INPUT -p tcp --dport 2053 -j DROP
另外,还需要确保cloudflared只监听127.0.0.1
sudo lsof -i -P -n | grep LISTEN | grep 2053
如果有输出,则不安全,重新设置cfd监听端口
cloudflare tunnel --url http://127.0.0.1:8080
fail2ban概述
sudo apt install fail2ban
fail2ban有几个重要的位置
- /etc/fail2ban/filter.d/
.conf - 基于regex的过滤器
- /etc/fail2ban/jail.local
- 配置监狱,每个filter的行为在这里配置
- /etc/fail2ban/action.d/
.conf - filter匹配成功后的行为
可以设置多个filter用来屏蔽不同类型的请求,在jail.local中随时打开关闭,很灵活。
fail2ban一般流程
以apache-wordpress为例子
1.添加filter规则,对tab和空格没有要求
sudo nano /etc/fail2ban/filter.d/apache-wordpress.conf
[Definition]
failregex = ^<HOST> -.*"(GET|POST) .*wp-(login|admin|content|includes).* HTTP.*"
^<HOST> -.*"(GET|POST) .*php.* HTTP.*"
^<HOST> -.*"(GET|POST) .*wordpress.* HTTP.*"
ignoreregex =
2.配置新jail
sudo nano /etc/fail2ban/jail.local
添加这一段
[apache-wordpress]
enabled = true
filter = apache-wordpress
# 抓到后的行为,在action.d配置
action = cloudflare-ban
logpath = /var/log/apache2/access.log
# 最大尝试次数
maxretry = 2
# 统计周期,单位sec
findtime = 60
# 封禁时间,单位sec,-1为永封
bantime = -1
# 务必ignore你的管理用地址
ignoreip = 127.0.0.1 192.168.1.0
3.验证
验证regex是否能匹配/是否过匹配
sudo fail2ban-regex <access.log> <apache-wordpress.conf>
重启服务
sudo systemctl restart fail2ban
显示正在运作的jail
sudo fail2ban-client status
显示某个jail的状态
sudo fail2ban-client status apache-wordpress
action.d
如果是一般的公网服务器,action可以直接调用防火墙来屏蔽
action = iptables[name=Apache-WP, port=http, protocol=tcp]
但是cloudflare tunnel中这样配置无效,因为iptables或ufw无法阻断通过cloudflared代理的请求。 这就需要配置新的action,在cloudflare那一层封禁ip。
然而,cloudflare WAF是收费的,不过我们可以用api实现免费的防护。这需要:
- 添加action
- 获得cloudfalre token,以赋予action权限
- 添加action
sudo nano /etc/fail2ban/action.d/cloudflare-ban.conf
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = curl -s -X POST "https://api.cloudflare.com/client/v4/zones/<zone-id>/firewall/access_rules/>
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
--data "{\"mode\":\"block\",\"configuration\":{\"target\":\"ip\",\"value\":\"<ip>\"},\"notes\":\"Blocked by Fail2Ban\"}"
actionunban = echo "Unban not supported via Cloudflare API"
[Init]
注意需要安装curl,有时系统没有自带它。
其中zone-id和token需要替换,接下来我们去获得它们。
- 获取zone-id
打开cloudflare dashboard,点进域名,在“API”那里可以看到“区域ID”,这就是zone-id。
- 获取token
前往“我的-API Tokens”,点击创建token。 有一些可以选择的条目,至少需要包含:
- Zone.Zone: Read
- Zone.Firewall Services: Edit
生成后建议保存token到备忘录,因为无法再次查看它。同时一定保密。
- 代入
把两个值代入cloudflare-ban.conf。 在jail.local中,把action改成:
action = cloudflare-ban
重启fail2ban。
- 验证
前往dashboard-域-安全-事件,过一会就会出现封禁记录了。
解封
显示某个jail的状态,这会给出所有被这个规则封禁了的ip
sudo fail2ban-client status apache-wordpress
找到想要的ip
sudo fail2ban-client set <jail-name> unbanip <ip>
其他jail
apache-abuse
apache-post