我正在研究根据Linux机器上的IP地址过滤传入UDPstream量的可能性,丢弃完全匹配任何filter地址的数据包。 我感兴趣的一组IP地址是dynamic的(并且经常)改变,并且不是先验的。 被视为丢弃的数据包应该跳过所有进一步的处理。 我可以授予进程的CAP_NET_RAW能力,但不想编写自己的驱动程序或修改内核。
我使用的一种实用方法来紧凑地表示一组大量的IP地址,它是一个布隆filter。 这种方法已经被作为设备驱动程序实现的dynamic数据包过滤方法所使用:
http://luca.ntop.org/Blooms.pdf
但是,我有用户级代码,无法调整内核或编写自己的设备驱动程序。
同样,我已经有了一个解决scheme,它基于一个PF_PACKET套接字和一个RX_RING,以一种有效的方式基于IP地址嗅探数据包,就像在netsniff-ng中所做的那样:
http://netsniff-ng.org/
我的方法是扩展netsniff(或tcpdump或Wireshark)中的捕获机制,以Bloomfilter原理扩展,以获得更紧凑的伯克利包filter(BPF)程序。 这个效果很好,但是有副作用,即使filter丢弃数据包(因此它不会出现在RX_RING中),它仍然继续在内核中的行程。 最终,由于接收到的大部分过滤stream量(大部分是合成的,就像通过netsniff的trafgen)没有开放的套接字,所以会生成ICMP destination-unreachable
消息。
以不同的方式提出的问题是,在networking堆栈处理的早期阶段,是否有C / C ++方法来select性地丢弃基于自定义代码的stream量(例如,使用布隆filter)?
我已经看过基于iptables的方法,但通过iptables-restorepipe理防火墙规则似乎太麻烦的情况。 另外,这些地址不是连续的IP地址集,因此会导致一长串单独的地址进行testing。
由于所涉及的交通量很大,效率是一个关键的方面。
你可能想使用libipq
和libiptc
库来玩iptables
。
这个答案不会提供有关选择性地丢弃流量的很多帮助,但是可以考虑使用Patricia trie (基数树)进行IP地址表示和查找,而不是布隆过滤器。 在工作中,我们必须存储和查找大量的动态IP地址和范围,并且发现Patricia trie是最有效的。
顺便说一句,我试图加载布卢姆链接,它不会加载我。