在与传入相同的接口上回复?

Sha*_*off 71 linux routing iptables

我有一个有两个接口的系统。两个接口都连接到互联网。其中之一设置为默认路由;这样做的副作用是,如果数据包进入非默认路由接口,则回复将通过默认路由接口发回。有没有办法使用 iptables(或其他东西)来跟踪连接并通过它来自的接口发回回复?

小智 79

echo 200 isp2 >> /etc/iproute2/rt_tables
ip rule add from <interface_IP> table isp2 prio 1
ip route add default via <gateway_IP> dev <interface> table isp2
Run Code Online (Sandbox Code Playgroud)

以上不需要使用 ipfilter 进行任何数据包标记。它起作用是因为传出(回复)数据包将具有最初用于连接到第二个接口的 IP 地址作为传出数据包的源(来自)地址。

  • 对我来说,只有当我在 `ip rule` 命令中省略 `dev` 参数时它才起作用,所以运行 `ip rule add from &lt;interface_IP&gt; table isp2` (26认同)
  • 哇,这正是我要找的。如果有人正在寻找基于 RH 的发行版,您可以将相关的规则和路由命令放在名为“rule-eth0”或“route-eth0”(例如)的文件中,这些文件将在 ifup/ifdown 上添加或删除。将这些文件放在 ifcfg-eth0 文件旁边。对于 IPv6,有内置的“route6-eth0”功能,但没有内置“rule6-eth0”(还)。 (7认同)
  • 我必须从 `ip rule` 中删除 `dev &lt;interface&gt;` 才能让它在我的机器上工作。如果我理解正确的话,`dev &lt;interface&gt;` 正在过滤掉以某种方式设置在错误接口上的数据包,这些数据包需要通过覆盖的路由转移到正确的接口,但按接口过滤的规则阻止了这种情况的发生. (6认同)
  • 您可以通过将 `up ip rule add from &lt;interface_IP&gt; table isp2` 和 `up ip route add default via &lt;gateway_IP&gt; dev ppp0 table isp2` 添加到 /etc/network/interfaces 下,在接口上升时创建这些相关接口。 (2认同)
  • 像大多数其他人一样,我必须从 `ip rule` 命令中删除 `dev &lt;interface&gt;` 才能使其正常工作。请更新答案!除了那个细节,它就像一个魅力。非常感谢,@彼得! (2认同)
  • 对于最近读到这篇文章的人来说,每个人都在谈论的“dev &lt;interface&gt;”已经被删除了——有问题的是“rule”行上的“dev &lt;interface&gt;”,而不是“route”上的“dev &lt;interface&gt;”。线(尽管我不相信其中任何一个是必要的)。 (2认同)

Gil*_*il' 9

以下命令通过eth1为具有标记 1 的数据包(到 localhost 的数据包除外)创建备用路由表。该ip命令来自iproute2套件(Ubuntu:iproute 安装 iproute http://bit.ly/software-smalliproute-doc 安装 iproute-doc http://bit.ly/software-small)。

ip rule add fwmark 1 table 1
ip route add 127.0.0.0/0 table 1 dev lo
ip route add 0.0.0.0/0 table 1 dev eth1
Run Code Online (Sandbox Code Playgroud)

另一半工作是识别必须获得标记 1 的数据包;然后使用iptables -t mangle -A OUTPUT … -j MARK --set-mark 1这些数据包让它们通过路由表 1 路由。我认为以下应该这样做(用非默认路由接口的地址替换 1.2.3.4):

iptables -t mangle -A OUTPUT -m conntrack --ctorigdst 1.2.3.4 -j MARK --set-mark 1
Run Code Online (Sandbox Code Playgroud)

我不确定这是否足够,也许传入数据包需要另一个规则来告诉 conntrack 模块跟踪它们。


小智 7

我在使用 Peter 建议的解决方案本地生成的数据包时遇到了问题,我发现以下更正了:

echo 200 isp2 >> /etc/iproute2/rt_tables
ip rule add from <interface_IP> table isp2 priority 900
ip rule add from dev <interface> table isp2 priority 1000
ip route add default via <gateway_IP> dev <interface> table isp2
ip route add <interface_prefix> dev <interface> proto static scope link src <interface_IP> table isp2
Run Code Online (Sandbox Code Playgroud)

注意:您可能会遇到上面第 4 行的语法问题。在这种情况下,第四个命令的语法现在可能是这样的:

ip rule add iif <interface> table isp2 priority 1000
Run Code Online (Sandbox Code Playgroud)


zaT*_*cky 6

我假设您正在运行 Linux,而且您正在使用基于 RedHat/CentOS 的发行版。其他 Unix 和发行版将需要类似的步骤 - 但细节会有所不同。


从测试开始(请注意,这与@Peter 的回答非常相似。我假设如下:

  • eno0 是 isp0 并且具有整体默认网关
  • eno1 是 isp1,IP/范围为 192.168.1.2/24,网关为 192.168.1.1

命令如下:

$ echo 200 isp1 >> /etc/iproute2/rt_tables
$ ip rule add from eno1 table isp1
$ ip route add default via 192.168.1.1 dev eno1 table isp1
Run Code Online (Sandbox Code Playgroud)

防火墙不以任何方式参与。回复数据包总是从正确的 IP 发送 - 但以前是通过错误的接口发送的。现在这些来自正确 IP 的数据包将通过正确的接口发送。


假设上述操作有效,您现在可以永久更改规则和路由。这取决于您使用的 Unix 版本。和以前一样,我假设一个基于 RH/CentOS 的 Linux 发行版。

$ echo "from eno1 table isp1" > /etc/sysconfig/network-scripts/rule-eno1
$ echo "default via 192.168.1.1 dev eno1 table isp1" > /etc/sysconfig/network-scripts/route-eno1
Run Code Online (Sandbox Code Playgroud)

测试网络更改是否是永久性的:

$ ifdown eno1 ; ifup eno1
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,在更高版本的 RH/CentOS 上,您还需要使用以下两个选项之一:

  1. 不要使用默认的NetworkManager.service;请改用network.service。我还没有探索这所需的确切步骤。我想它涉及标准的chkconfigsystemctl命令来启用/禁用服务。

或者

  1. 安装 NetworkManager-dispatcher-routing-rules 包

我个人更喜欢安装规则包,因为它是更简单、更受支持的方法:

$ yum install NetworkManager-dispatcher-routing-rules
Run Code Online (Sandbox Code Playgroud)

另一个强烈建议是启用 arp 过滤,因为这可以防止与双网络配置相关的其他问题。对于 RH/CentOS,将以下内容添加到 /etc/sysctl.conf 文件中:

net.ipv4.conf.default.arp_filter=1
net.ipv4.conf.all.arp_filter=1
Run Code Online (Sandbox Code Playgroud)