副本集节点间通信必须放行内网端口27017,但严禁外网访问;需三层收敛防护:云平台白名单、bindIp严格限定成员IP+127.0.0.1、系统防火墙仅放行对应内网段。

副本集节点间通信必须放行,但外网访问必须阻断
副本集不是单机部署,各节点(primary、secondary、arbiter)需持续交换心跳、oplog 和配置变更。若防火墙粗暴屏蔽 27017 端口,会导致 replSetGetStatus 显示 HEALTHY: false、stateStr: "STARTUP2" 或反复 RECOVERING —— 这不是 MongoDB 故障,是网络策略误伤。
但同一端口若对公网开放,攻击者可直接发起:mongodump 扫描、未授权 db.runCommand({listDatabases:1})、或利用 CVE-2025-14847(MongoBleed)发送畸形 zlib 包读取堆内存。2026 年初监测显示,暴露在公网的副本集实例中,92% 的入侵始于未设白名单的 27017 端口。
- 仅允许内网 IP 段(如
10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)访问 27017 端口 - 禁止
0.0.0.0/0或空白名单配置(云厂商控制台里填这个等于贴告示“请黑我”) - 若使用云服务(阿里云、MongoDB Atlas),白名单需分别配置在云防火墙 + MongoDB 自身
net.bindIp两层
bindIp 配置错误会导致副本集脑裂或拒绝连接
net.bindIp 不是“白名单”,而是绑定监听地址。设错会直接让节点失联:比如在副本集配置里只写 127.0.0.1,节点就只能收本机请求,其他成员发来的心跳全被丢弃;若写成 0.0.0.0 又等于把数据库裸奔在公网。
正确做法是显式列出所有合法通信地址:
- 本地回环必须保留:
127.0.0.1(用于本地管理命令和监控) - 每个节点的真实内网 IP 必须全部列出,例如:
10.20.30.10,10.20.30.11,10.20.30.12 - 不能用 CIDR 简写(
10.20.30.0/24在bindIp中无效,只会导致 mongod 启动失败) - 修改后必须重启
mongod,且逐个节点验证rs.status().members[n].health是否为1
UFW / iptables 规则顺序决定防护是否生效
Linux 防火墙规则按顺序匹配,一旦命中就停止检查。如果先加了 ufw allow 27017(允许所有 IP),再加 ufw allow from 10.20.30.0/24 to any port 27017,后者永远不生效 —— 因为流量早在第一条就放行了。
实操要点:
- 先删除宽松规则:
sudo ufw delete allow 27017 - 再精确放行:
sudo ufw allow from 10.20.30.0/24 to any port 27017 proto tcp - 最后确认默认策略是 deny:
sudo ufw default deny incoming - 验证时用另一台不在白名单内的机器执行:
nc -zv your-mongo-ip 27017,应返回Connection refused
云环境白名单常被忽略的两个盲区
在阿里云、腾讯云或 MongoDB Atlas 上配置副本集,容易只改控制台白名单,却忘了底层节点自身的 bindIp 和系统防火墙。结果就是:云防火墙拦住了外网,但内网某台测试机仍能连上 —— 因为它在白名单里,而该节点又绑定了 0.0.0.0,等于把入口从云网关直接开到了操作系统层面。
真正安全的组合是三层收敛:
- 云平台白名单:只填业务服务器和运维跳板机的固定 IP
- MongoDB
net.bindIp:严格限定为副本集成员 IP + 127.0.0.1 - 系统防火墙(UFW/iptables):默认 deny,仅放行上述 IP 段的 27017/tcp
任何一层缺失,都可能让攻击者绕过其中一环。尤其注意:副本集仲裁节点(arbiter)虽不存数据,但同样需要相同网络策略 —— 它参与投票,一旦被控,可助攻击者触发主从切换。


















