我正在运行 Gentoo Linux,因此使用普通的 iptbales 来管理我的防火墙和网络。我通常使用 wan0 处理所有流量,但由于我已经有一个网络服务器,我希望将 wan1 (绑定到另一个域)作为我的第二个网络服务器。
我有三个接口:
- eth0 = 局域网
- wan0 = 主要使用的 WAN(默认网关)
- wan1 = 辅助 WAN
关于网关的一些信息
> route -n
Kernel IP Routentabelle
Ziel Router Genmask Flags Metric Ref Use Iface
0.0.0.0 80.108.x.x 0.0.0.0 UG 0 0 0 wan0
192.168.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
80.108.x.0 0.0.0.0 255.255.254.0 U 0 0 0 wan0
84.114.y.0 0.0.0.0 255.255.255.0 U 0 0 0 wan1
127.0.0.0 127.0.0.1 255.0.0.0 UG 0 0 0 lo
NAT/MASQUEARDING 的默认初始化是
sysctl -q -w net.ipv4.conf.all.forwarding=1
iptables -N BLOCK
iptables -A BLOCK -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A BLOCK -m state --state NEW,ESTABLISHED -i eth0 -j ACCEPT
iptables -A BLOCK -m state --state NEW,ESTABLISHED -i lo -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/16 -j MASQUERADE
iptables -t nat -A POSTROUTING -o wan0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o wan1 -j MASQUERADE
在这个网关后面,我运行着几个 Web 服务器。在一台机器上,我在端口 8000 而不是 80 上运行 HTTP 服务器。通常,当我使用 wan0 作为传入接口时,我会使用以下规则:
lan_host1="192.168.0.200"
iptables -A FORWARD -i wan0 -p TCP -d $lan_host1--dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -i wan0 -p TCP --dport 8000 -j DNAT --to-destination "$lan_host1":80
iptables -A FORWARD -i wan0 -p UDP -d $lan_host1--dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -i wan0 -p UDP --dport 8000 -j DNAT --to-destination "$lan_host1":80
效果很好。现在我想使用 wan1,因为 wan0 与我通常用于其他用途的 IP/域绑定。
我认为对 wan1 进行简单的更改就可以了。
lan_host1="192.168.0.200"
iptables -A FORWARD -i wan1 -p TCP -d $lan_host1--dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -i wan1 -p TCP --dport 8000 -j DNAT --to-destination "$lan_host1":80
iptables -A FORWARD -i wan1 -p UDP -d $lan_host1--dport 80 -j ACCEPT
iptables -t nat -A PREROUTING -i wan1 -p UDP --dport 8000 -j DNAT --to-destination "$lan_host1":80
但这是行不通的。我猜问题是 wan0 是默认 GW。所以我猜测 wan1 收到的包会转发到 lan_host1,但是当发送回网关时,它们会通过 wan0 而不是 wan1 发送,或者至少使用 wan0 的 ip。
有什么建议我可以如何处理这个问题吗?
预先感谢,罗布
答案1
由于答案与配置相关,我做了一些假设。您必须调整答案以适应实际配置。
湾1的 LAN 和网关湾1任意选择为 84.114.7.0/24 和 84.114.7.254。
没有考虑防火墙规则,但所有这些都不应该与它们相互作用。
在 Linux 上ip link
,ip address
和ip route
应始终使用而不是已弃用的ifconfig
和route
。route
无论如何,可能无法处理额外的路由表。
只是作为一个提醒,iptables或者实际上网络过滤器,不路由,但它可以通过其操作更改 IP 路由堆栈做出的路由决策。这示意图显示路由决策可能发生的位置。对于仅在一个地方的路由(而不是本地发起)流量,并且更改必须在此之前发生:原始/预路由,mangle/预路由或者nat/预路由, 和生的通常不切实际,并且纳特仅适用于有限情况,大多数情况下会离开碾压。
A基本多宿主系统,要使用多个互联网路径,通常需要策略路由,其中路由不仅可以像往常一样随目的地而变化,还可以随源或策略规则中使用的其他选择器(如此处所做的那样)而变化。在 Linux 上,使用以下命令制定附加规则ip rule
可以选择不同的路由表来选择例如不同的默认路由(仍然只有一个默认路由,但是一个每个路由表)。
所以这里的原则是,同时仍然保持活跃严格反向路径转发(rp_过滤器), 是接受来自的数据包湾1并像往常一样将它们引导至以太网0使用备用表(这将允许通过rp_过滤器)。此附加路由表应复制主路由表,但仅使用备用路径所需的路由(湾1),因此不包括具有“正常”路径的常用路线(旺0)。如果流经的流量必须涉及其他路由(例如 VPN 等)湾1,很可能他们的路线也必须添加,或者必须创建其他额外的规则和表格来应对这种情况。
由于 Linux 在内核 3.6 中不再使用路由缓存,因此路由堆栈中没有任何内容会告诉您从主机1给客户通过湾1他们最终会使用主要的默认路线出去旺0, 对该接口使用错误的 IP 进行 NAT (网络过滤器与路由无关,并且在接收连接的第一个数据包时已经选择要完成的 NAT),并且可能被也执行严格反向路径过滤的 ISP 的下一个路由器丢弃。有一个网络过滤器允许在 conntrack 标记中复制数据包标记并将其放回数据包中的功能:这将充当连接的路由存储器。所以iptables和网络过滤器的连线将用于两个相关功能:标记数据包以更改路由决策,以及在标识为同一连接一部分的回复数据包上恢复此标记。
所有这些都转化为这些命令:
- 路由部分
对于标记的数据包(任意标记值 101)使用额外的路由表(不相关的任意值也是 101):
ip rule add fwmark 101 lookup 101
使用类似的条目填充表主要的路由表,减去旺0条目:
ip route add table 101 192.168.0.0/16 dev eth0
ip route add table 101 84.114.7.0/24 dev wan1
ip route add table 101 default via 84.114.7.254 dev wan1
- iptables/网络过滤器部分
以下命令有各种可能的优化,可能还可以改进。
恢复已保存的潜在先前标记,因此回复数据包将获得与原始数据包相同的标记:
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
标记来自以下位置的数据包湾1改变上面的路由决策:
iptables -t mangle -A PREROUTING -i wan1 -j MARK --set-mark 101
如果有标记,请将其保存在连线(本来可以在纳特表每个连接流只执行一次,而不是每个数据包):
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j CONNMARK --save-mark
实际上这仍然会失败严格反向路径转发检查,因为这未记录的功能于 2010 年添加。此处必须使用它:
sysctl -w net.ipv4.conf.wan1.src_valid_mark=1