bindIp仅指定监听地址,不控制客户端IP访问;限制客户端IP需结合安全组、iptables及authenticationRestrictions三者协同实现。

bindIp 只控制监听地址,不等于限制客户端IP
bindIp 配置项决定的是 MongoDB 进程**在哪些网卡/地址上监听连接请求**,不是白名单机制。比如设成 bindIp: 192.168.1.100,意思是“只在该 IP 对应的网卡上开 27017 端口”,外部流量若路由不到这个 IP,自然连不上——但它不校验发起连接的客户端真实 IP。所以想拦住 192.168.1.0/24 以外的访问,光靠 bindIp 不行。
用 iptables 限制 IP 段:实际生效的命令组合
Linux 主机上,iptables 是最直接可控的方式。注意必须在 MongoDB 启动后、且端口已监听的前提下操作:
- 先确认 MongoDB 监听的是
0.0.0.0:27017或:::27017(即允许所有地址接入),否则iptables规则没机会匹配 - 拒绝非授权网段(例如只放行
10.0.5.0/24):sudo iptables -A INPUT -p tcp --dport 27017 ! -s 10.0.5.0/24 -j DROP
- 确保已有 ESTABLISHED 连接不受影响:
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
- 保存规则(Ubuntu/Debian):
sudo iptables-save | sudo tee /etc/iptables/rules.v4
;CentOS 7+ 用iptables-services包配合service iptables save
别漏掉 IPv6:如果服务启用了 IPv6 监听,还得加一条 ip6tables 规则,否则攻击者可能绕过。
云服务器必须配安全组,iptables 只是补充
阿里云、腾讯云、AWS 等平台的“安全组”运行在网络层,**优先级高于系统 iptables**。如果你只在服务器上配了 iptables 却没改安全组,默认会把所有外网 27017 流量在入口就丢弃——此时 iptables 根本收不到包,规则形同虚设。
- 安全组要明确放行源 IP 段(如
172.16.0.0/12),协议选 TCP,端口填27017 -
iptables在云环境里更适合做二次过滤:比如同一网段内再细分,或封掉某个具体扫描 IP(iptables -I INPUT -s 203.0.113.42 -j DROP) - 某些云厂商(如 AWS)的安全组不支持 CIDR 范围排除语法,想“只禁某个子网”必须靠
iptables实现
authenticationRestrictions 是唯一真正的客户端 IP 白名单
MongoDB 3.6+ 支持在创建用户时绑定客户端来源,这才是服务端原生的 IP 限制逻辑:
db.runCommand({
createUser: "appuser",
pwd: "secret",
roles: ["readWrite"],
authenticationRestrictions: [{
clientSource: ["192.168.10.0/24", "10.20.30.40"]
}]
})
关键点:
- 该限制对用户有效,不是全局;不同用户可设不同
clientSource - 只校验 TCP 连接发起方 IP,不防代理、NAT 后的真实用户(比如所有请求都经 LB 转发,那看到的全是 LB 的 IP)
- 必须启用
security.authorization: enabled,否则此字段被忽略 - 错误日志里会出现
Failed to authenticate ... not in authenticationRestrictions,可据此排查
真正要堵死非授权访问,得三层配合:安全组控大范围 → iptables 补细节 → 用户级 authenticationRestrictions 做最终校验。少一层,风险就多一分。


















