CVE-2022-24769
近期在 Docker 中发现了一个 影响所有版本的安全漏洞 CVE-2022-24769,该漏洞已经在 Docker 最新的版本 v20.10.14 中修复。
这个漏洞主要是由于错误的设置了非空的 Linux 进程的 Inheritable capabilities 集合。导致在 execve(2)
期间,可能会造成提权。
我在《Kubernetes 安全原理与实践》 中 Linux 的权限和能力模型中, 曾介绍过相关内容。
Linux 中的 capabilities 可以作为每个线程的属性存在,也可以作用在可执行文件上。如果用作线程属性存在,我们称之为 线程 capability 集合;如果用作可执行文件的扩展属性上,则称之为 文件 capability 集合。
其中的线程 capability 集合主要包含以下五类:
- Permitted
- Inheritable
- Effective
- Bounding
- Ambient
本次漏洞受影响的就是 Inheritable 集合。它主要定义了一组跨 execve(2) 系统调用时可继承的 capability 集合。但是它的影响是会将 Inheritable 集合中的 capability 应用于新线程的 Permitted 集合中,而非直接设置成新线程的 Effective 集合。
另一方面,文件 capability 集合则主要包含以下三类:
- Permitted
- Inheritable
- Effective
其中 Inheritable 集合的作用是它定义的 capability 会与线程的 Inheritable 取交集, 然后添加到 execve(2)
产生的线程 Permitted 集合中。
所以当上述关于 Inheritable 集合的 capability 都进行设置时,就可能会出现提权。
以下是本次修正此漏洞时的主要变更, 可以看到主要是将原先默认设置的 Inheritable 集合的部分去掉。这样就可以创建出来一个典型的 Linux 环境了。
func SetCapabilities(s *specs.Spec, caplist []string) error {
- s.Process.Capabilities.Effective = caplist
- s.Process.Capabilities.Bounding = caplist
- s.Process.Capabilities.Permitted = caplist
- s.Process.Capabilities.Inheritable = caplist
// setUser has already been executed here
- // if non root drop capabilities in the way execve does
- if s.Process.User.UID != 0 {
- s.Process.Capabilities.Effective = []string{}
- s.Process.Capabilities.Permitted = []string{}
+ if s.Process.User.UID == 0 {
+ s.Process.Capabilities = &specs.LinuxCapabilities{
+ Effective: caplist,
+ Bounding: caplist,
+ Permitted: caplist,
+ }
+ } else {
+ // Do not set Effective and Permitted capabilities for non-root users,
+ // to match what execve does.
+ s.Process.Capabilities = &specs.LinuxCapabilities{
+ Bounding: caplist,
+ }
}
return nil
}
此漏洞虽然是在 Docker 中发现的,但实际上在 containerd 中也是存在的。当前 Docker 已经发布了最新的 v20.10.14 版本修正此漏洞。同时 containerd 也相继发布了 v1.5.11 和 v1.6.2 来对此漏洞进行修复。建议大家进行升级。并且升级后需要对现有已经启动的容器进行重建操作。
或者,如果在不升级的情况下,可以通过主动删除 Inheritable 集合的 capability 来进行安全防护。
cert-manager v1.8.0-alpha.0 发布
cert-manager 是一个可以很方便在 Kubernetes 集群上用于自动化管理证书的工具。这是 cert-manager v1.8.0 的 alpha 版本。其中有一些我很关注的内容:
在 #4789 中删除了硬编码的 Ingress 的 whitelist-source-range
Annotation, 这样就可以通过 Ingress template 来自定义进行设置了。
这对于用户想要去使用其他的 Ingress controller 是非常关键的。比如我正在做的 Apache APISIX Ingress controller项目,对于这类黑白名单需求的 Annotation 名称其实是 k8s.apisix.apache.org/allowlist-source-range
和 k8s.apisix.apache.org/blocklist-source-range
, 经过此次修改就可以很方便的使用了。
此外,对于 Kubernetes Ingress-nginx 项目而言,在 v1.x 版本中,我们将其中的 white/black
等都修改成了 allowlist/blocklist
了,所以此次修改也能对 Ingress-nginx 项目的 新版本进行兼容。
此外,从这个版本开始引入了 ServerSideApply
的特性,不过相关功能应该还会有些变更,这里就不展开了。
更多关于此版本的变更请查看其 ReleaseNote
上游进展
- KEP-3136: beta apis off by default · kubernetes/enhancements 从 Kubernetes v1.24 开始默认情况下将会禁用新的 Beta 版本 API,但是不影响旧的/已存在的。
- #107979 · kubernetes/kubernetes loadBalancerClass 特性达到 GA 状态,这是从 v1.21 开始引入的,跟 IngressClass/StorageClass 等比较类似。
题外话
Kubernetes 的发布周期从 2021 年初改成了一年三个版本,至今已经一年了。Kubernetes 的发版节奏变慢,你感觉如何?欢迎留言交流讨论