我们有许多用于转发连接的 iptables 规则,这些规则可靠且运行良好。
例如,端口 80 转发到同一台机器(网络服务器)上的端口 8080。当给定的网络服务器重新启动时,我们将请求转发到端口 8080 上的另一个 IP,该 IP 显示维护页面。在大多数情况下,此其他 IP 位于单独的服务器上。
在我们安装了 bridge-utils 并更改为使用网桥 br0 而不是 eth0 作为接口之前,这一切都运行良好。
我们转为使用网桥接口的原因是为了访问 ebtables 的 MAC SNAT/DNAT 功能。我们没有其他理由在服务器上添加桥接接口,因为它们实际上并没有桥接多个接口上的连接。
我知道在服务器上添加网桥是一个奇怪的原因,但是我们在一个新项目中使用 MAC SNAT/DNAT 功能,并且 ebtables 似乎是最安全、最快和最简单的方法,因为我们已经如此熟悉iptables。
问题是,由于转换为 br0 接口,iptables PREROUTING 转发到外部服务器不再起作用。
内部 PREROUTING 转发工作正常(例如:请求进入端口 80,它转发到端口 8080)。
OUTPUT 链也可以工作(例如:我们可以通过本地目标 IP:8080 从盒子向外连接,OUTPUT 链将其映射到不同服务器上的维护服务器 IP,端口 8080,并返回一个网页)。
但是,如果目标 IP 是外部 IP,则在 PREROUTING 规则之后进入该框的任何流量似乎都会消失。
这是我们的设置示例:
旧设置:
iptables -t nat -A PREROUTING -p tcp --dport 9080 -j DNAT --to-destination $MAINTIP:8080 iptables -a FORWARD --in-interface eth0 -j ACCEPT iptables -t nat -A POSTROUTING --out-interface eth0 -j MASQUERADE 回声 1 > /proc/sys/net/ipv4/ip_forward
新设置:(也尝试了各种格式的旧设置...,尝试记录 eth0 和 br0 数据包)
iptables -t nat -A PREROUTING -p tcp --dport 9080 -j DNAT --to-destination $MAINTIP:8080 iptables -a FORWARD --in-interface br0 -j ACCEPT iptables -t nat -A POSTROUTING --out-interface br0 -j MASQUERADE 回声 1 > /proc/sys/net/ipv4/ip_forward
在更改为 br0 之前,客户端请求将转到端口 9080 的服务器 A,然后被伪装到另一个服务器 $MAINTIP。
如上所述,如果 $MAINTIP 在同一台机器上,这可以正常工作,但如果它在另一台服务器上,则数据包永远不会在新的 br0 设置下发送到 $MAINTIP。
我们希望数据包从它们进来的同一个接口(伪装)出去,就像在我们切换到使用单 NIC 网桥 (br0/bridge-utils) 之前所做的那样。
我尝试在 iptables 的所有阶段添加日志记录。由于某种原因,iptables TRACE 目标在此设置上不起作用,所以我无法获得 TRACE 日志,但数据包显示在 PREROUTING 表中,但之后似乎被静默丢弃。
我已经阅读了这份出色的文档,并且对 iptables 和 ebtables 之间的流程有了更好的理解:http: //ebtables.sourceforge.net/br_fw_ia/br_fw_ia.html
据我了解,网桥似乎没有将数据包转发到它们进入的同一接口,而是丢弃它们。如果我们添加了第二个接口,我想它会将它们转发到该接口(桥的另一侧) - 这就是桥的工作方式;-)
是否有可能按照我们想要的方式进行这项工作,并像我们以前一样通过它们进入的同一接口预路由/转发这些数据包?
我希望有一些 ebtables 规则可以与 iptables PREROUTING/FORWARD/POSTROUTING 规则结合使用,以使 iptables 转发以通常的方式工作,并将路由数据包发送到 br0 (eth0) 而不是丢弃它们。
欢迎评论,火焰,任何和所有的建议!
最好的问候,尼尔