-upnp 退场,-natpmp 接棒:比特币核心端口自动映射的换代账本 图 1
-upnp 退场,-natpmp 接棒:比特币核心端口自动映射的换代账本 · 图 1

家用路由器后面的比特币节点想被外面连上,传统做法是自动端口映射。三年前这条路的招牌还是 UPnP;到了比特币核心 v30,配置文件里写 -upnp=1 已经会直接报错——这个参数被彻底删除,接班的是 -natpmp。这场换代是怎么走完的,两个协议有什么不同,本文按发布说明与 v31.0 源码记一本明白账。

三步走完的退场

v29.0 发布说明:UPnP 支持被放弃,想自动开口的用户改用 -natpmp 选项,节点会按路由器支持情况走 PCP 或 NAT-PMP;同版把外部库 libnatpmp 换成了内建的 PCP 与 NAT-PMP 实现,顺带把支持范围从 IPv4 端口转发扩展到 IPv6 的端口针孔;MiniUPnPc 与 libnatpmp 两个构建依赖一并移除。同一版还留了一个兼容台阶:设置 -upnp 会打一条警告并被翻译解释成 -natpmp。v30.0 收尾:-upnp 被完全删除,同时 -natpmp 改为默认开启——带 -listen(默认即开)的节点,只要家用的路由器或防火墙支持 PCP 或 NAT-PMP,就会尝试自动取得可达性。v31.0 源码里内建实现的默认常量仍是开。

值得注意的是,发布说明对放弃 UPnP 只用了”dropped”一词,没有附原因说明;用户在社区讨论里常引用的担忧——UPnP 在局域网内面向任何设备开放的暴露面与实现安全史——属于背景信息,写文章、做决策时可以参考,但不要把”官方说明了安全原因”当成事实引用。

-upnp 退场,-natpmp 接棒:比特币核心端口自动映射的换代账本 图 2
-upnp 退场,-natpmp 接棒:比特币核心端口自动映射的换代账本 · 图 2

PCP 与 NAT-PMP 是什么

NAT-PMP 定义于 IETF 的 RFC 6886,源自早年的端口映射需求,只处理 IPv4 的地址映射请求;PCP 定义于 RFC 6887,在同一类交互上扩展了对 IPv6 的支持,并引入更明确的生存期管理。比特币核心 v29 起的内建实现同时讲这两种协议:路由器认哪种就用哪种,不认就什么都不做。与 UPnP 相比,两者都不做设备发现广播那一套,交互对象是路由器单点,请求面明显更窄。

自动映射不是你想开就开:三处联动

v31.0 源码的启动逻辑里,有两处会把 -natpmp 静默压回关闭:设了 -proxy 时,节点认为出站都走代理、映射无意义,日志会打出一行 parameter interaction 说明它替你改了参数;-listen=0 时同样联动关闭。也就是说,“我配了 natpmp 怎么没见端口开”的第三种答案可能是你同时配了代理。另一处与端口有关的联动来自 v29:设置 -port 后,洋葱监听端口不再钉死主网默认值,而是按该端口加一推导,做双节点错端口时可以少配一项。

家用节点的四步验收

第一步,确认发行版:v30 起 -natpmp 默认一,配置文件里没写它反而是关不掉的——真想关要显式 -natpmp=0。第二步,查路由器:翻网关管理界面找 PCP/NAT-PMP 支持情况,两者都不支持的路由器上,节点不会有任何自动映射,只剩 UPnP 端口转发或手动规则这两条老路。第三步,看日志:映射成功或失败都会在启动阶段留记录,排查先看这里。第四步,外部验证:用另一台网络里的节点直连你的公网地址加端口,或者做可达性自检流程——日志说成功不等于外网通,这中间的落差正是路由器兼容性最常藏身的地方。

还有一类用户不该错过这条时间线:把 -upnp=1 写死在配置模板、镜像或部署脚本里的老运维。v29 与 v30 之间有两个版本窗口,第一个窗口只会警告,第二个窗口直接启动失败——升级 bitcoind 时报”无法识别的参数”的节点,先翻配置文件再翻网络拓扑,多半一行就治好。迁移顺手做:把参数换成 -natpmp,重启后到路由器管理页确认映射条目出现,比留着一条永远不会生效的旧开关体面得多。

风险提示:本文依据比特币核心 v29、v30 发布说明与 v31.0 源码整理,协议支持与默认值可能随版本调整,路由器行为则以你的设备实测为准。内容为技术说明,不构成任何投资建议。