方案一:ip规则

方案一:ip规则

我的系统有两个网络接口,它们都使用不同的 IP 地址连接到互联网。我希望对传入请求的响应通过接收它们的同一接口发送。

由于德国互联网提供商的性质,我的网络接口的公共 IP 地址每 24 小时更改一次。这是与类似问题的主要区别在与传入相同的界面上回复?,其响应均依赖于基于接口 IP 地址定义 IP 规则。

我可以配置一个 IP 规则,根据接口而不是其 IP 地址来选择路由表吗?到目前为止,我已经有但尚未成功应用的想法是使用iifoif选项或设置fwmarkusing iptables mangle。

答案1

感谢您在评论中提供的所有提示。基于它们,我提出了两种可能的解决方案。

方案一:ip规则

假设我有两个接口eth1eth2,并且eth1应该是用于传出连接的默认设备,我将定义第二个路由表,该路由表将使用eth2并设置一个 ip 规则,该规则使用此路由表来响应 上的传入请求eth2

iptables -t mangle -A INPUT -j CONNMARK -i eth2 --set-mark 2
iptables -t mangle -A OUTPUT -j CONNMARK -m connmark --mark 2 --restore-mark
ip route add 192.168.1.0/24 dev eth2 table 1234
ip route add default via 192.168.1.1 table 1234
ip rule add fwmark 2 lookup 1234

(对于 IPv6,请使用ip6tables和重复相同的操作ip -6。)

CONNMARK添加一个标记联系(包括响应)与 相对MARK,它为(传入)添加一个标记仅有的。该INPUT规则设置connmark传入的请求eth2及其响应。OUTPUTwith 规则会将--restore-mark复制connmark到 a 中mark,这是必要的,因为fwmarkip 规则的匹配器只匹配marks 而不是connmarks。

OUTPUT我添加的规则中-m connmark --mark 2,以确保仅为具有 of 的包设置connmark标记2。我添加这个是因为否则它会覆盖所有传出连接的标记,例如破坏依赖于其自身标记的 Wireguard。

路由连接

上述规则仅匹配eth2由机器本身处理的传入连接,但不匹配路由到另一台机器的连接。为了支持该用例,请使用以下附加规则:

iptables -t mangle -A PREROUTING -j CONNMARK -m connmark --mark 2 --restore-mark
iptables -t mangle -A PREROUTING -j CONNMARK -i eth2 --set-mark 2

第二条规则将标记通过 传入的每个数据包eth2,而第一个规则将匹配其的每个数据包联系已经有一个 connmark2并将复制该标记联系(确保对最初传入的数据包的响应eth2也被标记)。

为此,1234还需要将路线目的地添加到表中!

解决方案 2:ip 命名空间

通过此解决方案,两个网络接口将完全彼此分离。每个进程将被分配给其中一个命名空间,因此只能看到两个网络接口之一。这意味着应该通过两个网络接口(例如 ssh)访问的服务需要启动两次,每个命名空间一次。由于进程和网络接口彼此严格分开,因此响应会自动通过正确的接口发送。据我了解,这甚至意味着当我通过一个特定网络接口 SSH 到计算机上时,我从该 SSH 会话发起的任何传出网络请求将始终使用同一网络接口。

我还没有尝试过这个解决方案,因为它对于我的用例来说并不是很完美,但是从我可以在网上找到的信息来看,它应该配置如下:

ip netns add net2
ip link set eth2 netns net2

net2然后,您可以使用运行命名空间范围内的任何命令ip netns exec net2 <command>。任何配置或使用网络接口的 DHCP 客户端或其他软件都必须以这种方式启动。在我看来,不同 Linux 发行版的网络配置解决方案之间还没有对命名空间的广泛支持,因此可能需要一些手动脚本才能使其正常工作。

相关内容