ngx_http_sub_module通过字节流替换实现代理响应体敏感词过滤,不改后端、不解析HTML,适用于轻量脱敏;需启用模块、显式声明sub_filter_types、禁用gzip或启用gunzip,并注意sub_filter_once和执行顺序。
用
在网关层做静态源码的敏感词过滤,核心是“代理响应体中做字节流替换”,不改后端、不解析 HTML 结构,适合轻量脱敏和品牌统一。但必须注意它的能力边界——它不是正则引擎,也不解压缩,配置错一步就完全失效。
确认模块已启用并匹配响应类型
先验证 Nginx 是否带该模块:
运行
,有输出才表示编译时启用了
若无,需重新编译,加参数
默认只处理
响应,静态资源如
、
、
必须显式声明 MIME 类型:
sub_filter_types text/html text/plain application/json text/css application/javascript;
配置替换规则与执行逻辑
替换行为由三条关键指令控制:
:精确字符串匹配,区分大小写,不支持正则
:默认只换第一个匹配项,设为
才能全局替换(比如页面中出现 5 次“张三”,全掩掉)
多条
按书写顺序执行,建议长词、高频词优先,避免被短词截断(例如先替“张三丰”,再替“张三”,否则后者会干扰前者)
绕过 gzip 和编码陷阱
这是最常踩的坑:上游返回
时,
完全不生效。
方案一(推荐):让后端关闭 gzip,尤其对 HTML/JS/CSS 这类文本资源
方案二:Nginx 启用解压,需确认已编译
,并在 location 中加:
gunzip on;
注意:
仅对带
头的响应起作用,且会增加 CPU 开销;不建议对大文件或高并发接口启用。
结合 proxy_pass 实现网关级注入
典型场景:前端静态资源托管在对象存储或 CDN,通过 Nginx 反向代理统一出口,在此层过滤测试环境标识、内部域名、手机号等:
屏蔽测试水印:
替换内网地址:
简单手机号脱敏(假设原始格式为纯数字):
务必确保这些规则放在
同一 location 块内,且
覆盖对应资源类型(如 JS 文件要含
)。
ngx_http_sub_modulenginx -V 2>&1 | grep -o with-http_sub_module--with-http_sub_modulesub_filtertext/html.js.css.jsonsub_filter "张三" "***"sub_filter_once offoffsub_filterContent-Encoding: gzipsub_filterngx_http_gunzip_modulegunzip ongzipsub_filter 'TEST' '';sub_filter 'http://dev-api.internal/' 'https://api.example.com/';sub_filter '13812345678' '138****5678';proxy_passsub_filter_typesapplication/javascript