我正在尝试解决ESP数据包碎片化的问题,因为在添加ESP标头后,超出了MTU大小。解决方案(每个人都这样做)是在进行ESP加密之前进行分段。
我的问题是,如果它非常有用,为什么Linux IPSec实现本身不支持它。我知道L4流量选择器不会起作用的某些限制。但并非每个人都能利用它。
此外,如果您可以分享关于添加此支持的最佳方式的指示,那将非常有帮助。
感谢。
答案 0 :(得分:1)
为了完成这个圈子(并希望帮助那些可能正在寻找类似解决方案的人),我们通过使用libnetfilter_queue解决了我们的问题。我们面临的挑战是,我们无法访问应用程序的源代码,否则我们就可以在应用程序级别完成碎片化。
这里是 Sriram Dharwadkar 编写的内部文件的相关摘录,他们也做了实施。一些参考文献是我们的内部应用程序名称,但不要认为您在理解方面应该有任何问题。
NetFilter队列是用户空间库,提供API来处理已由内核数据包过滤器排队的数据包。 愿意使用此功能的应用程序应链接到 netfilter_queue & nfnetlink 动态地包含来自sysroot-target / usr / include / libnetfilter_queue /的必要标头 SYSROOT目标的/ usr /包括/ libnfnetlink /。 需要添加以NFQUEUE作为目标的Iptables。 NFQUEUE是一个iptables和ip6tables目标,它将数据包的决策委托给用户空间软件。例如,以下规则将要求对所有排队的数据包的侦听用户空间程序做出决定。
iptables -A INPUT -j NFQUEUE --queue-num 0
在用户空间中,软件必须使用libnetfilter_queue apis连接到队列0(默认值)并从内核获取消息。然后必须对数据包作出判决 当数据包到达NFQUEUE目标时,它将被添加到与--queue-num选项给出的数字对应的队列中。数据包队列实现为链式列表,其中元素是数据包和元数据(Linux内核skb):
预碎片化逻辑在AvPreFragApp(新应用程序)和安全代理(现有控制器应用程序)中实现。
在安全代理中,一旦隧道建立。以下两条规则被添加到RAW表中。
用于TCP预碎片化:
/ usr / sbin / iptables -t raw -I OUTPUT 1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360
以上规则在三手握手期间协商适当的MSS尺寸。 可以安全地假设,1360 + TCPH + IPH + ESP + IPH <= 1500,因此在加密碎片后不会发生。
用于UDP预碎片:
/ usr / sbin / iptables -t raw -I OUTPUT 2 -s&lt; tia&gt; -p udp -m mark! --mark 0xbeef0000 / 0xffff0000 -j NFQUEUE
上面的规则将所有带有src ip的udp数据包排队为TIA(隧道地址),并将不等于0xbeef0000的数据队列到要由应用程序处理的netfilter队列。在排队的所有udp数据包上,将由AvPreFragApp标记0xbeef0000。这样做是为了避免重复排队。
AvPreFragApp应用程序使用netfilter队列来处理由NFQUEUE目标排队的数据包。 如上所述,iptables规则将具有TIA的udp数据包排队,因为src ip被添加到安全代理中。此规则在隧道建立时添加,并在隧道反弹时使用新TIA进行更新。因此,所有使用TIA作为源IP的数据包都排队等待AvPreFragApp进行处理。
注意:TIA:隧道内部地址,逻辑IPSec接口。