![使用 DNS 进行流量路由](https://linux22.com/image/69899/%E4%BD%BF%E7%94%A8%20DNS%20%E8%BF%9B%E8%A1%8C%E6%B5%81%E9%87%8F%E8%B7%AF%E7%94%B1.png)
我有 2 台网关机器。 1 debian(主 - 192.168.1.1),1 centos(备份 192.168.1.2)。有 2 个网络,1 个 LAN 和 1 个 WAN,通过“主网络”,然后通过 ISP1“备份”位于 LAN 上,并通过 PPP(基本上通过 3G 棒)传至 ISP2
问题是,当 ISP1“死机”或由于恶劣天气或其他原因丢包时,我希望能够手动设置肯定LAN 站的 INTERNET 流量通过 ISP2,将其余流量留在 ISP1 上。因此,假设我希望 192.168.1.3 通常通过 GW1/ISP1 上网,然后在某个时候我想手动将其切换到 GW2/ISP2。我需要尽可能在不“接触”站点网络设置的情况下执行此操作,因为它会破坏本地网络连接,这不可以发生。
192.168.1.3 (WinXP) 有默认网关 192.168.1.1 和通过 DHCP 方式设置到 ISP1 的 2 个 DNS 服务器的 DNS 服务器
我尝试了使用DNAT(它似乎用192.168.1.2替换任何外部IP,因此通信在那里停止)和ip路由(这搞乱了本地网络通信)的各种解决方案
我认为我在 iptables DNAT 解决方案中没有看到明显的东西,但我无法指出它。作为参考,该行看起来像这样:
iptables -t nat -A PREROUTING -s 192.168.1.3 ! -d 192.168.1.0/8 -j DNAT --to 192.168.1.2
ip路由是这样完成的:
ip route add 192.168.1.3 via 192.168.1.2
均在 GW1 (192.168.1.1) 上完成
GW2 中启用了 ip 转发(显然,GW1 中的路由和 NAT 本身一切正常)
GW2 上的 iptables 规则看起来像这样(来自 iptables-save),因为我不太确定它是否正常。
*nat
:PREROUTING ACCEPT [21038:1379326]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [302:19015]
-A POSTROUTING -o ppp0 -j MASQUERADE
COMMIT
*filter
:INPUT ACCEPT [61306:4073979]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [27660:3745654]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A FORWARD -s 192.168.1.3/32 -j ACCEPT
-A FORWARD -d 192.168.1.3/32 -j ACCEPT
COMMIT
谢谢。
答案1
您的 Debian 路由器(主路由器 - 192.168.1.1)不应尝试对流量进行 NAT 以便将其重定向到备用路由器。最好的情况是,这将导致双重 NAT(因为备份路由器将ppp0
按照其规则再次对其进行 NAT MASQUERADE
),最坏的情况是您将重写 IP 地址,从而使返回流量无法获得后退。
最简单的选择是使用 VRRP。设置两个路由器之间共享的虚拟网关地址。设置优先级,以便主路由器默认担任主路由器角色,但在其自己的 Internet 连接不可用时退出。在Linux下,使用VRRPD实施VRRP。然后将要切换的工作站的默认网关设置为虚拟网关地址,其余的保留指向主路由器的真实IP地址。
如果您想真正手动执行此操作,则甚至不需要 VRRP。只需手动管理虚拟网关地址,将其从主路由器 ( ip addr del x.y.z.w/qq dev eth?
) 中删除并将其添加到另一个路由器 ( ip addr add x.y.z.w/qq dev eth?
) 中。但请注意,除了 IP 地址之外,真正的 VRRP 还管理 MAC 地址,因此如果您采用手动路由(无双关语),您可能会遇到一些 ARP 问题。
另一种方法是在 Debian 路由器上安装指向备用路由器的静态默认路由。您可以使用策略路由(使用ip rule
)将此路由仅应用于具有特定源 IP 地址的数据包。该路由应具有比走出 WAN 的默认路由更高的度量。因此,当存在从 WAN 发出的默认路由时,它将被独占使用,否则流量将遵循回退默认路由。这种默认路由可能会也可能不会导致将 ICMP 重定向发送到工作站。您可能希望禁用这些功能,以便工作站在返回时立即返回到主路由,假设主路由器可以处理重定向到其他路由器的进出流量。 ( /proc/sys/net/ipv4/conf/<intf>/send_redirects
)
答案2
好像忘记回复了。所以这就是我最终解决它的方法:
- 我将 LAN1 设置为还托管转发 DNS 服务器
- 我更改了 DHCP 设置,并将 DNS 服务器从 ISP 服务器更改为本地服务器(LAN1)
- 我在 3g 路由器上编写了一个脚本,用于获取网络信息,将自身配置为本地网关,将 LAN 网关更改为指向自身,基本上如下所示(必须在通过 vwdial 建立 3g 连接后立即执行(我有一个不同的脚本,因为我喜欢保持它以观察成功的连接和任何网络问题)):
#!/bin/sh
# get info
LOCAL_IP=`tail -n 20 /var/log/messages | grep pppd | grep local | sed "s/.*IP address \(.*\)/\1/"`
REMOTE_IP=`tail -n 20 /var/log/messages | grep pppd | grep ": remote" | sed "s/.*IP address \(.*\)/\1/"`
DNS1=`tail -n 20 /var/log/messages | grep pppd | grep ": primary" | sed "s/.*DNS address \(.*\)/\1/"`
DNS2=`tail -n 20 /var/log/messages | grep pppd | grep ": secondary" | sed "s/.*DNS address \(.*\)/\1/"`
echo got info LOCAL_IP=$LOCAL_IP REMOTE_IP=$REMOTE_IP DNS1=$DNS1 DNS2=$DNS2
# setup self as gateway
echo nameserver $DNS1>/etc/resolv.conf
echo nameserver $DNS2>>/etc/resolv.conf
route del default gw 192.168.1.1 eth0
route add default gw $REMOTE_IP ppp0
echo done setting up self with new params
# setup old gateway to forward to self
echo changing dplug routes
ssh [email protected] 'route del default gw X.Y.Z.W eth0'
ssh [email protected] 'route add default gw 192.168.1.7 eth1'
echo removing dplug LAN SNAT
ssh [email protected] 'iptables -t nat -D POSTROUTING -o eth0 -j SNAT --to-source A.B.C.D'
echo deleting WIFI SNAT
ssh [email protected] 'eval "$(cat firewall/iptables | grep "\-A POSTR" | grep -v "\#" | sed "s/-A/iptables -t nat -D/")"'
echo adding new WIFI SNAT
ssh [email protected] 'eval "$(cat firewall/iptables | grep "\-A POSTR" | grep -v "\#" | grep 192.168.2 | sed "s/\(-A .*\) -o .*/iptables -t nat \1 -o eth1 -j SNAT --to-source 192.168.1.1/")"'
echo setting up dnsmasq DHCP for new values
ssh [email protected] 'echo "# this dnsmasq config file is generated by 3g router. do not edit.">/etc/dnsmasq.3g.conf'
ssh [email protected] "echo server=$DNS1>>/etc/dnsmasq.3g.conf"
ssh [email protected] "echo server=$DNS2>>/etc/dnsmasq.3g.conf"
ssh [email protected] "echo dhcp-option=net:wlan,6,$DNS1,$DNS2>>/etc/dnsmasq.3g.conf"
ssh [email protected] "echo dhcp-option=net:lan,6,$DNS1,$DNS2>>/etc/dnsmasq.3g.conf"
echo restarting dnsmasq
ssh [email protected] '/etc/init.d/dnsmasq restart'
echo all done
/etc/dnsmasq.3g.conf 包含在 dnsmasq.conf 中,它本来是空的。有一个脚本可以以简约的方式撤消上述操作,因为我然后只是杀死 3g 路由器虚拟机(拔出 3g USB 棒会导致内核恐慌......),所以我并不真正关心它。
该脚本确保只有那些配置为 Internet 访问的 WAN IP 将继续具有 Internet 访问权限,而其他 IP 则不会。用于互联网访问的 LAN IP 手动添加到 3g 路由器的 iptables 中。 (那些不会改变)