iptables封端口

iptables封端口最佳实践


当前状况

  1. 服务配置

    • Docker 容器监听:172.17.0.2:5000
    • NAT 映射:宿主机:30081 → 172.17.0.2:5000
  2. 数据包流向

    外部客户端 → 宿主机:30081
        ↓
    PREROUTING (NAT表) - DNAT: 改写目标 → 172.17.0.2:5000
        ↓
    路由决策: 发现目标为容器IP,走 FORWARD 链
        ↓
    FORWARD 链: 包已是5000端口,无法匹配30081规则
        ↓
    Docker 容器 172.17.0.2:5000
    
  3. 当前 DROP 规则无效的原因

    • INPUT 链规则失效:只作用于访问宿主机本身的流量,DNAT 后的流量不走 INPUT。
    • FORWARD 链 DROP 30081 规则失效:此时端口已被 DNAT 改为 5000,匹配不到 30081。
    • FORWARD 链 DROP 5000 规则无效:规则在 DOCKER 链后面,而 DOCKER 链已 ACCEPT 了流量。

解决方案对比

方案1:在 NAT 表做限制(❌ 不推荐)

iptables -t nat -I PREROUTING ! -s <允许IP> -p tcp --dport 30081 -j DROP
  • 缺点:NAT 表本意是做地址转换,不应该直接 DROP,违反规范。

方案2:在 raw 表做限制(✅ 推荐)

# 允许指定来源访问
iptables -t raw -I PREROUTING -s <允许IP> -p tcp --dport 30081 -j ACCEPT
# 拒绝其他来源
iptables -t raw -A PREROUTING -p tcp --dport 30081 -j DROP
  • 优点:

    1. DNAT 之前 拦截,规则简单明了
    2. 处理阶段最早,性能最佳
    3. 符合 iptables 最佳实践

方案3:调整 FORWARD 链顺序

# 删除原有无效规则
iptables -D FORWARD 1
# 在 DOCKER 链之前拦截
iptables -I FORWARD 1 ! -s <允许IP> -d 172.17.0.2 -p tcp --dport 5000 -j DROP
  • 优点:可行
  • 缺点:需提前知道容器 IP,规则依赖具体容器

方案4:使用 conntrack 标记(最灵活)

# mangle表:标记不允许的连接
iptables -t mangle -A PREROUTING ! -s <允许IP> -p tcp --dport 30081 -j MARK --set-mark 0x99
# filter表:丢弃带标记的连接
iptables -I FORWARD 1 -m mark --mark 0x99 -j DROP
  • 优点:

    1. 不受 DNAT 影响
    2. 灵活,可扩展复杂策略
  • 缺点:实现复杂度高


建议

  • 首选方案 2(raw 表拦截)

    • 逻辑清晰,在 DNAT 前截断,不依赖容器 IP。
    • 规则简洁,性能最好,维护成本最低。

要不要我帮你画一个 iptables 数据包流向 + 拦截点示意图(Mermaid 流程图),这样更直观地对比这几种方案?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值