用公共节点或小型服务商的 RPC 给监控系统接线时,很多人默认”账号口令对了就能调所有命令”。比特币核心其实留了一套按用户划分的方法白名单:-rpcwhitelist 与它的搭档 -rpcwhitelistdefault。多数运维教程只提第一个开关,而真正决定”没写白名单的用户能干什么”的是第二个——这个配对语义弄反,轻则监控全瞎,重则把一个只读账号变成全权账号。本文按 v31.0 源码 httprpc.cpp 的实际分支逻辑拆解。
两条配置线,一台服务器
-rpcwhitelist=<用户>:<方法1>,<方法2>,… 为指定用户登记一份方法集合,可以重复书写;同一用户给多条时,源码取的是集合交集——越写越窄,不会越写越宽。第二个开关 -rpcwhitelistdefault 的默认值有个不显眼的设计:它默认等于”是否配置过任何 rpcwhitelist”。也就是说,只要你写了至少一条白名单,系统就自动进入”其余用户一律空表”的模式;一条都不写时,它等于关,所有人都全权限。
这个默认联动能防止一类经典事故:只给部分用户加白名单,却以为没加的用户保持原样。源码行为恰恰相反,没登记的默认被拒。想恢复”未登记用户全权限”,必须显式 -rpcwhitelistdefault=0。

请求进来时的判定顺序
httprpc.cpp 的处理路径值得完整走一遍。收到请求先问:当前认证用户有没有登记过白名单?没登记,且 default 为开,直接回 HTTP 403,日志记一句 “RPC User … not allowed to call any methods”;登记过,则查方法名在不在集合里,不在同样 403,日志写明哪个方法被拒。批量请求(JSON 数组)逐个解析每个 method 逐一判权限,任何一条越权整批拒绝。
被拒的响应是 HTTP 层的 403,不是 JSON-RPC 的错误对象——排查时看到 403 就该想到白名单,而不是命令语法或节点状态。这一层检查发生在认证之后、执行之前,白名单挡不住窃取了合法凭据的攻击者,它防的是权限误配与低权限账号被滥用后的爆炸半径。
与 RPC 权限的三层关系
比特币核心对一次 RPC 调用的关卡大致是:网络可达(rpcbind、rpcallowip 或本机 cookie)、认证通过(口令或 cookie)、方法许可(whitelist)。三层各自独立,白名单只补第三层。给监控账号发”只能看”的凭据时,标准配方是:单独用户名、-rpcwhitelist=monitor:getblockchaininfo,getnetworkinfo,getmempoolinfo,getrawmempool,并复核 -rpcwhitelistdefault 的实际生效值。
需要特别小心的反例是”为了方便先不开 default”:在 default 关的模式里,写错的白名单只保护登记过的用户,其他用户照旧全权,白名单形同虚设。上线前用低权限账号亲手试一次 stop 或 importprivkey,期待 403,这一步验证比读十遍文档可靠。
一个可复用的最小配方
给”只读监控”发放凭据时,一套保守的写法是把方法集收窄到四五个:getblockchaininfo、getnetworkinfo、getmempoolinfo、getrawmempool,再加告警需要用的 getrpcinfo。同时为管理员保留独立用户,两个账号分端口不如分方法:同一 8332 端口、不同用户名、不同白名单。若监控系统偶尔要查钱包,不要为它打开整类钱包方法,而是单独给它 getwalletinfo 一项,出现缺口时按最小增量补录。变更走评审、上线做负向测试、日志定期看异常拒绝行,三件事坚持半年,权限漂移的病灶基本能被按住。
审计与遗留问题
日志里的 “not allowed to call method” 是现成的审计线索,出现频率异常说明有脚本在用错误的身份跑命令。另一个习惯问题:白名单方法名要跟随版本演进维护——某方法在新版本被拆分或改名(历史上不少命令有废弃路径),旧名单会让升级后的监控静默断供。把白名单当作代码纳入变更评审,比当配置文件里的死文本安全得多。
最后提醒部署边界:多用户 RPC 常见于共享节点,而跨可信域暴露 RPC 本身就需要另一番评估;白名单是”同一信任域内分权”的工具,不是把 RPC 暴露到公网的理由。
风险提示:本文为 RPC 访问控制参数说明,对应 Bitcoin Core v31.0 源码;权限配置错误可能导致服务不可用或权限过宽,变更请在预发环境验证;不构成投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。