![640](https://i-blog.csdnimg.cn/blog_migrate/c357d80c385913c39bb48cb0ab12f623.gif)
BPF for security—and chaos—in Kubernetes
June 10, 2019
This article was contributed by Sean Kerner
KubeCon EU
对LWN读者来说,BPF应该已经听过不少次了。不过Kubernetes社区还很少了解BPF。在KubeCon + CloudNativeCon Europe 2019,有好几个题目带着BPF的话题,讲解了BPF对Kubernetes的安全,监控,chaos engineering testing会有什么帮助。开源社区Cilium项目,希望帮助大家在Kubernetes container环境里使用BPF。Thomas Graf是Linux kernel的BPF开发参与者,介绍了如何利用Envoy, Cilium和BPF来做transparent chaos testing。而Dan Wendlandt,OpenStack社区知名人士,帮助推动了Neutron networking项目,在会场介绍了怎样利用kernel的BPF功能来在Kubernetes环境里更好的查看系统以及增强安全性。
Cilium GitHub项目的主页面上把自己定义为一种增强网络安全的技术,它可以利用BPF和eXpress Data Path (XDP)来深入了解多个microservice(微服务)之间的API调用。Cilium同时也利用BPF程序来从运行中的容器里提取各种数据,从而更好的查看以及管理这些容器。
Chaos engineering
Kubernetes架构中的一个核心能力就是能迅速恢复。初始配置正确后,可以从任何错误里面快速恢复出来,只需要启动一个新的pod(即Kubernetes中的最小部署单元)即可。要想做好这些针对快速恢复能力的配置优化,就需要利用一类名为chaos testing(混沌测试)的测试方法。这类测试来源于所谓的chaos engineering(netflix等公司在推广的致力于减少宕机次数与时长的开发方法);Graf介绍了一下这个概念,简单来说就是对商业应用中的软件系统按某种规则做各种试验,希望能确保系统稳定性足以应对各种意外状况。“简单来说,你需要在你的软件平台利引入各种混乱,来更好的了解会有哪些出错模式”。Graf还特别指出在chaos testing里面,fault injection是非常有用的手段。他解释了fault injection,就是故意往软件里面注入各种特别设计过的、屏厂很少出现的错误状况。Fault injection可以模拟停电,或者服务出错,也可以是模拟拖慢一个程序的响应。
为了使用fault injection,就需要在各个service互相通讯的通路上,能找到一些中间函数,来截获这些通讯交互。还需要很高的可定制化,例如只有对1%的操作才触发inject fault操作,而不是让这个service在100%的时间都是出错的。最后,还需要提供查看方法,能确保fault injection成功,以及确保观测到的错误现象真的是由于chaos testing导致的,而不是正在跑的application本身真的出现了问题。
Graf的chaos engineering测试环境会使用到一个Envoy proxy,这是一个开源服务,由Cloud Native Computing Foundation (CNCF)提供服务。主要是使用Go语言写各种扩展来进行fault injection测试。此外还需要Cilium,这是基于BPF的一个项目,实现了Kubernetes network policy以及identity-based enforcement。"Cilium会启动Envoy,运行它之后再利用BPF,好像变魔术一般地把所有网络数据流都送到fault-injection策略那边检查一下“。
Graf演示中用到的fault-inection代码已经公布到了GitHub仓库里,可以支持模拟delayed response以及服务失败场景。
Securing Kubernetes with BPF
Wendlandt利用他的会议时间,介绍了BPF和Cilium是怎么帮助改善Kubernetes集群中应用程序的安全性的。从安全的角度来说,Kubernetes跟通用的操作系统是完全不一样的东西。Kubernetes集群里面有很多microservice微服务,这样能减少并更好的控制可能被攻击的界面,因为每个microservice都只能做很固定的少数几种操作。
Wendlandt介绍他自己主要关注运行时的动态安全攻击,都是在application正在运行状态时发生的。他说:“恶意攻击,通常都是某个恶意攻击者找到了一个开发者很少注意到的、但是切实可行的执行路径,或者数据流”。security control安全控制应该可以阻止一些不合理的执行顺序和数据流,不过说起来容易做起来难,因为security control千万要小心,绝对不能限制合法的使用方式。最后,他发现BPF对这种情况太合适了,BPF对Kubernetes的安全性来说,并不仅仅是让它更安全,而是能够在不增加application开发者负担的情况下来透明的提供安全性优势。
他解释了一下BPF的工作原理,然后指出BPF可以让kernel event来提供function-as-a-service的能力,也就是说针对某个特定的event,可以触发我们动态指定的某个函数。每个触发的函数都是在BPF沙盒环境里执行的,这样就能绝对禁止这些插入的函数做那些未被授权的操作。Wendlandt认为,用BPF就可以动态的更新hook,让Kubernetes和microservices都更加智能。
BPF maps是一种很高效的数据结构,可以用于函数调用中的数据传递。他觉得BPF可以被看做是arrays和hash tables。BPF程序可以通过写入、读取BPF maps,把这些数据长久保留,确保一个BPF program的执行生命周期里数据不丢失。Wandlandt还推荐了一篇LWN文章来详细介绍persistent BPF objects。他也提醒,“BPF maps可以被BPF program来写,也可以是由BPF的相关user space工具来写入的”。
Beyond iptables
Iptables可以根据IP地址来设置防火墙规则,从而帮助管控外部可以访问到的web server等资源。不过iptables对Kubernetes来说不是一个很理想的方案。在Kubernetes里面,pods变化很快,时开时关的,并且一个集群里面可能有数千个微服务同时运行。iptables对这种规模的应用来说不是很好,它的设计逻辑还是只是针对IP地址和端口号的,可是在Kubernetes里面,IP地址都是很短暂的,变化频繁,不适合作为长时间的一个特征。
Kubernetes里的label是最适合作为特征值的。BPF和Cilium就可以检测到这个特征值,从而利用来针对性的施加一些限制,或者检查一些状态。Wendlandt他们做了很多事情来确保不是针对IP address来识别kubernetes对象,而是根据cloud里面原生的这个更有代表性的label来识别。Cilium对app来说是完全透明的,不需要app提供任何其他信息,这就正是BPF的强大所在了。网络数据流只会经过kernel,我们只是用BPF截获来做一些操作,根本不需要application来帮主我们实现这个功能。
他举了一个例子来说明,有一种伪造从server端发起的request,可能可以让Kubernetes集群整个都丧失安全性。这类攻击可能来自各种不同的攻击模式,甚至最微小的一个配置错误都可能导致安全风险。“可以说哪怕是再小的代码都有可能存在安全相关的bug”,他说,“你需要做各种最坏假设,一旦你的环境中某个地方出问题了,怎么能把影响限制在最小范围”。
利用BPF可以更好的理解application在做什么,然后对它做更多限制,只给他所需要的最少的资源,这样攻击者就很难拿到更高的自由度来继续进行攻击了,从而斩断黑手。Wendlandt认为Kubernetes microservices的架构设计,已经非常有助于避免系统崩溃了(比起Linux里的application来说)。虽然microservice已经用的太滥了,不过它对Kubernetes本身意义非凡。micro意味着你不需要跑一个臃肿的容器,只需要能精简到只要能跑你需要的最基本的工作就够了,这样就能提供一个非常合理、干净的环境。
他补充道,在调试microservice的时候,可以区分出是主进程发起的network传输,还是一个开发者通过kubectl exec命令发起的network传输。这样,在Kubernetes里面就可以针对不同类型的访问赋予相应的权限。对于microservices的这些服务来说,IP不再有意义,相应的,了解指定的pod能访问哪些service,对安全和控制策略设置来说更有意义。他强调在Kubernetes里面,每个个体都是跟Kubernetes label指定的service绑定在一起的,不是绑定IP地址。因此Cilium就可以对gRPC,HTTP,以及service API请求都能帮上忙了。
Identifying and stopping runtime attachs
要想减少runtime attack的风险,首先就需要了解每一个microservice的正常行为是什么。了解之后,就可以监控它是否有哪些越界行为。“我们可以监测这个application平时是怎样,利用BPF提供的信息来学习,然后用这些信息来施加安全策略,禁止这个pod做其他越界的事情。”
Wendlandt演示了一下如何使用Cilium,以及BCC tools项目的相关工具,帮助大家理解某个特定的系统调用(例如connect(), fork(), exec()等)怎么执行的,然后把相应的参数提取出来送给Cilium来决定需要施加哪些强制策略限制。
他也解释了Kubernetes pod里面的所有东西都是在一个network namespace的,公用一个IP地址,所以iptables这些传统防火墙无法区分来自某个特定pod的各种网络数据,因为都是来自相同的IP地址。“利用BPF,我们就能使用操作系统中system call级别的信息,来确保它只能执行最简单的工作,而不会做其他越界的操作”
关于Chaos Testing和eBPF Security这两个session的录像可以在YouTube上观看。
全文完
LWN文章遵循CC BY-SA 4.0许可协议。
极度欢迎将文章分享到朋友圈热烈欢迎转载以及基于现有协议上的修改再创作~
长按下面二维码关注:Linux News搬运工,希望每周的深度文章以及开源社区的各种新近言论,能够让大家满意~