前一段时间博客站被人恶意 cc 攻击,虽然没有打死,但造成博客站访问变慢甚至不能访问,服务器资源(主要是带宽和 CPU 资源)被消耗殆尽,无法提供正常服务。CC 攻击属于 DDOS 攻击的一种,但又不相同,现在的 DDOS 攻击主要是流量攻击并属于 Layer3、Layer4 攻击,针对的是服务器的网络资源,而 CC 攻击是 Layer7 攻击,针对的是在服务器上面运行的网站或者应用程序。常规高防服务器通过流量清洗可以抵挡 DDOS 攻击,但却无法阻挡 CC 攻击,只有通过 WAF(Web Application Firewall)对可疑流量进行筛查并阻拦才可以阻挡。

计算机网络的七层结构、五层结构和四层结构_AllenLeungX的博客-CSDN博客_计算机网络有几层

LoadBalancer Types: L3, L4, L7 - 호롤리한 하루

Cloudflare 自带 WAF,但套了 CF 会浪费小鸡的优质带宽,特别是中国大陆用户访问体验极差,宝塔面板的 Nginx WAF 防火墙固然可以起到一定的效果,但工作在 Layer7 是其一大特点,当流量已经到达 Layer7, 使用防火墙再去阻拦还是会消耗服务器的 CPU 资源,特别是配置低的 VPS 根本扛不住,所以我们的方案就是要在 Layer3、Layer4 阻拦可疑流量,并快速封禁攻击 IP,阻止流量到达 Layer7。

我的方案是用 fail2ban 读取 nginx 日志并分析出可疑 IP,使用 ufw 或者 firewalld 封禁,这样所有可疑流量都会被阻止,并且不会影响真实用户的访问。

值得注意的是,宝塔面板自带的 fail2ban 尽量不要用,是坏的!

本文以基于 Debian11,linux 其它发行版只要可以安装 fail2ban 就可以一样使用。

安装 fail2ban

bash
1
2
apt install -y fail2ban
sudo systemctl enable fail2ban #配置开机启动

其他相关命令:

  • sudo fail2ban-client status #查看 Fail2ban 的状态
  • sudo fail2ban-client version #查看 Fai2ban 的版本
  • sudo fail2ban-client ping #检查 Fail2ban 是否正常运行(正常将显示 pong
  • sudo systemctl start fail2ban #启动 Fail2ban
  • sudo systemctl stop fail2ban #停止 Fail2ban
  • sudo systemctl restart fail2ban #重启 Fail2ban
  • sudo tail -f /var/log/fail2ban.log #打开 Fail2ban 的日志监控
  • sudo fail2ban-client status 配置项目名 #查看某项目的状态

配置 fail2ban

Fail2ban 在安装时会创建两个默认的配置文件 /etc/fail2ban/jail.d/defaults-debian.conf/etc/fail2ban/jail.conf。我们不建议直接修改这些文件,因为更新 Fail2ban 时它们可能会被覆盖。

Fail2ban 将按以下顺序读取配置文件。每个.local 文件都会覆盖.conf 文件中的设置:

  • /etc/fail2ban/jail.conf
  • /etc/fail2ban/jail.d/*.conf
  • /etc/fail2ban/jail.local
  • /etc/fail2ban/jail.d/*.local

每个.local 文件都会覆盖.conf 文件中的设置。配置 Fail2ban 的最简单方法是将 jail.conf 复制到 jail.local 并修改.local 文件。你也可以从头开始构建.local 配置文件。

.local 文件不必包含.conf 文件中的所有设置,只需包含您要覆盖的设置即可。使用以下命令,从默认的 jail.conf 文件创建一个.local 配置文件:

bash
1
2
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

设置默认配置

makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#默认设置,优先级最低
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 YOUR_SERVER_IP #白名单,可以自己再添加。
bantime = 86400
findtime = 600 #设置失败次数之间的持续时间。
maxretry = 5 #在以上的findtime时间内最大访问次数,超过即执行action。
banaction = ufw #Debian、Ubuntu使用ufw,CentOS使用firewalld,不建议使用iptables。
action = %(action_mwl)s

# SSH防爆破
[ssh]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 6

# nginx防cc
[nginx-cc]
enabled = true
port = http,https
filter = nginx-bt-cc
action = %(action_mwl)s
maxretry = 40 #自己调整
findtime = 30 #自己调整
bantime = 600 #自己调整
logpath = /www/wwwlogs/ceshi.xyz.log
/www/wwwlogs/*com.log
/www/wwwlogs/*.log #根据自己需求设置日志的路径

设置过滤器

vim
1
nano /etc/fail2ban/filter.d/nginx-bt-cc.conf

设置日志的格式,如果是宝塔复制粘贴即可:

ruby
1
2
3
[Definition]
failregex = (,)?<HOST> .*- .*HTTP/1.* .* .*$
ignoreregex =

重启 fail2ban

保存设置,完成后执行

axapta
1
2
fail2ban reload
sudo fail2ban-client status

检查 nginx-cc 服务的状态:

axapta
1
sudo fail2ban-client status nginx-cc

删除已被限制 IP:

gams
1
sudo fail2ban-client set nginx-cc unbanip 1.1.1.1

禁止已被限制的 IP:

gams
1
sudo fail2ban-client set nginx-cc banip 1.1.1.1