日志里写不写对端 IP:logips 的拼接式脱敏与它管不到的地方 图 1
日志里写不写对端 IP:logips 的拼接式脱敏与它管不到的地方 · 图 1

节点日志里到底写没写你的 IP?这个问题问得不准确,准确的问题是:日志里写了别人的什么、有没有写你自己的。比特币核心在 v31.0 里给出的默认答案是”不写 IP”,由一个名为 -logips 的开关控制,默认关闭。它是日志系统里唯一的身份脱敏开关,因此也成了隐私自查清单上的一项,但它既不是总开关,也不能单独撑起”日志安全”这个结论。本文按 v31.0 源码拆解它的实现方式、覆盖面和管不到的地方。

实现方式:全局布尔,不是过滤器

v31.0 源码里,logging.h 定义默认常量 DEFAULT_LOGIPS = falseinit/common.cpp 在初始化时把配置值读进全局变量 fLogIPs。它的工作机制不是”写日志时把 IP 抹掉”,而是”根本不组装那段文字”:网络层的辅助函数 DisconnectMsg 输出”disconnecting peer=7”,只有当传入的 log_ip 为真时才追加”peeraddr=203.0.113.5”这样的字段。换句话说,被关掉的是拼接,不是脱敏——日志里不留被遮罩的痕迹,也留不下反推的线索。

这种设计的含义值得点明:开关不改变日志量语义,只改变内容。开与关之间,peer 编号、连接类型、断连原因都在,缺的只是地址列。

日志里写不写对端 IP:logips 的拼接式脱敏与它管不到的地方 图 2
日志里写不写对端 IP:logips 的拼接式脱敏与它管不到的地方 · 图 2

什么时候需要打开它

关闭 IP 是默认,也是最保守的选择,但排障阶段常常需要地址。典型场景有三类:一是怀疑与某个 ASN 的连接质量异常,需要把断连记录按地址聚合;二是自建节点怀疑被人反复扫描,想统计入站来源;三是与运维同事联合排查时,peer 编号无法跨节点对齐,地址才能对齐。此时临时打开 -logips,配合 -debug=net 或运行时 logging net=1,观察一段时间后再关闭,是一条成本可控的路径。

需要区分:-logips-debug 家族是正交的。-debug=net 控制”网络类日志写不写”,-logips 控制”写的时候带不带地址”。只开前者不开后者,你会得到大量没有地址的网络事件;只开后者不开前者,网络类日志本身可能压根没在输出。

它管不到的清单

这是最容易高估的地方。日志里泄露身份的渠道远不止 IP 一列:入站连接的计数与频率本身就是行为指纹;你的用户代理字符串(版本信息)逐条连接都在广播;debug.log 里钱包类日志会带交易编号,而交易编号在浏览器里可以顺藤摸瓜。-logips 对这些一概不管。同样地,它也不处理网络传输路径上明文 V1 握手阶段的地址可见性——那是网络层的事,日志开关无法伸手到网线。

还有一条实践红线:日志文件的权限与保留策略。调试期开着 logips 生成了带地址的 debug.log,事件结束后只把开关关掉,旧文件里的地址仍在磁盘上,备份、日志采集、故障压缩包都可能把它继续扩散。完整动作应是”关开关 + 清理或轮转历史日志”。

自查三步

第一步,检查配置:grep -i logips ~/.bitcoin/bitcoin.confsettings.json,确认没有历史遗留的开。第二步,抽样文件:在 debug.log 里搜点分十进制与冒号十六进制模式,看当前是否真的无地址。第三步,检查轮转:debug.log 是否定期截断或轮转,旧归档留在何处、权限几何。三步都干净,才算完成一次”日志身份卫生”自查。

最后校正一个常见误解:-logips 关着不代表”日志里查不到坏人”。peer 编号在同一进程生命周期内稳定,配合入站事件的时间序列表仍能定位行为;需要精确封禁时,用运行时日志开关临时打开、处理完立刻关掉,才是隐私与可运维性的合理平衡点。

一个折中的替代路线

很多”想看地址”的需求其实不必打开服务器端日志。运行时用 logging 命令临时点亮 net 类别、配合 -netinfo 的地址列或 getpeerinfo 的 address 字段,同样能定位问题,而且这些信息只存在于当次会话的返回值里,不落盘。把”临时查询”与”长期记录”分开对待,logips 就只在真正的取证场景出场——比如你需要还原几小时前的断连序列,内存态早已消失,只有日志里的历史可查。这个分层思路比”永远不开”或”一直开着”都更接近工程实践的真实形态。

风险提示:本文为日志与隐私参数机制说明,对应 Bitcoin Core v31.0 源码;日志内容可能包含可关联信息,公开分享日志前请先自查脱敏;不构成投资建议。