前一段时间博客站被人恶意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

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配置文件:

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

设置默认配置

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 #根据自己需求设置日志的路径

设置过滤器

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

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

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

重启fail2ban

保存设置,完成后执行

1
2
fail2ban reload
sudo fail2ban-client status

检查nginx-cc服务的状态:

1
sudo fail2ban-client status nginx-cc

删除已被限制IP:

1
sudo fail2ban-client set nginx-cc unbanip 1.1.1.1

禁止已被限制的IP:

1
sudo fail2ban-client set nginx-cc banip 1.1.1.1