日志敏感信息处理应遵循“先识别、再脱敏、后留存”的基本原则,先精准识别手机号、身份证号、邮箱、密码、token 等敏感字段,再使用 sed、awk、jq 等工具进行掩码处理而不是直接删除,最后再按实际业务场景分级归档或清理日志数据。

在日志分析过程中,过滤和清理敏感隐私信息的核心仍然是“先识别、再脱敏、后留存”,不能简单粗暴地删除整行内容,否则容易破坏日志上下文、排障线索以及审计追踪能力。真正有效的方法是精准定位敏感字段,采用安全替换、字符掩码等方式处理,同时保留时间戳、请求动作、操作类型等必要审计信息。
识别常见敏感字段类型
不同类型的日志格式中,敏感信息通常具有较明显的固定模式,实际处理时应结合正则表达式与字段位置进行判断和过滤:
- 身份类:手机号(1[3-9]d{9})、身份证号(d{17}[dXx])、邮箱([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,})
- 凭证类:密码参数(password=([^&s]*)、token=[^&s]*)、API 密钥(sk_live_[a-zA-Z0-9]{32})
- 路径与数据:包含用户 ID 的 URL 路径(/api/users/(d+)/profile)、数据库连接串(jdbc:mysql://[^"]*)
- 环境信息:内网 IP(10.d+.d+.d+|172.(1[6-9]|2[0-9]|3[0-1]).d+.d+|192.168.d+.d+)、主机名(hostname=([^&s]*))
用sed和awk做实时脱敏处理
处理日志敏感信息时,建议不要直接修改原始日志文件,而是生成脱敏副本,或在日志管道中实时完成过滤与脱敏:
- 替换密码参数:
sed 's/password=[^&]*/password=***/g' access.log - 掩码手机号(保留前 3 后 4):
sed -E 's/1[3-9][0-9]{2}([0-9]{4})([0-9]{4})/112/g' app.log | sed 's/([0-9]{4})([0-9]{4})/1****/' - 提取并脱敏 Nginx 日志中的 IP 和请求参数:
awk '{gsub(/password=[^&]*/, "password=***", $7); print $1, $7}' nginx.log - 对 JSON 日志中的敏感字段脱敏(需 jq 支持):
jq 'del(.user.token, .db.password) | .user.phone |= sub("(\d{3})\d{4}(\d{4})"; "\1****\2")' api.log
清理策略要分场景执行
日志“清理”并不等于全部删除,而应根据安全规范、合规要求和日志用途进行分级处理:
- 生产环境日志:禁用
rm或truncate直接清空,建议使用logrotate配置自动归档与压缩,并设置maxage 90实现自动过期 - 调试日志临时文件:在确认没有审计需求后,可使用
find /tmp -name "*debug*.log" -mtime +7 -delete定期清理 - 含PII的测试日志:可使用
grep -v筛选不含敏感词的日志行后保存,或通过awk '!/password|token|id_card/ {print}' test.log > clean.log生成清洁日志 - 审计日志(如/var/log/secure):原则上禁止删除,只允许使用
auditctl -e 0临时停止记录,并在操作结束后立即恢复
自动化脚本示例(安全脱敏+归档)
下面的脚本示例会将日志中的手机号、邮箱、密码参数统一进行掩码处理,并在完成后压缩归档,适合做批量日志脱敏与清理:
#!/bin/bash
LOG_FILE="/var/log/app/error.log"
MASKED_FILE="${LOG_FILE}.masked.$(date +%Y%m%d)"
gzip_file="${MASKED_FILE}.gz"
脱敏并写入新文件
sed -E \
-e 's/1[3-9][0-9]{9}/1*5678/g' \
-e 's/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/user@domain.com/g' \
-e 's/(password|token|key)=([^&n]+)/1=/g' \
"$LOG_FILE" > "$MASKED_FILE"
压缩并清理原文件(仅当确认无需原始日志时)
gzip "$MASKED_FILE"
rm "$LOG_FILE"
