
核心要点(TL;DR)
- 文件监控胜在部署快、成本低,但存在轮询与事件丢失盲区。
- 内核拦截能在写入落盘前阻断,防篡改强度更高但依赖内核与策略调优。
- Nginx静态目录适合内核拦截,Tomcat热部署目录建议白名单加文件监控。
- 选型先定RTO与误报容忍度,再用检查清单做小范围灰度验证。
网页被挂马、首页被替换、JS 被注入挖矿脚本,这类事故的共同点是:攻击者拿到写权限后,几分钟内就能改完文件,而运维往往几小时后才从用户投诉里发现。要解决这个问题,核心不是「事后比对」,而是选对防篡改的技术路线。本文面向要动手落地的运维与站长,把 Nginx 与 Tomcat 场景下的两类主流方案——文件监控与内核拦截——拆开对比,并给出可直接执行的命令与检查清单。
两类方案到底在拦什么
文件监控基于 inotify/fanotify 监听文件事件,写入发生后触发告警或自动还原,属于「事后秒级发现」。内核拦截则通过 LSM(如 AppArmor、SELinux)或只读挂载,在 write/open 系统调用阶段直接拒绝,属于「写入前阻断」。
| 维度 | 文件监控 | 内核拦截 |
|---|---|---|
| 拦截时机 | 写入落盘后 | 写入落盘前 |
| 部署成本 | 低,装 agent 即可 | 中,需内核支持与策略调优 |
| 误报风险 | 较高(热部署、日志轮转) | 较低但配置错误会阻断业务 |
| 适用目录 | 高频变更目录 | 静态资源、发布后目录 |
Nginx 场景:静态目录优先内核拦截
Nginx 的 html 目录写入频率极低,是最适合内核拦截的对象。最直接的做法是只读挂载或 LSM 路径规则:
# 检查当前挂载
findmnt -T /usr/share/nginx/html
# 以只读方式重新挂载(示例,按实际分区调整)
mount -o remount,ro /usr/share/nginx/html
# 验证
sudo -u nginx touch /usr/share/nginx/html/test.html
# 预期:Permission denied 或 Read-only file system若目录需保留可写(如上传目录),改用 AppArmor 对 nginx worker 做路径级限制,只允许写 upload 子目录。配置后务必执行 apparmor_parser -r 重载,并用 aa-status 确认规则处于 enforce 模式。文件监控在此处作为兜底,记录被拒绝的写入尝试与进程名,便于溯源。
Tomcat 场景:热部署目录用监控加白名单
Tomcat 的 webapps 会因 war 解压、热部署产生大量短时写入,纯内核拦截容易误伤发布流程。推荐组合:对已发布应用目录做文件监控,发布窗口临时放行。
- 调大监听上限:
sysctl -w fs.inotify.max_user_watches=524288,写入 /etc/sysctl.conf 持久化。 - 监控命令示例:
inotifywait -mrq -e modify,create,delete,move --format '%w%f %e' /opt/tomcat/webapps/app。 - 排除 work、temp、*.tmp、*.log,避免日志轮转刷屏。
- 发布时先解除保护,解压完成后重新加锁,并触发一次全量哈希校验补齐事件丢失。
对确实不允许任何写入的核心配置(如 server.xml、context.xml),再叠加内核级只读策略,形成「核心拦截 + 外围监控」的分层结构。
落地检查清单
- 是否明确受保护路径清单,并区分静态目录与可写目录?
- 是否做过写入验证:普通账号、root 账号各测一次?
- 告警是否带进程名、PID、路径与时间,能否直接溯源?
- 是否有发布窗口放行机制,避免误伤业务?
- 是否配置全量哈希基线,定期比对补齐事件盲区?
行动建议
先用一天时间做小范围灰度:选一个 Nginx 静态站点做只读挂载验证,选一个 Tomcat 应用做 inotify 监控加白名单,观察一周误报与性能基线。确认稳定后再全量推广。若希望减少自建 agent 与策略调优的投入,可评估 AegisX 的网页防篡改能力,其同时提供文件完整性基线与写入拦截策略,便于在 Nginx、Tomcat 混合环境中统一落地。
常见问题(FAQ)
Nginx的html目录用文件监控还是内核拦截更合适?
优先内核拦截。Nginx静态资源目录写入频率低、文件数量可控,用fanotify或LSM规则对目录做只读挂载式保护,能在write系统调用阶段直接拒绝,篡改不会落盘。文件监控可作为兜底审计,记录尝试写入的进程与路径,便于溯源。
Tomcat的webapps目录频繁热部署,防篡改会不会大量误报?
会。Tomcat解压war包会短时间产生大量写入,纯文件监控容易刷屏。建议对webapps按应用目录做白名单,只监控已发布目录并排除*.tmp、work目录;内核拦截则对部署窗口临时放行,部署完成后重新锁定,避免影响正常发布。
inotify监控大量文件时提示上限不足怎么办?
先调大内核参数:sysctl -w fs.inotify.max_user_watches=524288,并写入/etc/sysctl.conf持久化。若目录层级深、文件超百万,建议改用fanotify按挂载点监控,减少watch数量,同时配合定期全量哈希校验补齐事件丢失。
内核拦截方案会不会影响Nginx和Tomcat性能?
影响可控。基于LSM的路径级规则只在命中受保护路径时介入,常规读写走原有路径,压测QPS下降通常在个位数百分比。建议上线前用ab或wrk对静态页与接口做基线对比,并观察系统调用延迟,确认无异常后再全量。
如何验证防篡改规则真的生效了?
做三步验证:一是用普通账号echo测试写入受保护文件,应返回Permission denied;二是用root模拟篡改,确认拦截或告警触发;三是查看审计日志是否记录进程名、PID与路径。三步都通过才算规则生效,并纳入日常巡检。