iptables:多WAN、端口转发和端口重定向

iptables:多WAN、端口转发和端口重定向

我正在运行 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 addressip route应始终使用而不是已弃用的ifconfigrouteroute无论如何,可能无法处理额外的路由表。

只是作为一个提醒,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

相关内容