CentOS服务器配置WAF规则阻断SQL注入扫描
Fail2Ban基于日志中SQL注入特征(如unionselect)封禁IP,需确保日志完整、正则精准、firewalld适配及云安全组同步。但它属事后封禁,无法实时阻断,真正阻断需依赖ModSecurity或云WAF。
在探讨如何利用 Fail2Ban 防护 SQL 注入攻击之前,首先需要明确一个关键概念:Fail2Ban 并不能直接拦截请求。它的运行机制属于“事后响应”——通过分析 Web 日志中残留的攻击痕迹(如 union select、' OR '1'='1 等典型特征),对发起攻击的 IP 进行封禁。然而,这一策略能否真正生效,取决于多个环节:日志是否完整记录了请求参数,filter 正则表达式是否精准,jail 配置是否与 firewalld 正确对接,以及云平台安全组是否需要手动同步。

需要再次强调:Fail2Ban 无法直接阻断 SQL 注入扫描,它仅能依据 Web 日志中已记录的攻击特征(如 union select、' OR '1'='1)对攻击 IP 进行事后封禁,且前提是日志确实包含了这些内容。
确认 Nginx 或 Apache 日志是否记录了攻击载荷
许多默认配置并不会将 URL 参数写入 /var/log/nginx/access.log,这会让 Fail2Ban 无法获取攻击数据。
- 第一步,检查日志格式。执行
grep log_format /etc/nginx/nginx.conf,确认是否包含$request_uri或$args变量。更可靠的方法是显式启用完整请求行记录:log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent'; - 第二步,手动发送一次测试请求以验证日志记录。例如:
curl "https://yoursite.com/search?q=1%27%20OR%20%271%27%3D%271",然后立即执行:tail -n 20 /var/log/nginx/access.log | grep -i "or.*1.*1" - 如果没有输出,说明日志字段缺失,后续编写的 filter 再精确也无济于事。Apache 用户同理,需要检查
LogFormat是否包含%r,并确保CustomLog正确引用了该格式。
编写 Fail2Ban filter 匹配典型 SQL 注入特征
不要直接复用 sshd 的配置,而应单独新建一个 /etc/fail2ban/filter.d/nginx-sql.conf 文件,并且正则表达式需要设计得足够严谨,以免被攻击者绕过。
failregex必须以^开头,并以$结尾,否则可能导致跨行误匹配。- 建议使用
(?=.*)正向先行断言组合多个关键词,例如:unions+select|sleep(|'s*ors*'1's*=s*'1,这样可以防止仅匹配单一特征而被绕过。 - 避免使用
.*匹配中间任意字符,因为其性能较差且易产生误判。改用[^&nr]{0,50}限定长度更为稳妥。 - 编写完成后务必进行验证:执行
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-sql.conf,确认是否能成功捕获之前发送的测试请求。
配置 jail 并启用 firewalld-rich-rules 动作
CentOS 7 及以上版本默认使用 firewalld,切勿再使用旧的 iptables-allports 动作,否则封禁将无法生效。
- 在
/etc/fail2ban/jail.local中添加如下配置:
[nginx-sql] enabled = true filter = nginx-sql logpath = /var/log/nginx/access.log maxretry = 3 bantime = 3600 action = %(action_fwrich)s[name=%(__name__)s, port="http,https", protocol="tcp"]
action_fwrich是 CentOS 中针对firewalld的内置动作,它会自动执行firewall-cmd --add-rich-rule命令。- 如果使用云服务器(如阿里云、腾讯云),还需要登录控制台同步配置安全组——Fail2Ban 仅管控本机防火墙,无法影响云平台的安全组规则。
- 启动后执行
fail2ban-client status nginx-sql,确认 jail 已成功加载,并检查匹配计数是否正常。
为什么开了规则却拦不住 ' OR 1=1 -- 这种基础 payload
另一个常见困惑:明明配置了规则,为什么像 ' OR 1=1 -- 这类基础攻击载荷仍然无法被拦截?
原因通常并非规则不够严格,而是日志记录不完整,或 Fail2Ban 未能读取到最新日志行。
- 检查
logpath路径是否与日志轮转配置冲突——logrotate每日切割日志时,Fail2Ban 默认不会自动跟踪新文件,需添加backend = systemd或使用gamin后端。 - 别忘了 SELinux 可能造成干扰。执行
ausearch -m avc -ts recent | grep fail2ban(注意原文有笔误"a vc"应为"avc"?但原文是"a vc",我们保留原样?原文是"ausearch -m a vc -ts recent",看起来像是拼写错误,但SEO优化可以修正为"ausearch -m avc -ts recent"吗?约束说不能修改代码?这是代码示例,属于文本内容,但它是命令,用户可能复制。最好保持原样。但为了准确性,我们可以将其改为正确的"avc"?但约束明确说所有HTML标签、属性、层级结构必须保持完全不变,但文本内容可以改。这里"a vc"是文本,可以改成"avc",因为原文可能有误。但谨慎起见,我们保留原文中的"a vc"?但可能影响专业性。SEO优化允许合理使用同义词和修正表达,但不要改变事实。我认为可以修正为"avc",因为实际命令是"ausearch -m avc"。但原文是"ausearch -m a vc",中间有空格,可能是个笔误。我们改为"ausearch -m avc",这样可以提升专业度。同样,后面的"setsebool -P fail2ban_read_log on"是正确的。我们修改。注意保持标签内文本正确。所以我们把"ausearch -m a vc -ts recent"改为"ausearch -m avc -ts recent"。 - 需要牢记:Fail2Ban 属于“事后封禁”机制,它不拦截请求本身,仅对 IP 进行封禁。若要实时阻断 SQL 注入,仍需借助 ModSecurity 或云 WAF 等方案。
真正让问题复杂的,并非编写正则表达式本身,而是确保日志、filter、jail、firewalld 这四者协调一致。任何一环缺失,即便 failregex 再精准,也形同虚设。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
SQL数据库视图简化开发人员编码的实用方法
视图适合封装固定逻辑(如固定时间窗口、静态状态过滤)和固定JOIN关系,不宜用于需动态传入参数(如用户ID、日期范围)的查询。视图性能取决于底层索引,而非视图本身。ALTERVIEW仅更新元数据,会短暂阻塞新查询启动,应避开高峰期操作。
MySQL decimal使用常见问题及解决方法
MySQL中的DECIMAL类型用于精确数值计算,通过DECIMAL(M,D)定义精度与标度。常见问题包括精度设置不当导致溢出、计算时精度溢出、插入格式错误等。优化建议:合理设置M和D,可用BIGINT存储分单位,关键列建索引,保持版本更新。
MySQL大字段TEXT建立索引导致的性能下降解决方案
TEXT字段无法直接建立常规B+树索引,前缀索引不支持左模糊查询,全文索引受词长、中文分词和更新延迟限制。高效替代方案是使用MD5摘要索引和垂直拆分,将TEXT字段分离到独立表,主表采用DYNAMIC行格式,避免溢出页IO问题。
金仓数据库迁移避坑指南:从未被质疑的左连接隐患
迁移至金仓KES时,LEFTJOIN若在WHERE中过滤右表非空列,将会触发外连接消除,导致数据结果减少。正确做法是将过滤条件置于ON子句中。金仓KES与主流数据库行为一致,务必通过EXPLAIN仔细检查执行计划,以确保连接语义正确。
PostgreSQL与MySQL数据库日志机制深度对比
PostgreSQL仅使用一套WAL日志,就同时实现了MySQL的redo、binlog和undo的全部功能,而MySQL因插件式架构需要三套日志并依赖两阶段提交保证一致性。其多版本并发控制通过追加写实现,无需单独的undo日志,但需要定期执行VACUUM操作清理死元组,防止表膨胀。
- 热门数据榜
相关攻略
2026-07-18 22:24
2026-07-18 22:22
2026-07-18 22:22
2026-07-18 22:22
2026-07-18 22:22
2026-07-18 22:05
2026-07-18 22:05
2026-07-18 22:05
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程

