【问题标题】:Is it possible to discard incoming packets based on (a dynamically changing set of) IP address(es) on Linux from C/C++ code?是否可以从 C/C++ 代码中丢弃基于 Linux 上(一组动态变化的)IP 地址的传入数据包?
【发布时间】:2012-10-20 14:34:46
【问题描述】:

我正在研究基于 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 一样)都没有打开的套接字,因此会生成 ICMP destination-unreachable 消息。

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

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

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

【问题讨论】:

    标签: c++ linux networking


    【解决方案1】:

    您可能想使用iptables 或使用libipqlibiptc 库。

    【讨论】:

    • +1。关于效率:将所有流量重定向到用户空间并返回进行检查可能仍然不如通过 iptables 调整内核 netfilter 效率。
    • 我对基于 netfilter.org/documentation/FAQ/netfilter-faq-4.html#ss4.5 的 libiptc 有点担心,但 libnetfilter_queue 似乎是我应该研究的一个有前途的方法。
    【解决方案2】:

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

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

    【讨论】:

    • 目前,我使用 SO_ATTACH_FILTER 和一个 PF_PACKET 套接字来注册一个 BPF 程序,它是一个非常简单的指令集的解释代码。 BPF 程序太低级了,不能允许更复杂的数据结构,甚至不可能向后跳转。然而,在 Bloom 过滤器中查找项目是计算哈希和在数组中索引的问题,这很简单,可以放入 BPF 程序中。如果过滤代码最终达到 C++ 级别,那么基数树可能是更好的解决方案。
    猜你喜欢
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 1970-01-01
    • 2019-10-30
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    相关资源
    最近更新 更多