我试图做到以下几点:我有一个服务监听虚拟接口(比如说172.16.0.1),udp端口5555的一个盒子。现在我想要做的是将接收到的数据包eth0 1.1.1.1:5555)和eth1(2.2.2.2:5555),然后将它们转发到虚拟接口上的服务,并且将回复返回到与客户端相同的物理接口的客户端。客户端必须认为他们正在与1.1.1.1:5555或2.2.2.2:5555。 我想我需要一个iptables规则和包标记的组合,加上一些iproute规则(如果可能的话)。 我尝试的是捕获来自eth0和eth1,udp端口5555的数据包,并分别用1和2标记,并在connmark中标记。 然后我用DNAT到172.16.0.1。 该服务似乎正在获取数据包。 现在我不知道如何做相反的事情。 看起来,对于从盒子发出的数据包,在路由决策之前你什么也做不了,但是这将是恢复标记的地方,从而根据这些数据做出路由决策。 以下是我到目前为止:
iptables -t mangle -A PREROUTING -d 1.1.1.1 -p udp --port 5555 -j MARK --set-mark 1 iptables -t mangle -A PREROUTING -d 2.2.2.2 -p udp --port 5555 -j MARK --set-mark 2 iptables -t mangle -A PREROUTING -d 1.1.1.1 -p udp --port 5555 -j CONNMARK --save-mark iptables -t mangle -A PREROUTING -d 2.2.2.2 -p udp --port 5555 -j CONNMARK --save-mark iptables -t nat -A PREROUTING -m mark --mark 1 -j DNAT --to-destination 172.16.0.1 iptables -t nat -A PREROUTING -m mark --mark 2 -j DNAT --to-destination 172.16.0.1 # What next?
正如我所说,我甚至不确定可以做到。 为了给出一些背景知识,这是一个旧的OpenVPN安装,不能升级(否则我会安装一个最新的版本,本地支持multihoming)。
谢谢你的帮助。
您是否尝试过使用直接NAT(通过REDIRECT目标)来执行此操作? Conntrack应该处理返回数据包,不需要手动标记。
我觉得我的工作起到了作用,以下是我在未来对其他人有用的情况下所做的工作:
iptables -t mangle -A PREROUTING -i eth0 -d 1.1.1.1 -p udp --dport 5555 -j MARK --set-mark 1 iptables -t mangle -A PREROUTING -i eth1 -d 2.2.2.2 -p udp --dport 5555 -j MARK --set-mark 2 iptables -t mangle -A PREROUTING -i eth0 -p udp --dport 5555 -j CONNMARK --save-mark iptables -t mangle -A PREROUTING -i eth1 -p udp --dport 5555 -j CONNMARK --save-mark # nat PREROUTING comes after mangle PREROUTING iptables -t nat -A PREROUTING -m mark --mark 1 -j DNAT --to-destination 172.16.0.1 iptables -t nat -A PREROUTING -m mark --mark 2 -j DNAT --to-destination 172.16.0.1 # restore mark from packets originating from 172.16.0.1, as it triggers a new routing decision iptables -t mangle -A OUTPUT -s 172.16.0.1 -p udp --sport 5555 -j CONNMARK --restore-mark ip rule add prio 20 fwmark 1 lookup upstream0 ip rule add prio 21 fwmark 2 lookup upstream1
OpenVPN仅绑定到172.16.0.1(分配给接口dummy0),并获取客户端发送到1.1.1.1:5555或2.2.2.2:5555的所有stream量。
我看不出有什么帮助:
通过将目标IP更改为传入接口的主地址,将数据包redirect到机器本身
传入数据包已经被定位到传入接口的地址(即1.1.1.1或2.2.2.2)。 或者,也许我不明白你的意思,在这种情况下道歉。
我忘了补充说,如果这个解决scheme看起来有点过分,那是因为我先尝试了一个更简单的方法,即让服务在0.0.0.0:5555上监听并使用数据包标记,但是我再也看不到在哪里为本地恢复标记生成的UDP数据包。
如果我切换到TCP,即使没有标记的需要,一切正常(不知道为什么); 当然,我仍然需要基于源代码的路由规则,但是它只是“正常工作”。 如果我无法使用UDP工作,我可能会切换到TCP(尽pipeTCP性能最差)。 我猜测为什么TCP工作,UDP不工作是因为UDP / IP数据包在触发路由决策时没有设置源地址集,所以地址在路由之后被“填充”,这将select默认路由,或多path组中的随机路由,并且不匹配原始传入接口(或者将会,但是只是偶然)。 另一方面,TCP / IP数据包到达路由阶段时已经有一个源地址(这是正确的),所以可以使用基于源的路由规则。 这只是一个猜测,如果有人发现一些错误,我很乐意纠正。
谢谢。