#server#security

fail2ban

developer

使用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权限
  1. 添加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需要替换,接下来我们去获得它们。

  1. 获取zone-id

打开cloudflare dashboard,点进域名,在“API”那里可以看到“区域ID”,这就是zone-id。

  1. 获取token

前往“我的-API Tokens”,点击创建token。 有一些可以选择的条目,至少需要包含:

  • Zone.Zone: Read
  • Zone.Firewall Services: Edit

生成后建议保存token到备忘录,因为无法再次查看它。同时一定保密。

  1. 代入

把两个值代入cloudflare-ban.conf。 在jail.local中,把action改成:

action = cloudflare-ban

重启fail2ban。

  1. 验证

前往dashboard-域-安全-事件,过一会就会出现封禁记录了。

解封

显示某个jail的状态,这会给出所有被这个规则封禁了的ip

sudo fail2ban-client status apache-wordpress

找到想要的ip

sudo fail2ban-client set <jail-name> unbanip <ip>

其他jail

apache-abuse

apache-post