2

我们有许多用于转发连接的 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) 而不是丢弃它们。

欢迎评论,火焰,任何和所有的建议!

最好的问候,尼尔

4

2 回答 2

3

我猜你做到了,但为了确定,你是否将 eth0 添加到网桥?

虽然,我不确定问题是什么,但我会给出一些调试技巧,在调试 bridge/ebtables/iptables 问题时可能会对您或其他人有所帮助:

确保启用“/proc/sys/net/bridge/bridge-nf-call-iptables” (1)
这会导致桥接流量通过 netfilter iptables 代码。

请注意,这可能会影响性能。

通过 ebtabels/iptables 规则检查数据包拦截,
使用命令:

iptables -t nat -L -n -v   

ebtables -t nat -L –Lc  

这可能有助于您了解流量是否匹配和拦截。
检查 IP NAT 流量是否出现在 conntrack 表中:

conntrack –L (if installed)  

或者

cat /proc/net/nf_conntrack  

检查网桥的 MAC 学习

brctl showmacs br0  

在 eth0 和 br0 上使用 tcpdump 来检查是否在两者上都看到了预期
的数据包 使用 -e 选项也可以查看 MAC 地址。

为了调试,尝试将网桥接口置于混杂模式,可能网桥接收到不同MAC地址的数据包(在混杂模式下它也会接受不同的MAC)

也许将网桥转发延迟设置为 0

brctl setfd br0 0  

并禁用 stp(生成树协议)

brctl stp br0 off  

你的路由表是什么样的?
尝试使用“dev br0”添加特定或默认路由规则

我希望它有点帮助......<br>祝你好运

于 2013-06-19T08:35:49.777 回答
2

好吧,只有 1.5 岁,但可能对以后的查找有用。刚才查看您的链接,它明确表示,如果 MAC 在网桥的同一侧(而不是另一个端口或网桥本身(参见链接中的图 2.b),则路由将忽略数据包。

除此之外,我只是引用这个链接:http ://wiki.squid-cache.org/ConfigExamples/Intercept/LinuxBridge

“... ebtables DROP 与 iptables DROP

在大多数情况下用于过滤网络流量的 iptables 中,DROP 目标意味着“数据包消失”。

在 ebtables 中,“-j redirect --redirect-target DROP”表示“数据包从网桥进入内核的上层,例如路由\转发”(<-- 相关位!)

由于 ebtables 在连接的链路层工作以拦截连接,我们必须将流量“重定向”到 iptables 能够拦截的级别\tproxy。

其中就是你的答案(当然,除非你还在,p)

于 2015-01-05T22:47:31.343 回答