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

可以使用 rsyslog 的 property replacer 配合 substring 操作,对 `$msg`(或其它字段)进行截断,从而避免完整日志中暴露过长的 Token 字符串。关键在于定位 Token 出现位置并控制输出长度,而非简单粗暴地截前 N 位。
明确要截取的目标字段和 Token 特征
rsyslog 默认处理的是整条原始报文(`$msg`),但 Token 往往嵌在特定字段里,比如 JSON 日志中的 "token":"abc123...xyz"。直接对 `$msg` 截取容易误伤正常内容。建议先用 json 模块解析日志,再针对 `$.token` 或 `$.authorization` 等字段操作:
- 若日志是标准 JSON,启用
module(load="imjson")并用json.parse="on" - 若无法解析 JSON,可用
re_extract提取 Token 值(如匹配token[[:space:]]*:[[:space:]]*["']([^"']+)["']) - 确认 Token 最大合理长度(如 JWT 通常 ≥ 200 字符,API Key 可能为 32~64 位),设定安全截断点(例如只保留前 8 位 + "...")
使用 substring property replacer 实现可控截断
rsyslog 支持 %field:2:8% 这类语法:从第 2 个字符开始取 8 个字符。但 Token 位置不固定,需结合变量提取。典型做法是:
- 先用
set $!tok = $.token;获取 Token 字符串(JSON 解析后) - 再用
%$!tok:0:8%截取前 8 位;若需带省略号,写成%$!tok:0:8%... - 若想动态控制(如最长显示 12 位),可配合
if $!tok != "" then判断后再赋值 - 注意:substring 起始索引从 0 开始,长度为正整数;超出长度则自动截到末尾,不会报错
在模板中组合脱敏后的字段输出
定义一个新模板,把处理后的 Token 嵌入格式化日志中,避免原始 `$msg` 直接落地:
- 示例模板:
template(name="SecureLog" type="string" string="%timestamp% %hostname% %syslogtag% token=%$!tok:0:8%... %msg%\n") - 在 rule 中调用:
*.* action(type="omfile" file="/var/log/secure.log" template="SecureLog") - 确保该模板仅用于敏感日志路径,普通日志仍走原始模板,避免影响排查
- 测试时用
logger '{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"}'验证是否只输出token=eyJhbGci...
补充防护:配合 drop 或 filter 避免原始日志泄露
仅修改输出模板不能阻止原始 `$msg` 被写入其他文件或转发出去。必须同步清理源头:
- 在写入本地文件前,用
if $msg contains "token" then stop阻断原始含 Token 的日志落盘 - 或用
if $!tok != "" then set $msg = replace($msg, $!tok, "%$!tok:0:8%...");替换原始消息体内的 Token - 对外转发(如发给 Elasticsearch)务必使用脱敏后模板,且禁用原始 `$msg` 字段透传
- 定期检查 rsyslog 配置中是否有未加保护的
*.* /var/log/messages类泛写规则











