iptables / ebtables / bridge-utils:通过单个NIC PREROUTING / FORWARD到另一个服务器

时间:2013-06-14 19:43:45

标签: iptables ebtables

我们有许多用于转发连接的iptables规则,这些规则很扎实并且运行良好。

例如,端口80转发到同一台计算机(网络服务器)上的端口8080。当给定的Web服务器重新启动时,我们将请求转发到端口8080上的另一个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是外部的,那么进入框中的任何流量似乎都会在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
echo 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
echo 1 > /proc/sys/net/ipv4/ip_forward

在更改为br0之前,客户端请求将在端口9080转到服务器A,然后MASQUERADED转到另一台服务器$ MAINTIP。

如上所述,如果$ MAINTIP在同一台机器上,这可以正常工作,但如果它在另一台服务器上,则在新的br0设置下,数据包永远不会发送到$ MAINTIP。

我们希望数据包与他们进入的相同接口MASQUERADED一样,就像我们切换到使用单NIC网桥(br0 / bridge-utils)之前一样。

我尝试在iptables的所有阶段添加日志记录。出于某种原因,iptables TRACE目标在此设置上不起作用,因此我无法获得TRACE日志,但数据包显示在PREROUTING表中,但在此之后似乎会默默地丢弃。

我已经阅读了这篇优秀的文档,并对iptables和ebtables之间的流程有了更好的理解: http://ebtables.sourceforge.net/br_fw_ia/br_fw_ia.html

根据我的理解,似乎网桥没有将数据包转发到它们所进入的相同接口,并且正在丢弃它们。如果我们添加了第二个接口,我想它会将它们转发到该接口(桥的另一侧) - 这就是桥的工作方式; - )

是否有可能按照我们想要的方式完成这项工作,并将这些数据包通过他们所使用的相同界面进行PREROUTE / FORWARD,就像我们以前一样?

我希望有一些ebtables规则可以与iptables PREROUTING / FORWARD / POSTROUTING规则一起使用,使iptables转发按照通常的方式工作,并将路由数据包发送到br0(eth0)而不是放弃它们。

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

最诚挚的问候, 尼尔

2 个答案:

答案 0 :(得分:0)

我猜你做到了,但是为了确定,你是否将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  

这可以帮助您了解流量是否匹配和截获 检查conntrack表中是否显示IP NAT流量:

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”

添加特定或默认路由规则

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

答案 1 :(得分:0)

只有1.5岁但可能对以后的查找有用。现在看一下你的链接,它特别指出,如果MAC位于网桥的同一侧(而不是另一个端口或网桥本身(见链路中的图2.b),则brouting将忽略该数据包。)

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

“... ebtables DROP vs iptables DROP

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

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

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

其中有你的答案(当然,为未来的访客增加了赌注,除非你还在,p)