安全是eBPF 应用中较为重要的一个特性。比如操作系统、软件安、网络、容器等场景都会应用到eBPF的安全特性。
可观测性存在冰山现象,安全也是。普通开发者或用户,平时接触的多为主机安全、PC 端的安全等。PC 端或大型集群服务器的业务场景非常广泛,包括异常的攻击行为、异常漏洞等,其对应的检测范围也较大。主机端实现安全防护或检测,一般通过构建病毒库,然后不断地根据受到的攻击将新的病毒更新到病毒库,达到一定的阻断和防御目的。但该手段无法应对近年出现的新型病毒,因此我们需要利用eBPF的能力,比如用 eBPF做一个容器或云原生场景的白名单,该白名单之外的所有异常行为都会被阻断。
安全是指一种状态,在这种状态下,某种对象或对象的某种属性不受威胁。
eBPF具有以下几个安全特性:
l 程序沙箱化:内核源代码受到保护并保持不变,eBPF程序的验证步骤会确保资源不会程序阻塞;
l 侵入性低:无需修改内核代码,也无需停下现有程序来验证效果;
l 透明化:数据都从内核中透明地收集,应用无需检测监控的状态,符合安全用例;
l 可配置:自定义乃至自动化配置策略,修改检测、阻断规则文件更快速,更新灵活性高、过滤条件丰富(进程、网络、文件等)。一般而言,检测到异常后,如果直接阻断,可能会对业务产生影响。因此,会先进行告警,然后根据严重程度决定是否阻断。
l 快速检测:在内核直接处理各种事件,使得检测异常情况更方便和快速,从性能和开销上也能获得更大的收益;
eBPF程序会被LLVM编译为eBPF字节码,eBPF字节码需要通过eBPF Verifier的(静态)验证,再通过比如JIT 解析成符合要求的机器码,方能真正地运行。
因此,边界检查是eBPF Verifier的重点工作,经过验证步骤后,能够确保eBPF程序可以安全运行。内核的稳定性大多与内存相关,因此eBPF 验证器的主要工作也与其有一定的关联,也就需要确保以下几点:
第一,需要拥有加载 eBPF 流程所需的特权,对指令集、指令数等都有一定要求。从安全角度来说,即使赋予程序一定的非 root 权限,部分功能可能也并没有效果。
第二,不要出现 crash 或其他异常导致系统异常或内核崩溃的情况。因为 eBPF 本身的工作内容即沙箱化、无侵入、不对内核造成大的影响。
第三,程序可以正常结束,无死循环。从静态分析的角度将程序完全地运行一遍,确保无死循环。
第四,检查内存越界。如果存在内存越界,则可能导致验证不通过,流程无法往下进行。
第五,检查寄存器溢出。如果存在寄存器溢出,则会导致验证流程中断。
随着云网边端的急速发展,人们的目光越发聚焦在目前最火热的云原生场景上。Falco、Tracee、Tetragon、Datadog-agent、KubeArmor是现阶段云原生场景下比较流行的几款运行时防护方案。这些方案主要基于eBPF挂载内核函数并编写过滤策略,在内核层出现异常攻击时触发预置的策略,在内核层对异常攻击进行记录并发出告警,无需再返回用户层,可以直接发出告警甚至阻断。
以上方案多为应用层的运行时防御方案,以进程为粒度,而阻断进程会导致业务运行受到影响。
因此,我们正在推进内核侧的eBPF与LSM结合的方案,期望能够解决上述问题。该方案能够从函数调用的粒度进行阻断,在白名单内记录正常的调用路径,一旦发现白名单之外的调用行为,即可阻断此次函数调用,而不会影响正常的业务运行。但此类方案目前尚存在较多的限制,比如需要较高的内核版本。
此前,人们对安全的关注点大多集中于应用层规则的编写或安全策略的实施。而伴随着云原生的发展,我们会越来越注重于内核端,结合内核和 eBPF 的安全特性,进行防御和阻断。
安全策略可以通过 Kubernetes(CRD)、JSON API 或 Open Policy Agent(OPA)等系统注入。
以CNCF为例,上层收集到的数据后,通过 agent 到达内核端,进行一系列的收集、检测。每一个 POD 会制定规则,触发了规则之后会给予相应的措施,比如告警或阻断。
关于龙蜥峰会 eBPF & Linux 稳定性专场课件获取方式:
【PPT 课件获取】:关注微信公众号(OpenAnolis),回复“龙蜥课件” 即可获取。有任何疑问请随时咨询龙蜥助手—小龙(微信:openanolis_assis)。
【视频回放】:视频回放可前往龙蜥官网 https://openanolis.cn/video 查看。