5

我正在研究基于 Linux 机器上的 IP 地址过滤传入 UDP 流量的可能性,完全丢弃与任何过滤器地址匹配的数据包。我感兴趣的 IP 地址集是动态(并且经常)变化的,并且是先验未知的。被认为被丢弃的数据包应该跳过所有进一步的处理。我可以向进程授予 CAP_NET_RAW 功能,但不想编写自己的驱动程序或修改内核。

背景资料

我用来紧凑地表示大量 IP 地址的实用方法是布隆过滤器。这种方法已经被作为设备驱动程序实现的动态数据包过滤方法使用:

http://luca.ntop.org/Blooms.pdf

但是,我有用户级代码,无法调整内核或编写自己的设备驱动程序。

同样,我已经有了一个解决方案,它可以基于 PF_PACKET 套接字和 RX_RING 以有效的方式基于 IP 地址嗅探数据包,就像在 netsniff-ng 中所做的那样:

http://netsniff-ng.org/

我的方法是扩展 netsniff(或 tcpdump 或 Wireshark)中的捕获机制,使用 Bloom 过滤器原理进行扩展,以获得更紧凑的 Berkeley Packet Filter (BPF) 程序。这非常有效,但副作用是即使过滤器丢弃了数据包(因此它不会出现在 RX_RING 中),它仍然会在内核中继续它的旅程。最终,如果接收到的大部分过滤流量(大部分是合成的,就像 netsniff 的 trafgen 一样)没有打开的套接字,就会destination-unreachable生成 ICMP 消息。

以不同方式提出的问题是,在网络堆栈处理的早期阶段,是否存在基于自定义代码(例如,使用 Bloom 过滤器)有选择地丢弃流量的 C/C++ 方法?

我已经查看了基于 iptables 的方法,但是通过 iptables-restore 管理防火墙规则对于该场景来说似乎太麻烦了。此外,这些地址不是连续的 IP 地址集,因此会导致一长串要测试的单独地址。

由于涉及的流量很大,效率是一个关键方面。

4

2 回答 2

3

您可能想尝试iptables使用libipqlibiptc库。

于 2012-10-20T14:38:29.133 回答
0

这个答案不会为有选择地丢弃流量提供太多帮助,但是您可以考虑使用Patricia trie(基数树)来表示和查找 IP 地址,而不是 Bloom 过滤器?在工作中,我们必须存储和查找大量动态 IP 地址和范围,并且发现 Patricia trie 是最有效的。

顺便说一句,我尝试加载 Bloom 链接,但它不会为我加载。

于 2012-10-20T15:35:58.757 回答