最可靠的方式是在rsyslog接收日志第一时间用rainerscript脱敏,需v8.33+支持re_replace(),配置中先if定位日志,再set $!clean_msg=re_replace($msg,正则,'*'),最后set $msg=$!clean_msg覆盖原字段。

直接在 rsyslog 接收日志的第一时间做字段脱敏,是最可靠的方式——它不依赖应用层逻辑,能覆盖异常分支、调试输出、旧版本残留等所有可能泄露敏感信息的路径。
确认 rsyslog 版本支持 set + re_replace()
脱敏能力依赖 rsyslog v8.33 及以上版本。运行以下命令检查:
rsyslogd -v
若版本低于 8.33,需升级(如 CentOS 7 默认为 8.24,建议用 EPEL 或源码编译安装新版)。旧版仅支持简单字符串替换(如 $template 中的 %msg%),无法正则擦除 token、手机号、身份证号等动态内容。
在规则前用 RainerScript 做字段清洗
脱敏必须放在日志写入磁盘前,且在条件判断之后、动作执行之前。典型配置结构如下:
- 启用
imuxsock和imklog等输入模块 - 定义 ruleset(可选,用于隔离处理逻辑)
- 在 ruleset 内使用
if $programname == 'nginx' then { ... }或if $msg contains 'token=' then { ... }定位目标日志 - 用
set $!clean_msg = re_replace($msg, 'token=[^&\s]+', 'token=***');擦除 URL 中的 token 参数 - 再用
set $msg = $!clean_msg;覆盖原始消息字段
注意:$!clean_msg 是自定义变量(以 $! 开头),re_replace() 第二个参数是 PCRE 正则,第三个是替换内容。支持多级嵌套,例如同时处理 id_card= 和 phone=。
绑定脱敏后的消息到模板并落盘
脱敏完成后,消息体已更新,后续只需按常规方式写入文件。例如:
- 定义一个精简模板:
template(name="SanitizedLog" type="list") { property(name="timestamp" dateFormat="rfc3339") constant(value=" ") property(name="hostname") constant(value=" ") property(name="msg") constant(value=" ") } - 在规则中调用:
*.* action(type="omfile" file="/var/log/sanitized/app.log" template="SanitizedLog")
不要在模板里再对 msg 做二次处理——脱敏必须在进入模板前完成,否则正则替换无法生效。
验证与性能注意事项
脱敏逻辑上线前务必测试:
- 用
logger "GET /api/user?token=abc123&id=789"发送测试日志 - 检查
/var/log/sanitized/app.log是否显示为GET /api/user?token=***&id=789 - 观察
journalctl -u rsyslog是否有re_replace: invalid regex报错
单条日志脱敏耗时在微秒级,对吞吐影响极小。但避免在高频日志(如 access_log 每秒万级)上启用复杂正则回溯,建议用非贪婪匹配和锚点(如 token=[^&\s]{8,64})提升效率。











