更改 IP 地址时更改 iptables 中的所有规则

更改 IP 地址时更改 iptables 中的所有规则

我有一个网络网关系统,使用 iptables 来允许/拒绝往返内部网络的流量。我必须iptables根据内部网络中实体的要求手动添加和删除规则,包括对其流量进行 NAT。内部网络上的受信任实体可以根据需要请求添加和删除规则。最终结果是和表中的一堆规则natfilter包括POSTROUTING带有目标的规则SNAT,将源 IP 设置为网关系统的 IP,以及其他表中将网关外部 IP 地址设置为的规则dst

我希望能够动态设置网关系统的 IP。这当然会对 TCP 会话等造成破坏性后果,但我们先不考虑这一点。系统使用其他机制来处理这些问题。

问题是防火墙表中未知数量的规则仍然引用这个旧的源 IP 地址。

有没有办法轻松地更改所有这些规则以使用新的 IP 地址而不是旧的 IP 地址?当然,如果您比我更熟悉 bash,我也可以使用 sed/awk 或类似程序接受一些花哨的脚本......

答案1

如果被 SNAT 的流量始终使用出站接口的 IP 地址,请将其替换-j SNAT-j MASQUERADE。这将使用相同的基于 conntrack 的 SNAT,但会自动选择替换源地址。

iptables-save您可以使用和批量编辑 iptables 规则iptables-restore

  • 例如,以交互方式编辑规则集(特别是如果您的编辑器具有良好的搜索和替换功能):

    iptables-save > /tmp/rules
    vim /tmp/rules
    iptables-restore < /tmp/rules
    

    使用 moreutils 中的‘vipe’:

    iptables-save | vipe | iptables-restore
    
  • 要将一个确切的 IP 地址批量替换为另一个 IP 地址(请记住,.在正则表达式中是一个通配符,同时使用它\b来确保“12.34”不会意外匹配“112.34”):

    iptables-save | sed 's/\b12\.34\.56\.78\b/12.34.56.99/g' | iptables-restore
    

但我认为,任何编辑 iptables 规则(包括基于脚本的“iptables -A”设置)是一种不好的方法。相反,保留一个iptables.rules 文件(采用 iptables-save 格式)作为“源”,并始终从该文件加载规则集。然后,您可以开始使用某种形式的宏/模板语言来定义一次 IP 地址并在任何地方引用它 - 类似于通过 Salt/Ansible 部署配置文件时的操作(如果仍有人使用的话)。

  • 例如(实际上不要这样做;它会很快演变成难以控制的事情):

    cat /etc/iptables.rules | sed 's/%CUST_IP%/12.34.56.78/g' | iptables-restore
    
  • 我还建议您看一下 Ferm,它为 iptables 规则实现了另一种语法 —— 总体来说更易读,而且还内置了宏,因此您@def $cust_ip只需一次引用它就可以在任何地方引用它。

    domain (ip ip6) {
        @def dns_host4 = 10.10.0.53;
        @def ntp_host4 = 10.10.0.123;
    
        table filter {
            chain FORWARD {
                daddr ($dns_host4 $ntp_host4) accept;
            }
        }
    
        table nat {
            chain PREROUTING {
                proto (tcp udp) dport 53 DNAT to-destination $dns_host4;
                proto udp dport 123 DNAT to-destination $ntp_host4;
            }
        }
    }
    

    它的工作原理类似于 iptables-restore – 无需实时更改,只需编辑/etc/ferm.conf并运行ferm即可在完成后重新加载整个规则集。如果 IP 地址发生变化,只需编辑 ferm.conf 中的 @def 宏并重新加载即可。

    (此外,如果您最终切换到 nftables,最好习惯这一点,因为它的工作原理与 Ferm 几乎相同 - 当然语法有点不同,但它也有 $macros,您可以编辑 /etc/nftables.conf 并一次重新加载整个内容。)

答案2

我建议将 iptables 与 ipset 结合使用。

在 iptables 中,你会有你的规则,然后添加 --match-set setname src

iptables -I PREROUTING -s whatever ... --match-set setname src
iptables -I PREROUTING -s whatever ... --match-set setname dst

然后,为了禁用规则,您需要从名为“setname”的集合中删除 IP 地址。要启用它,您只需向 setname 添加一个 IP 地址。

然后 iptables 保持不变,你只需从 setname 中添加和减去条目

根据需要,每条规则可以有不同的名称。

相关内容