与使用DNATed IP的传入相同的接口回复

一个服务器在不同的公共networking中有3个ifaces,2个内部(eth1 / 2),一个外部(eth0)。

有一个服务(openvpn)不能绑定到一些IP / ifaces,只有全部或一个,但我需要它只接受连接(UDP)的内部ifaces。 默认的gw是通过外部的。

我有一个工作的设置与服务的两个实例绑定到每个内部iface的IP和iproute2路由集( ip route add xxx table xip rule add from <IP> table x )。

是否有可能将第二个内部iface(eth2)上的传入连接DNAT到第一个内部iface(eth1)的IP并通过相同接口(eth2)进行响应? 在这种情况下,不需要运行服务的第二个实例,并保持2个相同的configuration,只需要监听IP的不同。

问题是,如果我(使用DNAT)将eth2上的传入连接的目标IP更改为eth1的IP,则基于from <IP>的IP规则将不起作用。 或者,更好地说,它将使服务通过eth1而不是eth2使用eth1的默认gw来回答。

是否有可能对DNATed“会话”(UDP)的所有传出数据包进行高效设置标记,所以我可以在ip规则中使用fwmark? 任何其他解决scheme的主要问题?

find了解决办法。 这个解决scheme应该适用于任何不能侦听特定接口的linux服务,但只能在所有的(0.0.0.0)或者特定的,如MySQL,OpenVPN和其他的。 因此,我们使服务监听一个iface,并添加netfilter / iproute2规则,以将另一个iface上的相同协议和端口的所有请求redirect到我们在第一个iface上的服务。

“会话”(尽pipe在OpenVPN的情况下是UDP)实际上是由netfilter维护的,并且有一个模块conntrack允许引用来自特定会话的数据包。 在这种情况下,我在mangle表中为OUTPUT添加了一个规则,用标记标记来自DNATed会话的所有数据包。 然后我使用这个标记来路由数据包。

所以,这些命令是:

定义variables

 iface_int2=eth2 # the second internal iface ip_int2=xx.xx.xx.xx # the IP of the second internal iface proto=udp # the protocol of the connection service_port=1194 # the incoming service port ip_int1=yy.yy.yy.yy # the IP of the first internal iface ip_gw2=xx.xx.xx.1 # the IP of the default gateway for the second internal iface 

这个命令指示netfilter在第二个iface上覆盖传入连接的目标IP地址。

 iptables -t nat -A PREROUTING -i $iface_int2 -d $ip_int2 -p $proto --dport \ $service_port -j DNAT --to $ip_int1 

这个命令指示netfilter为被覆盖的(DNATed)传入连接的传出数据包(服务的回复)设置标记。 --ctorigdst是传入连接的原始(预先DNATed)目标IP

 iptables -t mangle -A OUTPUT -p $proto --sport $service_port -m conntrack \ --ctstate DNAT --ctorigdst $ip_int2 -j MARK --set-mark 0x75 

这个命令指示iproute2通过表100的路由定义来路由设置标记的分组。因为它是非常具体的并且不会干扰其他规则,所以必须为该规则设置最高优先级。 如果没有指定prio,则第一个内部iface的路由规则可能会获得更高的优先级。

 ip rule add prio 10 fwmark 0x75 table 100 

该命令将默认网关添加到表100

 ip route add default via $ip_gw2 table 100 

为了所有这些工作,有必要减less返回pathfilter对第二个内部事件的控制。

 # rp_filter - INTEGER # 0 - No source validation. # 1 - Strict mode as defined in RFC3704 Strict Reverse Path # Each incoming packet is tested against the FIB and if the interface # is not the best reverse path the packet check will fail. # By default failed packets are discarded. # 2 - Loose mode as defined in RFC3704 Loose Reverse Path # Each incoming packet's source address is also tested against the FIB # and if the source address is not reachable via any interface # the packet check will fail. echo 2 > /proc/sys/net/ipv4/conf/$iface_int2/rp_filter # -OR- sysctl -w "net.ipv4.conf.$iface_int2.rp_filter=2" # -OR- echo "net.ipv4.conf.$iface_int2.rp_filter=2" >> /etc/sysctl.conf sysctl -p /etc/sysctl.conf