如何使用iptables实现仅针对特定域名的L3 NAT路由?
如何使用iptables实现仅针对特定域名的L3 NAT路由?
这个问题的核心点在于:L3(网络层)路由是基于IP地址工作的,而域名属于L7(应用层)的内容——iptables本身没法直接匹配域名,所以我们得先把域名解析成对应的IP,再针对这些IP做路由和NAT配置。下面一步步来实现:
1. 先获取目标域名对应的IP地址
因为iptables只能识别IP,所以首先要把你想走Tailscale的域名解析成IP。可以用dig命令手动查询:
dig example.com +short
如果域名有多个IP或者IP会动态变化,后面可以写个脚本定期更新IP列表(后面会提到)。
2. 创建自定义路由表
我们需要一个专门的路由表,用来处理这些目标IP的流量,让它们走tailscale0接口。先编辑/etc/iproute2/rt_tables文件,添加一行自定义表(数字可以选100-254之间未被使用的,这里用100为例):
sudo tee -a /etc/iproute2/rt_tables <<EOF 100 tailscale-domains EOF
3. 给目标IP添加专属路由
把目标IP/IP段指向自定义路由表,指定走tailscale0接口:
- 如果是单个IP:
sudo ip route add 198.51.100.1 dev tailscale0 table tailscale-domains
- 如果是IP段:
sudo ip route add 198.51.100.0/24 dev tailscale0 table tailscale-domains
如果需要支持IPv6,同样添加对应的IPv6路由:
sudo ip -6 route add 2001:db8::1 dev tailscale0 table tailscale-domains
4. 添加IP规则,让流量匹配路由表
添加规则,让发往这些目标IP的流量使用我们自定义的路由表:
- 单个IPv4:
sudo ip rule add to 198.51.100.1 lookup tailscale-domains
- IPv4段:
sudo ip rule add to 198.51.100.0/24 lookup tailscale-domains
IPv6同理:
sudo ip -6 rule add to 2001:db8::1 lookup tailscale-domains
5. 保留(或调整)NAT规则
你之前设置的MASQUERADE规则已经足够,因为它只针对tailscale0接口的流量做NAT:
sudo iptables -t nat -A POSTROUTING -o tailscale0 -j MASQUERADE
如果要更严格,也可以加上目标IP的匹配(比如只对我们指定的IP段做NAT),但一般没必要,因为只有走tailscale0的流量才会触发这条规则。
6. 处理动态IP的情况(可选)
如果目标域名的IP经常变化,比如CDN类的域名,可以写个脚本定期更新路由:
#!/bin/bash DOMAIN="example.com" TABLE="tailscale-domains" INTERFACE="tailscale0" # 删除旧的路由 sudo ip route flush table $TABLE # 获取最新IP并添加路由 for IP in $(dig $DOMAIN +short); do sudo ip route add $IP dev $INTERFACE table $TABLE sudo ip rule add to $IP lookup $TABLE done
然后用cron定时执行这个脚本,比如每天凌晨跑一次:
sudo crontab -e # 添加一行 0 0 * * * /path/to/your/script.sh
7. 确保IP转发永久生效
把你之前设置的IP转发参数写到/etc/sysctl.conf里,避免重启后失效:
sudo tee -a /etc/sysctl.conf <<EOF net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1 EOF # 生效配置 sudo sysctl -p
备注:内容来源于stack exchange,提问作者Sawtaytoes
相关产品推荐
相关产品推荐

