问题

问题

今天是路由日。阅读本文后,您应该已经了解如何添加 IP 路由、 的基本用法ip rule,并且对 有了很好的理解。iptables

这是交叉发布(法语)Linux操作系统

问题

我有一个桥接模式下的 ADSL 调制解调器 (Freebox) 和一个 DMZ 模式下的光纤 (Livebox)。除选定的流量外,所有流量都通过 ADSL 传输,另一个流量通过光纤通道传输。这是我的设置,在相反的情况下,问题仍然相同。

为了缓解这个问题,我将讨论通过运行 Debian GNU/Linux 的路由器的流量,而不是该路由器产生的流量。

我的 ADSL 地址是 82.236.xxx.xxx,光纤是 90.76.xxx.xxx。

应该怎么做

我们理所当然地认为mangle桌子是空的。

> ip route show table livebox
default via 192.168.1.1 dev eth_livebox src 192.168.1.253 
82.236.xxx.0/24 dev eth_adsl scope link src 82.236.xxx.xxx 
192.168.0.0/24 dev bridge_local scope link src 192.168.0.253 
192.168.1.0/24 dev eth_livebox scope link src 192.168.1.253 

iptables -t mangle -I PREROUTING --destination 23.23.114.123 -j MARK --set-mark 1
ip rule add from all fwmark 0x1 lookup livebox

这不起作用。这意味着当我这样做时

curl http://api.ipify.org/ --resolve api.ipify.org:80:23.23.114.123

从 LAN 客户端来看,没有返回任何内容。

什么有效

表格livebox没有变化。但是,刷新表格后mangle,我们用以下内容填充它:

iptables -t mangle -I PREROUTING --source 23.23.114.123 -j TOS --set-tos 0x10
iptables -t mangle -I PREROUTING --destination 23.23.114.123 -j TOS --set-tos 0x10
ip rule add from all tos 0x10 lookup livebox

进而 :

> curl http://api.ipify.org/ --resolve api.ipify.org:80:23.23.114.123
90.76.xxx.xxx

答案1

为什么?

在这两个片段之间,我改变了两件事:

  1. 我用的是服务条款IP 头而不是防火墙标记,由内核及其模块内部管理。
  2. 我标记了返回的包裹。

我撒了谎(省略):rp_filter

我忘了说,在所有接口上,都rp_filter设置为 1。根据内核文档,值 1 代表严格反向路径检查,定义在RFC 3704

总而言之,当数据包进入接口时,内核会交换IP 地址source字段destination,并尝试路由这个新的假数据包。如果所选路由通过数据包来源接口发出,则检查成功。否则,数据包将被丢弃。

因此,根据What should work,由于传入数据包未标记为1,因此严格反向路径检查失败。事实上,返回数据包通过eth_livebox,但没有标记,根据main表格路由,该表格表示通过eth_adsl。这是失败的。这是更改 2 的原因。

为什么是 TOS 而不是 MARK ?

是的,当然,我尝试过-j MARK返回数据包。但这不起作用。经过几个小时挖掘旧邮件列表消息后,我发现这个

好的,看看 fib_validate_source(),rp_filter 的工作方式似乎就是内核接收数据包,反转源地址和目标地址以及接口,然后尝试进行路由查找。它在构建路由密钥时完全忽略标记,但奇怪的是,它确实会检查 TOS。

好的。所以我阅读了一些有关 TOS 的文档,由于我仍在寻找解决方案,所以我快速而粗略地做了一下。它有效。这就是更改 2 的原因。

还有更好的吗?

我让你检查一下代码fib_validate_source()。说实话,它对我来说太重了。

但在我看来,结果是不一致的。我知道那TOS是在报头内部IP,防火墙标记特定于主机内部。另一方面ip ruleTOS有一个语法,可以使用 来在标头值或防火墙标记值上查找路由fwmark

我现在真正不知道应该做什么,以下是我的结论,非排他性的。

放弃rp_filter公共接口

的目标rp_filter是避免 DDoS,同时也过滤直接在我自己管理的网络中伪造数据包的恶意客户端。这有点像防晒指数,它可以保护其他参与者。

在我的公共接口上,我显然有一个像这样的路由条目default via IP,所以无论如何,rp_filter都会得出数据包可以应答的结论。事实上,如果数据包到达我的路由器,那是因为我的 ISP 让它通过了。他们设法路由了它。

所以我可以放弃并rp_filter在所有这些接口上将其设置为 0(警告:应用了 net.ipv4.conf.eth_livebox.rp_filter 和 net.ipv4.conf.all.rp_filter 之间的最大值)。

编辑:用户rpfilter来自iptables

LinuxFR 上的某个人引起了我的注意对此:该rp_filter控件已弃用,或至少处于废弃状态。确实有一个rpfilter模块对于iptables,这是它的未来。例如,从这里

iptables -A PREROUTING -t raw -m rpfilter --invert -j DROP
ip6tables -A PREROUTING -t raw -m rpfilter --invert -j DROP

它与防火墙很好地集成在一起,可以正常工作,并且返回的数据包甚至不需要标记,因为它们可以通过其状态识别。

向内核开发人员报告此“错误”

在我看来,这似乎非常不一致,而且记录非常糟糕。一方面,ip rule让你制定适用于传入数据包的规则,但不能适用于返回数据包:行为不当。

但我现在的情况是:我没有时间去熟练地阅读、理解并修复这段代码。我甚至不知道这是否有一个好的理由,比如在调用时防火墙标记可能不可用fib_validate_source

但是如果有人告诉我可以向关心的人报告,或者解释,甚至修复和改进,我会很乐意这样做。

rp_filter编辑:也许应该更新参数的文档……

相关内容