翻开一份 error.log,报错信息里夹着明文手机号、姓名、收货地址,一串一串排得整整齐齐,这种事我一年能碰上好几回。做日志脱敏四要素,第一个是划范围,大家基本都记得;第四个是验证,好歹有人会提;中间那条最不起眼,也最容易被略过去。

做扎实的没几个。
日志脱敏四要素里,被跳过最多的那条
我把它拆成四件事:先把哪些字段算敏感划出来;脱敏之后日志之间还得能串起来;手法跟场景对上;做完有人验、有人留档。四件里三件是加法,只有第二条是减法,手一抖就删过头了嘛。
第2个要素:留下能串起来的那根线
我见过最典型的一种做法,是把 user_id、request_id、订单号一起抹成星号,觉得这样最安全,结果线上确实出了个支付回调的问题,查日志的时候满屏都是 ****,连是哪个用户触发的都对不上,只能去翻数据库的 binlog 一点点往回推。
线一断,就找不回来。
该留的线索其实不多:trace_id 或 request_id、时间戳、接口路径、状态码、耗时。这几样都不带身份,但能把一次调用从头到尾串起来。身份字段换成稳定的假名就好,user_id 走一遍 HMAC,盐放配置或者密钥管理里,别让它跟着日志一起被拖走。同一套盐下算出来的值是一致的,统计照样能做,只是人对不上号而已。
你会发现脱敏后的日志还能不能算 PV、能不能统计接口耗时,这个问题挺关键。能,只要那根线还在。反过来,你把 trace_id 也抹了,监控大盘上的错误率就成了一堆对不上号的孤岛,报警响起来你都不知道是谁在报,那还查什么呢。
范围先划清,别见字段就糊
手机号、身份证、银行卡、密码、各种 token 和 cookie、Authorization 头、数据库连接串、内网 IP,这些都算。但也别见字段就糊,URL 里 query 带的搜索词、商品 ID、页码,糊掉之后日志基本就废了,排查个参数问题全靠猜。我一般先拿一份真实日志出来从头读到尾,把字段列成表,一个个标「留、掩、删」,标完再动手。
范围划大,日志就废。
掩码、哈希、置空,用错场景等于白干
掩码这东西是给人眼看的,138****8888 这种,客服核对的时候用得上。前三位后四位就够了,别留太全。哈希呢,是给统计和关联用的,得加盐。手机号这种字段取值范围本来就小,不加盐直接 sha256 等于没脱——拿张号码表跑一遍,几分钟就撞出来。要么加个固定盐,别往日志里写;要么干脆上不可逆的令牌化方案。
盐得放在配置里。
置空对应的是完全用不上的字段,比如整个请求体。可逆加密往日志里塞,最坑。密钥就在同一台机器上,谁拿到日志谁就能解。绕一圈又回到明文,不然就是自欺欺人。说白了,手法本身没高低,跟场景对不上就是白干。老实说,我宁愿多花点时间做令牌化,也不想在日志里留一把能解开的锁。
nginx 和 filebeat 这一层怎么落地
nginx 的 access.log 默认把整个 URL 打出来,回调接口里带 token 的那种最危险,直接落盘。改法有两种:在 log_format 里少打点东西,只留必要变量;或者在 filebeat、logstash 那一层用正则替换,把敏感参数换成占位符。我一般走第二种,采集端改一行配置,扩缩容都不用动应用代码,出问题也容易回滚,代价是多一跳处理,日志延迟会稍微高一点。
脱敏之后谁来验
改完规则不等于上线了。抽几十行出来看,用手机号、身份证、邮箱的正则各 grep 一遍,看还有没有命中的。规则本身得有版本号,谁改的、哪天改的,记在一个地方就好。原始日志的读权限单独管,别跟生产库一个权限,不然前面脱了个寂寞。备份文件里那些老日志也得过一遍,很多人只处理新写入的,历史归档一直是明文,安安静静躺在对象存储里呗。
这条我吃过亏。
几个绕不开的坑
开发环境直接从生产拷一份日志来调试,是最常见的一条。日志轮转之前的旧文件忘了处理,也是啊。还有个更隐蔽的:脱敏只做了应用层的 error.log,nginx 的 access.log 原封不动,两下一对比等于没脱。监控和告警系统里贴的原始报文也得算在范围内,别只盯着日志文件看,工单截图里那一小段日志同样能泄露。
下次往代码里加一行日志之前,先问自己一句:这东西打出来,会不会给以后的自己添麻烦。会的话现在就改,别等出了事再回头翻。
【版权声明】:本站内容若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!