最近手头几个用轻量云跑的独立站点,访问日志里充斥着大量的自动化扫描脚本,每天都有成千上万次针对 /wp-includes、/.env、/phpmyadmin 等路径的试探。虽然后端都做了基础权限隔离,但 Nginx 和 PHP 频繁响应这些无效请求,仍然白白浪费了服务器 CPU。
索性在宝塔里开启了 Nginx 防火墙模块,经过两周的线上观察与误杀调优,服务基本恢复平稳。把目前跑得比较稳定的防御策略与踩坑经验记录下来,方便以后开新机器参考。
1. 默认规则启用与误杀处理
刚开防火墙时,建议先不要直接拉满所有防护开关。Nginx 防火墙的默认规则包含 SQL 注入、XSS 跨站、文件上传限制等。如果是纯静态站点直接开没问题,但如果带动态后台或 REST API,非常容易出现误杀:
- 后台文章保存报 403:写技术文章经常涉及代码片段(如包含
select * from、<script>标签),防注入规则会直接拦截。这类情况不要直接关掉全局防注入,而是去“URL 白名单”里,把管理后台的保存接口加入例外(例如/wp-admin/post.php或/api/v1/posts)。 - WebHook 误杀:GitHub 或 Gitee 的 WebHook 推送 Payload 较大且包含 JSON 结构,容易触发 POST 过滤规则,需要单独将 WebHook 的接收路径放行。
- 排查路径:遇到请求异常,第一时间翻看防火墙的“拦截日志”,里面会详细标出是哪一条规则(Rule ID)、请求哪个 URL、携带了什么特征参数触发了拦截,针对性放行即可。
2. 核心防御参数配置参考
防护规则中最核心的是 CC 防御(即限制单个 IP 的访问频次)。很多新手容易把阈值设得过低,导致同一个办公室使用同一个公网 IP 出口的多个人访问时,全部被拉黑。
根据不同服务器配置与业务规模,建议的参数调优参考如下:
| 服务器配置与业务场景 | 单 IP 周期与频次限制 | 触发封锁时长 | 初始防御等级建议 |
|---|---|---|---|
| 1核 1G ~ 1核 2G(个人低频博客) | 60秒内超过 120次 | 300秒(5分钟) | 宽松(先观察误杀,过滤扫描器即可) |
| 2核 4G(带会员/商城系统) | 10秒内超过 60次 | 600秒(10分钟) | 正常(配合白名单放行静态资源) |
| 4核 8G 以上(高并发内容站) | 5秒内超过 80次 | 1800秒(30分钟) | 严格(静态资源走外部 CDN,仅防动态接口) |
参数说明:
- 周期与频次:务必给静态资源配置缓存或让防火墙忽略
.js、.css、.png等后缀。如果把静态资源的请求也算进频次里,一个正常访客打开包含几十张图片的页面就会被误封。 - 封禁时间:普通攻击往往是脚本批量跑,封锁 5 到 10 分钟通常足够让扫描器超时撤退,不需要一上来就封禁永久,避免误封正常访客后无法自愈。
3. 套了 CDN 之后的配置踩坑
这是不少站长最常踩的坑:一旦站点接入了 Cloudflare 或国内 CDN,所有外部流量都会先经过 CDN 节点,再回源到你的宝塔服务器。
如果不做配置调整,防火墙看到的“访客 IP”实际上全是 CDN 的回源节点 IP:
- 灾难后果:一个攻击者发起 CC 攻击,防火墙识别到某个 CDN IP 请求频繁,直接把该节点 IP 拉入黑名单。结果就是该节点承载的所有正常访客全部遭遇 403 拒绝访问,甚至全站直接打不开。
- 解决方式:
set_real_ip_from 声明 CDN 的回源网段,并指定获取真实 IP 的 Header 为 X-Forwarded-For 或 CF-Connecting-IP。
- 确认日志中的 IP 地址已经变回访客真实公网 IP 后,才能开启 CC 频率拦截。
4. 为什么开了防火墙依然扛不住大流量?
实际维护中必须明确防火墙的边界能力:宝塔 Nginx 防火墙属于应用层(Layer 7)的软件防护。
软件防火墙的本质是 Nginx 读取了请求报文,通过 Lua 脚本或正则匹配规则进行计算和拦截。如果遭遇几十万 QPS 的洪峰 CC,或者数十 Gbps 的流量攻击(DDoS),这些流量依然实打实地打到了你的网卡和 Nginx 进程上,CPU 会因为频繁进行正则匹配直接跑满 100%,服务器依然会瘫痪。
因此,合理的架构思路是:
- 应对小体量的爬虫扫漏洞、弱口令撞库、低频恶意 CC,利用本机的 Nginx 防火墙直接掐断,最省心且不增加额外网络延迟。
- 遇到真正的大流量攻击,必须在流量到达源站服务器之前,由最外层的云厂商高防 IP 或 CDN 边缘节点清洗掉,不要指望单台云主机的软防火墙去硬抗。