通过特定接口路由特定端口上的流量?

通过特定接口路由特定端口上的流量?

我当前运行的系统需要能够直接发送和接收 HTTP 和 HTTPS 流量,但所有其他流量必须通过 VPN。

我的设置是:

x2 接口:eth0(本地网络,路由器后面)和 tun0(openvpn 客户端)

目前所有流量都通过我的 VPN 路由,我想知道是否可以不是通过 VPN 路由 http 和 https 流量 (80、443)。

这是系统和 openvpn 客户端启动时的路由表:

0.0.0.0/1 via 10.8.13.5 dev tun0 
default via 192.168.1.1 dev eth0 
10.8.13.1 via 10.8.13.5 dev tun0 
10.8.13.5 dev tun0 proto kernel scope link src 10.8.13.6 
128.0.0.0/1 via 10.8.13.5 dev tun0 
176.67.168.144 via 192.168.1.1 dev eth0 
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.56 
192.168.1.1 dev eth0 scope link 

我已经阅读了其他类似的问题,但是答案要么不会重新路由流量,要么只是阻止它。

提前致谢 :)

答案1

路由位于 IP 第 3 层。TCP 位于第 4 层,因此仅靠路由不足以解决此问题。

简而言之:有趣的流量必须是标记为iptables,并用选择的标记数据包ip rule使用fwmark单独的路由表。然后,必须对本地发起/接收流量情况应用另外两个修复,这比路由情况更困难。当然,所有设置都是在本地系统上完成的。

路由表80(可以添加匹配的符号名称,/etc/iproute2/rt_tables但这不是强制性的)和标记0x80是“任意”选择的。

ip route add table 80 192.168.1.0/24 dev eth0 scope link src 192.168.1.56
ip route add table 80 default dev eth0 via 192.168.1.1

用于-I确保 iptables 规则不会附加得太晚。您应该根据当前的规则检查如何在需要时重新排序:

iptables -t mangle -N markports
iptables -t mangle -I PREROUTING 1 -j CONNMARK --restore-mark
iptables -t mangle -I OUTPUT 1 -m mark --mark 0 -j markports
iptables -t mangle -I OUTPUT 2 -j CONNMARK --save-mark
iptables -t mangle -A markports -p tcp --dport 80 -j MARK --set-mark 0x80
iptables -t mangle -A markports -p tcp --dport 443 -j MARK --set-mark 0x80

ip rule add fwmark 0x80 lookup 80

这个博客:Netfilter Connmark » Linux 及更高版本!提供有关 的良好信息CONNMARK

这应该是有效的,但实际上在第一次路由决策时会选择错误的默认传出 IP,因为该路由即将通过tun0。由于 的标记而进行的重新路由检查mangle/OUTPUT(请参阅此Netfilter 和通用网络示意图中的数据包流为了澄清),这个IP不会改变。如果处理的流量是路由的而不是本地启动的,则不会发生此问题(使用单独的网络命名空间来确保这是服务的解决方案,可能不适用于桌面)。所以这还需要在它上面一层MASQUERADE(或者对于更复杂的情况):SNAT

iptables -t nat -I POSTROUTING 1 -m mark --mark 0x80 -j MASQUERADE

现在传出源 IP 是正确的,但它仍然不起作用:反向路径过滤器出于大约相同的原因,在返回路径中触发:之前做出的路由决策暂时PREROUTING不知道fwmark(尽管之前的原理图放置mangle/PREROUTING在路由决策之前,显然情况并非如此),因此认为返回流量数据包被欺骗并提前丢弃它们。接口eth0rp_filter必须置于松散模式才能允许这样做。这可能会产生一些(NAT 后面非常小的)安全问题,但我发现对于这种非路由情况来说这是不可避免的:

echo 2 > /proc/sys/net/ipv4/conf/eth0/rp_filter

您必须找到如何永久设置它(例如,echo net.ipv4.conf.eth0.rp_filter=2 > /etc/sysctl.d/90-local-loose-mode.conf如果以后没有其他东西改变它)。

使用具有与 OP 类似设置的命名空间进行测试,结果正常。

注意:DNS 请求仍将通过隧道。某些地理本地化 Web 服务可能无法按预期工作。

相关内容