A. 技术环境
系统:Linux
web Server: Apache
应用场景:私人环境或流量少的网站
B. 概述
2022年写了一篇相关的分享,实际上没有找到特别令人满意的解决方案,如今在AI的加持下终于发现一个对个人用户比较适合的方案。
在下面探讨中提到3个工具:
- mod_qos (apache 模块)对个人过于强大
- mod_evasive (apache 模块)够及时,但有点糙
- fail2ban (第三方工具)有点马后炮的意思
C. 企业级的防护mod_qos
mod_qos 是一个非常强大且复杂的 Apache 模块,可以看作是 mod_evasive
的"超级加强版"或"企业版"。
mod_qos 是什么?
mod_qos 是一个服务质量(Quality of Service, QoS)和流量管理模块,用于 Apache HTTP 服务器。它的核心目标是保护您的 Web 服务器和应用资源,确保其在高负载或遭受攻击时仍能保持稳定,并为重要流量提供优先服务。
您可以将其理解为一个功能极其丰富的 Web 应用防火墙(WAF)和流量整形器的结合体。
核心功能是什么?
与 mod_evasive
(主要专注于防御请求洪水攻击)相比,mod_qos
的功能要广泛和精细得多,主要包括:
1. 连接和请求限制(与 mod_evasive 类似但更强)
- 限制并发连接数:限制单个 IP、或整个服务器允许的最大并发连接数。
- 限制请求频率:限制每秒请求数(QPS),可针对单个 IP、特定 URL、或特定 HTTP 方法(如 POST)。
- 动态限制:可以根据服务器的当前负载(如 CPU 使用率、活动连接数)动态地启用或调整限制规则。
2. 基于特征的请求过滤(更智能的防护)
这是它比 mod_evasive
强大的关键。它可以分析请求内容并据此进行控制:
- 过滤恶意请求 :根据请求头(如
User-Agent
、Referer
)、URI(路径和参数)、HTTP 方法等特征来识别和阻止恶意流量(如扫描器、注入攻击、恶意爬虫)。 - 阻止特定攻击模式 :例如,可以轻松配置规则来阻止包含
../
(路径遍历攻击特征)或特定 SQL 关键词的请求。
3. 优先级和流量整形(真正的 QoS)
这是它的独到之处,可以实现精细化的流量管理:
- 请求优先级:可以为不同的请求分配不同的优先级。例如,来自已知用户的请求、对关键API的请求、或购物车的结账请求可以优先处理,而搜索引擎爬虫或大文件下载的请求优先级可以调低。
- 带宽限制:限制特定请求或连接的带宽占用,防止某个下载任务拖垮整个服务器。
- 公平共享资源:确保每个客户端 IP 能够公平地使用服务器资源,防止少数IP霸占所有连接。
4. 会话保护
- SSL/TLS 限制:可以限制 SSL/TLS 握手频率,以减轻"SSL 耗尽攻击"带来的 CPU 压力。
- 会话跟踪:通过 Cookie 或 URL 参数来跟踪用户会话,并基于会话来实施限制策略。
与 mod_evasive 的简单对比
特性 | mod_evasive | mod_qos |
---|---|---|
定位 | 轻量级防御工具 | 企业级流量管理套件 |
主要目的 | 防御 DDoS/洪水攻击 | QoS、流量整形、安全防护 |
配置复杂度 | 简单,几个参数 | 非常复杂,功能多配置项也多 |
控制粒度 | 较粗,主要基于IP和频率 | 极细,可基于IP、URL、头、内容、服务器状态等 |
优先级管理 | 无 | 有,核心功能之一 |
适用场景 | 个人网站、小型项目,需要快速部署防御 | 大型、高流量网站、商业应用,需要精细化管理 |
总结
mod_qos 是一个极其强大的模块,如果你需要:
- 保护服务器免受各种复杂攻击(而不仅仅是洪水攻击)。
- 确保关键业务(如登录、支付API)在高负载下永远可用。
- 对服务器流量进行精细化管理和整形。
- 拥有比
mod_fail2ban
(动态封禁)和mod_evasive
(频率限制)更实时、更高效的防护手段。
那么 mod_qos
是理想的选择。但是,它的学习曲线非常陡峭 ,配置不当反而可能影响正常用户访问。对于大多数个人用户或中小型网站来说,mod_evasive
+ fail2ban
的组合已经足够强大且更易于管理。
如果您决定使用它,请务必仔细阅读其详尽的官方文档,并在测试环境中充分验证配置后再应用到生产服务器。
D. Fail2Ban
1. 安装 Fail2Ban(如果尚未安装)
bash
sudo apt update
sudo apt install fail2ban
2. 创建自定义 Fail2Ban 规则
(A) 创建 apache-404
jail 规则
编辑或创建新的 jail 配置文件:
bash
sudo nano /etc/fail2ban/jail.d/apache-404.conf
上面的目录和文件名有问题
填入以下内容:
ini
[apache-404]
enabled = true
port = http,https
filter = apache-404
logpath = /var/log/apache2/access.log # Apache 访问日志路径
maxretry = 5 # 20 秒内 5 次 404 触发封禁
findtime = 20 # 时间窗口(秒)
bantime = 86400 # 封禁时间(秒,86400=1天)
action = %(action_)s
maxretry = 5
:20 秒内 5 次 404 触发封禁findtime = 20
:时间窗口 20 秒bantime = 86400
:封禁 1 天(可调整,-1
表示永久封禁)
(B) 创建 apache-404
filter 规则
Fail2Ban 需要一个 filter 来匹配 Apache 的 404 错误日志:
bash
sudo nano /etc/fail2ban/filter.d/apache-404.conf
填入以下内容:
ini
[Definition]
failregex = ^<HOST>.*"GET.*HTTP/1\.." 404 .*$
ignoreregex =
failregex
匹配所有 HTTP GET 请求返回 404 的日志行- 如果你的 Apache 日志格式不同(如
%h %l %u %t \"%r\" %>s %b
),可能需要调整正则表达式
3. 重启 Fail2Ban 使配置生效
bash
sudo systemctl restart fail2ban
4. 检查 Fail2Ban 是否正常工作
(A) 查看封禁状态
bash
sudo fail2ban-client status apache-404
输出示例:
yaml
Status for the jail: apache-404
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/apache2/access.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
(B) 手动测试规则
bash
sudo fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/apache-404.conf
如果匹配成功,说明规则生效。
5. 查看被封禁的 IP
bash
sudo fail2ban-client status apache-404
或
bash
sudo iptables -L -n # 查看 iptables 规则
6. 调整封禁时间
如果你想永久封禁(或调整封禁时间),修改 bantime
:
ini
bantime = -1 # 永久封禁
然后重启 Fail2Ban:
bash
sudo systemctl restart fail2ban
7. fail2ban的时效性特点
fail2ban的响应速度取决于日志生成和分析的延迟,通常在攻击者尝试多次失败后才会触发封禁(默认SSH规则为5分钟内6次失败)。这种机制确实存在"攻击已发生才响应"的特点,但相比完全被动防御仍有价值;特别要注意的是屏蔽时间应该相对长一些,比如60d->2个月。
8. 实例
jail.local
ini
[apache-badbots]
enabled = true
[apache-404]
enabled = true
port = http,https
filter = apache-404
logpath = /var/log/apache2/access.log
maxretry = 3 #重复3次
findtime = 5 #5秒内
bantime = 72h #屏蔽3天
action = iptables-multiport[]
查看状态
css
userxxx@deb12:~$ sudo fail2ban-client status apache-404
Status for the jail: apache-404
|- Filter
| |- Currently failed: 2
| |- Total failed: 73
| `- File list: /var/log/apache2/access.log
`- Actions
|- Currently banned: 4
|- Total banned: 5
`- Banned IP list: 185.177.72.144 165.227.37.233 118.193.59.10 185.177.72.29
E. mod_evasive 模块
额外防护建议(适用于 Apache2)
1. 限制访问敏感路径(如 .env
、wp-admin
)
在 Apache 配置中(如 /etc/apache2/sites-available/000-default.conf
):
apache
<LocationMatch "\.env|\.git|wp-admin|password\.php">
Require all denied
</LocationMatch>
然后重启 Apache:
bash
sudo systemctl restart apache2
2. 隐藏 Apache 版本信息
编辑 /etc/apache2/conf-available/security.conf
:
apache
ServerTokens Prod
ServerSignature Off
然后重启 Apache:
bash
sudo systemctl restart apache2
3. 使用 mod_evasive
防止暴力扫描
这个模块主要是为了防DDoS攻击的,也可以用来防止扫描!
安装并配置 mod_evasive
:
bash
sudo apt install libapache2-mod-evasive
sudo nano /etc/apache2/mods-enabled/evasive.conf
填入:
apache
<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 5
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 3600
</IfModule>
这里的DOSSiteCount要足够小,不然会被绕开。 然后重启 Apache:
bash
sudo systemctl restart apache2
evasive 起作用了,成功屏蔽了相应的IP,可以在error.log中看到