iptables 域名转发的核心实现方案是利用 ipset 工具动态维护 IP 地址列表,配合 DNS 解析脚本 将域名实时转换为 IP,再通过 iptables 的 NAT 表 进行流量劫持与重定向,由于 iptables 工作在 OSI 模型的第三层(网络层)和第四层(传输层),它本身无法直接识别第七层(应用层)的域名信息,因此必须借助 ipset 作为桥梁,将域名解析结果映射为 IP 集合,从而实现基于域名的精准流量转发,这种方法在构建透明代理、内网穿透或特定域名流量分流场景中具有极高的实用价值。

技术原理:iptables 与域名的层级隔阂
要掌握 iptables 域名转发,首先必须理解 Linux 内核网络栈的工作机制。iptables 是基于数据包头部信息进行过滤的,主要依据源 IP、目的 IP、端口号和协议号,当用户在浏览器访问一个域名时,虽然应用层发送的是域名,但在数据包离开操作系统进入网络之前,系统必须通过 DNS 协议将域名解析为目标 IP 地址,当 iptables 收到数据包时,它只能看到目标 IP,而看不到原始的域名。
这就引出了技术难点:如果目标服务器的 IP 是动态变化的(如 CDN 节点或云负载均衡),或者多个域名共享同一个 IP,单纯依靠 IP 转发将无法满足需求。ipset 的出现解决了这一痛点,ipset 是 Linux 内核的一个扩展,它允许用户创建一个 IP 地址的集合,并高效地对该集合进行匹配,通过定时任务或脚本,我们可以定期解析指定域名,将其 IP 更新到 ipset 集合中,iptables 只需匹配该集合即可实现“域名级”的转发。
实施步骤:构建基于域名的转发链路
实现这一功能需要三个关键步骤:创建 ipset 集合、编写 DNS 解析与更新脚本、配置 iptables 规则。
第一步:创建并管理 ipset 集合
系统需要安装 ipset 工具,我们需要创建一个哈希类型的 IP 集合,用于存储目标域名解析出的 IP 地址,使用 ipset create my_domain_set hash:ip 命令即可创建,为了保证转发规则的稳定性,建议设置超时时间,hash:ip timeout 300,这样即使 DNS 解析脚本出现异常,旧的 IP 规则也会在一段时间后自动失效,避免流量被错误地导向失效的 IP。
第二步:编写动态解析脚本
这是方案中最具技术含量的部分,我们需要编写一个 Shell 脚本,利用 dig 或 nslookup 命令获取域名的最新 A 记录,脚本逻辑如下:首先解析域名,获取返回的 IP 列表;然后清空 ipset 中旧的条目(或者进行差异比对);最后将新的 IP 添加到集合中。
为了应对 CDN 等多 IP 场景,脚本必须能够处理域名解析返回的多个 IP 地址,确保所有可能的节点 IP 都被加入转发规则,该脚本应放入 crontab 中每分钟执行一次,以确保域名 IP 变更能被及时感知。

第三步:配置 iptables NAT 规则
有了动态更新的 IP 集合,接下来就是配置 iptables,我们需要在 nat 表的 PREROUTING 链中进行操作,这是数据包进入路由判断前的关键节点。
核心命令示例:iptables -t nat -A PREROUTING -p tcp --dport 80 -m set --match-set my_domain_set dst -j REDIRECT --to-port 8080。
这条规则的含义是:对于所有目的端口为 80 的 TCP 流量,如果其目的 IP 存在于 my_domain_set 集合中,则将其重定向到本机的 8080 端口,如果需要转发到其他服务器,则可以使用 DNAT 目标动作,将数据包的目的 IP 修改为内网服务器的 IP。
专业见解与生产环境优化
在实际的生产环境中,仅仅实现转发是不够的,还需要考虑 性能、安全与高可用。
性能优化方面,ipset 的查询效率极高,即使集合中有数万条 IP,匹配速度也几乎不受影响,频繁的 DNS 解析会带来网络开销,建议在脚本中增加缓存机制,只有当解析结果与上一次不一致时,才去更新 ipset,从而减少不必要的系统调用。
安全与可靠性方面,必须警惕“域名劫持”风险,DNS 解析被篡改,流量可能被转发至恶意 IP,在脚本中应增加 IP 合法性校验,例如只允许内网 IP 或特定的公网 IP 段加入集合,对于 HTTPS 流量,iptables 的 REDIRECT 或 DNAT 只能转发 TCP 层数据,如果不配合 SSL 证书卸载,客户端直接访问会出现证书错误,通常的做法是在转发目标端口(如 8080)部署一个反向代理(如 Nginx 或 Squid),由该代理负责与目标服务器建立 HTTPS 连接,从而对客户端透明。
CDN 场景的特殊处理是本方案的难点,许多大型网站使用 CDN,域名解析出的 IP 可能是成百上千个边缘节点 IP,且这些 IP 变化极快,在这种情况下,基于 iptables 的域名转发可能会变得难以维护,且容易误伤共享同一 CDN IP 的其他域名,对此,专业的解决方案是结合应用层代理(如 SNI Proxy),它能够解析 TLS ClientHello 中的 SNI(Server Name Indication)字段,从而在真正建立连接前获取域名,但在纯 iptables 场景下,我们只能通过缩小 IP 范围或接受一定的“误杀”风险来换取转发功能的实现。

相关问答
Q1:iptables 能否直接通过 -d 参数指定域名进行转发?
A: 不能,iptables 的 -d(destination)参数在规则加载时只会解析一次当时的 IP 地址并固化,如果域名的 DNS 记录后续发生变化,iptables 规则仍然指向旧的 IP,导致转发失效,直接在 iptables 规则中使用域名是不可靠的,必须配合 ipset 实现动态更新。
Q2:使用 iptables 进行域名转发后,目标服务器获取到的真实源 IP 是什么?如何保留真实源 IP?
A: 在使用 DNAT 或 REDIRECT 模式下,数据包经过了 NAT 转换,目标服务器看到的源 IP 是转发服务器的 IP,而不是客户端的真实 IP,要保留真实源 IP,通常需要在转发层(如 Nginx)配置 X-Forwarded-For 头部字段,如果必须透传 IP 层信息,可以使用 TPROXY(透明代理)技术,但这需要更复杂的路由配置和应用程序支持,标准的 iptables NAT 转发无法直接做到这一点。
希望以上方案能为您的网络配置提供有力的技术支撑,如果您在实施过程中遇到关于脚本编写或规则匹配的具体问题,欢迎在评论区留言,我们可以进一步探讨细节。

















