Linux内核社区最近发布了bpfilter,它将用LinuxBPF支持的高性能网络过滤替代iptables的长期内核实现,同时保证Linux用户的无中断过渡。
作为tcpdump和Wireshark等流行工具的包过滤功能,BPF已经发展成为一个丰富的框架,以高度灵活的方式扩展Linux的功能,而不会牺牲性能和安全等关键属性。这种强大的组合让谷歌,Facebook和Netflix等Linux内核技术的前瞻性用户能够选择BPF用于从网络安全性,负载平衡到性能监控和故障排除等多种用途。Netflix的BrendanGregg首先称为BPFSuperpowers对于Linux。本文将介绍这些“超级大国”如何使像iptables这样的长期内核子系统变得冗余,同时实现几乎没有人想象过的新的内核用例。
在过去的15年中,Linux内核社区创作代码花费了很多子系统,包括TCP/IP协议栈,iptables等等,使我能够近距离观察BPF的发展。我很快意识到BPF不仅仅是另一个功能,而是代表了一个基本的技术转变,它将及时改变Linux中的网络和安全的各个方面。我开始贡献自己的力量,并成为其最大的支持者之一,他们与阿列克谢Starovoitov和DanielBorkmann一起,现在正在维护BPF上游。在这个镜头中,从bptables到bpfilter的转变只是BPF为振兴现代领域Linux网络栈的旅程中的下一个合理步骤。为了理解为什么这个转变如此激动人心,请允许我介绍一下内核中iptables的历史。
iptables和顺序过滤的根源
多年来,iptables一直是在Linux上实现防火墙和数据包过滤器的主要工具。从早期开始,iptables及其前身ipchains就成为了我个人Linux旅程的一部分。最初作为一个用户,稍后作为内核开发者。多年来,iptables一直是一个祝福和诅咒:它的灵活性和快速修复的祝福。在调试5K规则时,一个诅咒规定了在多个系统组件争夺谁安装iptables规则的环境中的iptables设置。
当iptables在20年前开始其生命周期以取代其前身ipchains时,防火墙功能的写作范围很简单:
保护本地应用程序免受不必要的网络通信(INPUT链)
保护本地应用程序发送不需要的网络流量(OUTPUT链)
过滤由Linux系统(FORWARD链)转发/路由的网络流量。
那时,网络速度很慢。记得拨号时调制解调器发出的声音?那是iptables最初被开发和设计的时代。由iptables实现访问控制列表(ACL)的标准做法是使用连续的规则列表,即每个接收或发送的数据包都会逐一匹配规则列表。
然而,线性处理有明显的巨大缺点,过滤数据包的成本可随着添加的规则数量线性增加。
中间解决方法:ipset
一段时间过去了,网络速度提高了,iptables设置已经从十几条规则发展到数千条规则。从性能和延迟角度来看,遍历顺序的iptables列表已经变得无法忍受。
社区很快发现了最常见的瓶颈:长长的规则列表要么拒绝要么允许单独的IP地址和端口组合。这导致了ipset的引入。ipset允许将与IP地址和/或端口组合匹配的规则列表压缩到散列表中,以减少整体iptables规则的数量。这一直是解决核心问题本身的解决方法。
不幸的是,ipset不是解决所有问题的答案。一个突出的例子是kube-proxy,Kubernetes的一个组件使用iptables和-jDNAT规则为服务提供负载平衡。它为服务所服务的每个后端安装多个iptables规则。对于添加到Kubernetes的每个服务,要遍历的iptables规则列表呈指数增长。
最近的KubeCon谈话详细研究了kube-proxy的表现。谈话呈现的测量结果显示随着服务数量的增长,无法预测的延迟和性能下降。它还揭示了iptables的另一个主要弱点:缺乏增量更新。每次添加新规则时,必须更换整个规则列表。这导致总共需要5个小时才能安装代表20KKubernetes服务的160Kiptables规则。
使用基于IP/端口的机制通常具有许多其他明显的缺点,特别是在应用容器时代。容器经常部署和拆除。这可能导致个别IP地址的使用寿命缩短。一个IP地址可能被一个容器使用了几秒钟,然后在几秒钟之后被另一个容器重新使用。这使得依靠使用IP地址进行安全过滤的系统受到压力,因为群集中的所有节点都必须始终了解最新的IP到容器映射。虽然在集群内这几乎没有困难,但它在整个集群中变得非常具有挑战性。潜入细节超出了本博文的范围,因此我们将其保存在未来的博文中。
BPF的兴起
近年来,BPF一直以疯狂的速度发展,解开了以前不在内核范围之内的东西。BPF提供的令人难以置信的强大和高效的可编程性使这成为可能。以前需要自定义内核开发和内核重新编译的任务现在可以通过BPF沙箱安全边界内的高效BPF程序来实现。
以下是项目清单,展示了BPF如何在各种项目和公司中得到利用:
Facebook已经推出了令人兴奋的基于BPF / XDP的负载平衡工作,以取代 也包含DDoS缓解逻辑的IPVS。尽管与iptables相比,IPVS是一个诱人的下一步,但Facebook在性能提高了大约10倍后,已经从IPVS转移到BPF。 Netflix,特别是Brendan Gregg,一直利用BPF的功能进行性能分析和跟踪。该BCC项目提供用户访问BPF的权力,例如,产生惊人的flamegraphs:
- Google一直在研究bpfd,它可以使用eBPF实现强大的Linux跟踪远程目标。基于BPF的上游参与,他们似乎也在考虑将各种内部项目迁移到BPF。
- Cloudflare正在使用BPF来缓解DDoS攻击 ,并发布了多篇博文,并就该主题发表了多次公开演讲。
- Suricata是一个IDS,它开始使用BPF和XDP来取代nfqueue,这是一个基于iptables的基础设施来监听数据包。更多细节可以在这个Kernel Recipes的演讲中找到。
- Open vSwitch一直致力于使用 eBPF驱动的数据路径。
一个BPF来统治他们BPF发展的最新进展是令人兴奋的提议,即以对用户完全透明的方式用BPF完全替换iptables的内核部分,即现有iptables客户端二进制文件和库将继续工作。 Quentin Monnet在FRnOG 30上提供的以下图表显示了与iptables和nftables相比较bpfilter的一些早期测量结果。它显示了仅软件BPF实现以及硬件卸载测试:
这些早期的性能数据是令人难以置信的前景,也是BPF功能的一个标志。必须指出,bpfilter和BPF本身不能解决由iptables使用顺序列表导致的性能问题。这样做需要本地使用BPF,例如Cilium 项目。 内核社区如何反应?一些Linux内核邮件列表以其火焰战争而闻名。在这种情况下,火焰爆发了吗?不,实际上,核心iptables维护人员立即提出了所有针对BPF方向的建议。 Florian Westphal 提出了一个将在bpfilter之上运行的框架,并将nftables转换为BPF。这允许保持特定领域的nftables语言,但受益于带有JIT编译器,硬件卸载和工具的BPF运行时的所有优点。 Pablo Neira Ayuso似乎一直在研究类似的提案 ,并发表了一系列将nftables翻译成BPF的系列文章。方法的主要区别似乎是Pablo打算在内核中执行翻译。此后社区同意,任何注入BPF程序都必须通过用户空间进行,并通过BPF验证程序来保证BPF的安全行为。
概要我认为BPF是多年以来最令人兴奋的Linux开发。我们几乎没有抓住其潜力的表面,它仍在不断发展。用BPF替换iptables的内核部分是合乎逻辑的第一步。真正的转变将是BPF原生工具以及远离传统的IP地址/端口中心构造。
|