背景
- 服务器:
10.32.26.41 服务:Docker 容器运行
2121→ vsftpd(容器内端口21)25432→ MySQL(容器内端口3306)
需求:
- 拒绝任意 IP 访问
10.32.26.41:2121/25432 - 允许
10.32.26.100、172.18.77.254访问
- 拒绝任意 IP 访问
问题排查过程
| 尝试方案 | 结果 | 原因 |
|---|---|---|
DOCKER-USER 链 + -d 10.32.26.41 | ❌ 不生效 | Docker 做 DNAT 后目标 IP 已变为容器内网 IP,规则匹配不上 |
DOCKER-USER 链 + conntrack --ctorigdst | ❌ 不生效 | pkts 始终为 0,流量未走到 DOCKER-USER |
INPUT 链顶部插入 DROP/ACCEPT | ❌ 不生效 | 服务器上运行的第三方安全软件(nfExtRuleIn 等)在 INPUT 之前已放行流量 |
mangle PREROUTING | ✅ 生效 | 这是 netfilter 中比 INPUT 更早的 hook 点,第三方软件尚未介入 |
该服务器上存在第三方安全/防火墙产品(如深信服、奇安信等),注册了nfExtRuleIn、nfExtRuleForward等自定义链,导致常规INPUT/DOCKER-USER拦截失效。
最终生效方案
核心思路
在 mangle 表的 PREROUTING 链中拦截:
- 白名单 IP →
RETURN(放行,继续后续处理) - 其他所有 IP →
DROP(直接丢弃,不进入后续链)
执行命令
# 1. 白名单放行(RETURN = 不处理,继续后续流程)
iptables -t mangle -I PREROUTING -s 10.32.26.100 -p tcp -m multiport --dports 2121,25432 -j RETURN
iptables -t mangle -I PREROUTING -s 172.18.77.254 -p tcp -m multiport --dports 2121,25432 -j RETURN
# 2. 其他所有 IP 拒绝
iptables -t mangle -I PREROUTING -p tcp -m multiport --dports 2121,25432 -j DROP验证规则顺序
iptables -t mangle -L PREROUTING -n -v --line-numbers正确输出:
num pkts bytes target prot opt in out source destination
1 0 0 RETURN tcp -- * * 10.32.26.100 0.0.0.0/0 multiport dports 2121,25432
2 0 0 RETURN tcp -- * * 172.18.77.254 0.0.0.0/0 multiport dports 2121,25432
3 0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 2121,25432注意顺序:RETURN必须在DROP的上面(行号更小),否则白名单也会被拒绝。
策略效果
| 来源 IP | 访问 10.32.26.41:2121 (vsftpd) | 访问 10.32.26.41:25432 (MySQL) |
|---|---|---|
10.32.26.100 | ✅ 允许 | ✅ 允许 |
172.18.77.254 | ✅ 允许 | ✅ 允许 |
| 其他任意 IP | ❌ 拒绝(连接超时) | ❌ 拒绝(连接超时) |
持久化保存
重启后规则会丢失,务必保存:
# CentOS / RHEL
iptables-save > /etc/sysconfig/iptables
# Ubuntu / Debian
iptables-save > /etc/iptables/rules.v4后续维护
新增白名单 IP
# 插入到 DROP 规则之前(假设 DROP 在第 3 行)
iptables -t mangle -I PREROUTING 3 -s <新IP> -p tcp -m multiport --dports 2121,25432 -j RETURN移除白名单 IP
# 先查看行号
iptables -t mangle -L PREROUTING -n -v --line-numbers
# 按行号删除
iptables -t mangle -D PREROUTING <行号>完全移除本策略
iptables -t mangle -D PREROUTING -s 10.32.26.100 -p tcp -m multiport --dports 2121,25432 -j RETURN
iptables -t mangle -D PREROUTING -s 172.18.77.254 -p tcp -m multiport --dports 2121,25432 -j RETURN
iptables -t mangle -D PREROUTING -p tcp -m multiport --dports 2121,25432 -j DROP关键教训
- Docker
userland-proxy模式:外部访问映射端口时,流量先到达宿主机的docker-proxy进程,再走INPUT链,不一定经过DOCKER-USER。 - 第三方安全软件干扰:企业服务器常安装主机安全 Agent,会在 netfilter 多个 hook 点注册规则,可能提前放行或丢弃流量,导致自定义规则失效。
排查方法:如果规则
pkts始终为 0,说明流量根本没走到这条链,需要向上游(更早的 hook 点)排查。netfilter 处理顺序为:raw PREROUTING → mangle PREROUTING → nat PREROUTING → mangle FORWARD → filter FORWARD → mangle POSTROUTING → nat POSTROUTING对于本机接收的流量,在
nat PREROUTING之后进入INPUT链。
新加入端口
# 白名单放行(-I 会插到最顶部)
iptables -t mangle -I PREROUTING -s 10.32.26.100 -p tcp -m multiport --dports 65519,65520 -j RETURN
# 拒绝其他所有 IP
iptables -t mangle -I PREROUTING -p tcp -m multiport --dports 65519,65520 -j DROP
验证规则
iptables -t mangle -L PREROUTING -n -v --line-numbers[root@ZHJB-WEB-01 ~]# iptables -t mangle -L PREROUTING -n -v --line-numbers
Chain PREROUTING (policy ACCEPT 51316 packets, 15M bytes)
num pkts bytes target prot opt in out source destination
1 630 147K RETURN tcp -- * * 10.32.26.100 0.0.0.0/0 multiport dports 65519,65520
2 0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 65519,65520
3 604 34393 RETURN tcp -- * * 10.32.26.100 0.0.0.0/0 multiport dports 2121,25432
4 22267 1791K RETURN tcp -- * * 172.18.77.254 0.0.0.0/0 multiport dports 2121,25432
5 0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 2121,25432
| 行号 | 动作 | 来源 IP | 端口 | 说明 |
| -- | -------- | ------------- | ----------- | ------ |
| 1 | `RETURN` | 10.32.26.100 | 65519,65520 | 白名单放行 |
| 2 | `DROP` | 0.0.0.0/0 | 65519,65520 | 其他全部拒绝 |
| 3 | `RETURN` | 10.32.26.100 | 2121,25432 | 白名单放行 |
| 4 | `RETURN` | 172.18.77.254 | 2121,25432 | 白名单放行 |
| 5 | `DROP` | 0.0.0.0/0 | 2121,25432 | 其他全部拒绝 |
| 来源 IP | 2121 (vsftpd) | 25432 (MySQL) | 65519 | 65520 |
| ------------- | :-----------: | :-----------: | :---: | :---: |
| 10.32.26.100 | ✅ 允许 | ✅ 允许 | ✅ 允许 | ✅ 允许 |
| 172.18.77.254 | ✅ 允许 | ✅ 允许 | ❌ 拒绝 | ❌ 拒绝 |
| 其他任意 IP | ❌ 拒绝 | ❌ 拒绝 | ❌ 拒绝 | ❌ 拒绝 |
# ========== 1. 从大到小删除现有 5 条规则 ==========
iptables -t mangle -D PREROUTING 5
iptables -t mangle -D PREROUTING 4
iptables -t mangle -D PREROUTING 3
iptables -t mangle -D PREROUTING 2
iptables -t mangle -D PREROUTING 1
# ========== 2. 重新插入(先 DROP 后 RETURN,RETURN 会顶到上面)==========
# --- 2121,25432 ---
iptables -t mangle -I PREROUTING -p tcp -m multiport --dports 2121,25432 -j DROP
iptables -t mangle -I PREROUTING -s 172.18.77.254 -p tcp -m multiport --dports 2121,25432 -j RETURN
iptables -t mangle -I PREROUTING -s 10.32.26.100 -p tcp -m multiport --dports 2121,25432 -j RETURN
# --- 65519,65520 ---
iptables -t mangle -I PREROUTING -p tcp -m multiport --dports 65519,65520 -j DROP
iptables -t mangle -I PREROUTING -s 172.18.77.254 -p tcp -m multiport --dports 65519,65520 -j RETURN
iptables -t mangle -I PREROUTING -s 10.32.26.100 -p tcp -m multiport --dports 65519,65520 -j RETURN
评论 (0)