You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用IPtables规则解决DNS解析IP频繁变更导致的连接超时问题

解决IPtables因DNS解析IP频繁变更导致的连接超时问题

这个问题我在运维场景里碰到过好多次——本质就是IPtables的规则是静态绑定IP的,一旦域名解析的IP变了,旧规则就失效了,必须手动刷新。下面几个方案按实用性和复杂度排序,你可以根据自己的环境选:

方案1:用ipset + 定时任务动态更新IP(最推荐)

ipset是IPtables的扩展工具,能把一组IP放在一个集合里,IPtables规则直接匹配这个集合就行。我们可以写个脚本定期解析域名的IP,更新ipset集合,不用动IPtables主规则。

步骤:

  • 安装ipset及解析工具:

    • Debian/Ubuntu系:sudo apt install ipset dnsutils(dnsutils提供dig命令用于解析域名)
    • CentOS/RHEL系:sudo yum install ipset bind-utils
  • 创建ipset集合:

    sudo ipset create dynamic_dns hash:ip
    

    (如果需要支持IPv6,把集合类型改成hash:ip6)

  • 添加IPtables规则匹配集合:
    比如你要允许访问该域名的80/443端口,就添加这条规则(根据实际业务的链和端口调整):

    sudo iptables -A OUTPUT -p tcp -m multiport --dports 80,443 -m set --match-set dynamic_dns dst -j ACCEPT
    

    要是需要允许外部访问到这个域名的IP(比如INPUT链场景),把OUTPUT改成INPUT,dst改成src即可。

  • 编写自动更新脚本:
    创建脚本文件/usr/local/bin/update_dns_ipset.sh,内容如下:

    #!/bin/bash
    DOMAIN="test.example.com"
    IPSET_NAME="dynamic_dns"
    
    # 获取域名当前的所有IPv4解析结果,过滤掉非IP内容
    CURRENT_IPS=$(dig +short $DOMAIN | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$')
    
    # 清空集合里的旧IP
    sudo ipset flush $IPSET_NAME
    
    # 将新IP逐一添加到集合
    for ip in $CURRENT_IPS; do
        sudo ipset add $IPSET_NAME $ip
    done
    
  • 给脚本添加执行权限:

    sudo chmod +x /usr/local/bin/update_dns_ipset.sh
    
  • 设置定时任务自动运行:
    用crontab配置定时执行,比如每5分钟更新一次:

    sudo crontab -e
    

    在打开的编辑器中添加一行:

    */5 * * * * /usr/local/bin/update_dns_ipset.sh
    

优点:

  • 不需要重启IPtables,仅更新ipset集合,对业务无影响
  • 支持多IP解析,能覆盖域名的所有解析结果
  • 性能比频繁修改IPtables规则高很多

方案2:切换到nftables(内置动态DNS支持)

如果你还在用传统IPtables,不妨考虑升级到nftables——它是Linux内核官方推荐的下一代防火墙工具,支持直接匹配域名,并且会自动定期刷新DNS解析结果。

步骤:

  • 安装nftables:

    • Debian/Ubuntu系:sudo apt install nftables
    • CentOS/RHEL系:sudo yum install nftables
  • 编写nftables规则:
    编辑nftables配置文件(比如/etc/nftables.conf),添加对应规则:

    table ip filter {
        chain output {
            type filter hook output priority 0; policy accept;
            # 允许访问test.example.com的80/443端口
            tcp dport {80, 443} dname "test.example.com" accept;
        }
    }
    

    若需要INPUT链规则,在对应的chain下添加即可。

  • 重启nftables服务生效:

    sudo systemctl restart nftables
    

注意:

  • 需要Linux内核4.19以上、nftables版本0.9.3以上才能支持dname域名匹配功能
  • 规则会自动定期刷新域名解析IP,无需额外脚本维护

方案3:直接用脚本更新IPtables规则(临时应急备选)

如果暂时不想切换工具,也可以写脚本直接修改IPtables规则,但这种方法效率低,频繁修改规则可能影响防火墙性能,仅适合临时应急。

大致思路:

  • 脚本定期解析域名的新IP
  • 通过iptables-save定位并删除旧的IP规则
  • 添加新的IP规则
  • 用crontab定时运行脚本

不过这种方法容易出现规则匹配错误,且每次修改都要刷新IPtables,稳定性不如前两个方案,不推荐长期使用。


内容的提问来源于stack exchange,提问作者Biks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:02:23