Docker映射端口无法通过INPUT链限制,必须在DOCKER-USER链中设置规则:先用iptables -I DOCKER-USER -i eth0 -s 白名单IP -p tcp --dport 端口 -j ACCEPT放行,再用iptables -I DOCKER-USER -i eth0 ! -s 白名单IP -p tcp --dport 端口 -j DROP拒绝其余,确保规则在Docker处理前生效。

Linux 限制特定 IP 访问开放的 TCP 端口,核心思路是“先放行白名单,再拒绝其余”,关键在于规则顺序和链选择。直接在 INPUT 链中按需插入 ACCEPT 和 DROP 规则即可生效,无需复杂配置。
用 iptables 实现精准控制
iptables 是最通用、最直接的方式,适用于大多数传统 Linux 发行版(如 CentOS 7 及以下、Ubuntu 等):
- 允许指定 IP 访问某端口(例如只让 192.168.1.100 访问 3306):
iptables -I INPUT -p tcp -s 192.168.1.100 --dport 3306 -j ACCEPT - 紧接着拒绝其他所有 IP 对该端口的访问:
iptables -I INPUT -p tcp --dport 3306 -j DROP - 注意:-I 表示插入到规则最前面,确保白名单优先匹配;若用 -A 则需保证 ACCEPT 在 DROP 之前,否则 DROP 会拦截所有流量
用 firewalld 设置富规则(推荐用于 CentOS/RHEL 8+)
firewalld 更适合 systemd 环境,规则更易维护且支持永久生效:
- 添加白名单规则(仅允许多个 IP 访问 8080):
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="8080" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.2.5" port port="8080" protocol="tcp" accept' - 可选:显式拒绝其余访问(firewalld 默认已拒绝,但加一条更明确):
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="8080" protocol="tcp" drop' - 最后执行:
firewall-cmd --reload
针对 Docker 容器服务的特殊处理
如果端口是通过 docker run -p 暴露的,iptables 的 INPUT 链规则无效——Docker 自动将流量导向 DOCKER 链。必须使用 DOCKER-USER 链:
- 只允许 203.101.5.12 访问宿主机映射的 80 端口:
iptables -I DOCKER-USER -i eth0 ! -s 203.101.5.12 -p tcp --dport 80 -j DROP - 其中
eth0替换为你的实际外网网卡名(可用ip link show查看) - 该规则在 Docker 处理前生效,能真正拦截非授权请求
保存与验证规则
临时规则重启后丢失,务必持久化并确认效果:
- iptables 保存(Ubuntu/Debian):
iptables-save > /etc/iptables/rules.v4 - iptables 保存(CentOS 6/7):
service iptables save 或 iptables-save > /etc/sysconfig/iptables - firewalld 不需要额外保存,--permanent 参数已写入配置
- 验证是否生效:
iptables -L INPUT -n | grep 3306(查看规则)
firewall-cmd --list-all(查看 firewalld 全局规则)











