后台更改公司网站背景图片,写文案要看的网站,上海外贸公司外滩27号,北京住房和城乡建设部网站今年 K8s Ingress Nginx 项目接连披露了三个高危安全漏洞#xff08;CVE-2021-25745[1], CVE-2021-25746[2], CVE-2021-25748[3]#xff09;#xff0c;该项目也在近期宣布将停止接收新功能 PR#xff0c;专注修复并提升稳定性。Ingress Nginx 作为 K8s 项目自带的网关组件…今年 K8s Ingress Nginx 项目接连披露了三个高危安全漏洞CVE-2021-25745[1], CVE-2021-25746[2], CVE-2021-25748[3]该项目也在近期宣布将停止接收新功能 PR专注修复并提升稳定性。Ingress Nginx 作为 K8s 项目自带的网关组件被大量用户的 K8s 集群默认安装。作为处于 Internet 网络边界的基础软件又被大规模使用势必会成为一些攻击者的理想目标。一旦防线攻破其代价是惨痛的可以参考同样是网络边界的基础组件OpenSSL 的 Heartbleed 心血漏洞殷鉴不远。
2014 年 Heartbleed 漏洞释出不久OpenBSD 开始自行维护 LibreSSLGoogle 也推出了 BoringSSL基于和 OpenSSL 遵循同一套 SSL/TLS 协议标准提供更安全的替代品。类似的基于同一套 K8s Ingress API 标准是否有更安全的 K8s 网关可以替代 Ingress Nginx
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-example
spec:rules:- host: foo.bar.comhttp:paths:- pathType: Prefixpath: /backend:service:name: service1port:number: 80- host: bar.foo.comhttp:paths:- pathType: Prefixpath: /backend:service:name: service2port:number: 80
Ingress API 标准示例
在《K8s 网关选型初判Nginx 还是 Envoy》一文中我们已经给出了这个新的选项MSE 云原生网关。本文继续展开分析为何 MSE 云原生网关有更好的安全性保障。
Ingress Nginx 架构设计缺陷 Ingress Nginx 容器架构图片来自 kubernetes.io
Ingress Nginx 安全漏洞频发的背后是由其不安全的架构设计导致的将控制面 Ingress Controller 组件Go 程序和数据面 Nginx 组件放在一个容器内。控制面在这里是一个 Admin 的角色可想而知其会管理一些敏感的信息例如和 K8s API Server 通信的认证凭证。数据面和控制面共用容器就给攻击者通过数据面获取这些敏感信息提供了可乘之机。举例来说
K8s 使用了 RBAC 机制实现 API Server 接口的认证鉴权而用于 RBAC 认证的凭证信息会通过 volume 挂载到容器的/var/ru n/secrets/http://kubernetes.io/serviceaccount 目录。CVE-2021-25745 就是利用了控制面拼接 nginx.conf 配置文件的漏洞通过 Ingress Path 实现了配置注入让 Nginx 提供一个静态文件代理的路由从而获取到这个凭证。可以看下有了这个凭证能干什么事情 Ingress Nginx 凭证权限图片来自 blog.lightspin.io
上图是 ingress-nginx 这个 ServiceAccount 角色的 ClusterRole 权限描述因为网关需要加载 TLS 证书所以这个角色是具有查看集群内所有 Secret 的权限的。攻击者不但能通过这个凭证拿到所有 TLS 证书的私钥信息还能拿到集群里所有密钥类配置 导致漏洞的架构根因 图片来自 blog.lightspin.io
实际上CVE-2021-25746 和 CVE-2021-25748包括更早的 CVE-2021-25742[4]根因都是这个问题。CVE-2021-25742 基于 custom snippet 通过 Nginx 配置片段实现凭证获取CVE-2021-25746 可以基于多种 Ingress Annotation 实现 Nginx 配置片段注入获取凭证CVE-2021-25748 绕过了针对 CVE-2021-25745 修复的正则检测。真是防不胜防......
Ingress Nginx 社区认识到了这个架构问题的严重性已经开始计划做控制面和数据面的分离。若继续保持现有架构未来可能会爆出更严重的安全漏洞。
值得注意的是这种架构除了会导致上述安全问题还会导致容器 CPU 负载较高时控制面和数据面进程互相抢占调度出现一系列稳定性问题例如
1. 由控制面负责的存活健康检查livenessProbe超时失败导致容器不断重启
2. 在开启了 prometheus 采集监控指标的情况下控制面因为高负载抢占不到足够的 CPU会出现 OOM导致容器被 kill详细原因见文末相关 issue[5]
更安全的替代品——MSE 云原生网关 MSE 云原生网关的控制面和数据面架构
从上图可以看到MSE 云原生网关使用了数据面Envoy和控制面Istio隔离的架构从根本上避免了上述问题。MSE 云原生网关采用了托管部署的模式不是部署在用户自己的 K8s 集群中即使出现了安全漏洞用户也可以通过一键平滑升级轻松修复漏洞。并且有专业安全团队收集漏洞情报相比开源能提供更迅速、更可靠的修复方案。
基于前面几个 CVE 漏洞原理的说明不难发现 Ingress Nginx 通过控制面拼接 nginx.conf 配置实现数据面控制的方式也存在很大的安全隐患例如定义一个特殊的 Ingress Path
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-example
spec:rules:- http:paths:- pathType: Prefix# 下文中{...}省略号隐去了可能引发漏洞的配置path: /inject{...}location /abcbackend:service:name: serviceport:number: 80
就会在生成的 nginx.conf 中出现如下配置片段
location /inject{...}location /abc {set $ingress_name ingress-example;......
}
熟悉 Nginx 配置的同学会了解这里有两个 location 路径匹配规则其中 location /abc 是对应上述 Ingress 路由配置的而 location /inject 则可以实现一个额外的配置注入在{...}中可以写任意的 Nginx Location 级别配置甚至使用灵活度很高的 Lua 脚本达到配置注入者的各种目的。
不同于 Ingress Nginx 通过控制面拼接 nginx.conf 配置实现数据面控制云原生网关使用了更安全可靠的 xDS 协议通过 xDS API 配置解析替代字符串拼接从根本上避免了拼接配置导致配置注入的问题确保配置动作是明确的行为是可预期的。下面是向 Envoy 下发路由匹配规则用到的 proto 协议不同于 Ingress Nginx 的 location 指令拼接这种方式显然约束了路由匹配配置的作用范围。
message RouteMatch {option (udpa.annotations.versioning).previous_message_type envoy.api.v2.route.RouteMatch;message GrpcRouteMatchOptions {option (udpa.annotations.versioning).previous_message_type envoy.api.v2.route.RouteMatch.GrpcRouteMatchOptions;}message TlsContextMatchOptions {option (udpa.annotations.versioning).previous_message_type envoy.api.v2.route.RouteMatch.TlsContextMatchOptions;google.protobuf.BoolValue presented 1;google.protobuf.BoolValue validated 2;}// An extensible message for matching CONNECT requests.message ConnectMatcher {}reserved 5, 3;reserved regex;oneof path_specifier {option (validate.required) true;string prefix 1;string path 2;type.matcher.v3.RegexMatcher safe_regex 10 [(validate.rules).message {required: true}];ConnectMatcher connect_matcher 12;string path_separated_prefix 14 [(validate.rules).string {pattern: ^[^?#][^?#/]$}];string path_template 15[(validate.rules).string {min_len: 1 max_len: 256 ignore_empty: true}];}google.protobuf.BoolValue case_sensitive 4;core.v3.RuntimeFractionalPercent runtime_fraction 9;repeated HeaderMatcher headers 6;repeated QueryParameterMatcher query_parameters 7;GrpcRouteMatchOptions grpc 8;TlsContextMatchOptions tls_context 11;repeated type.matcher.v3.MetadataMatcher dynamic_metadata 13;
}
值得一提的是目前 Ingress Nginx 的大量路由策略功能都需要通过更新 nginx.conf然后重启 Nginx 生效重启过程中客户端连接会断开在 websocket 等长连接场景下会造成业务影响而通过 Envoy 的 xDS 配置下发路由策略生效基于 RDS/ECDS对长连接完全无影响。
为了方便用户从 Ingress Nginx 平滑迁移到 MSE 云原生网关我们除了完全兼容了 K8s Ingress API 的标准也兼容了常用的 Ingress Nginx Annotation详见文末文档[6]。
此外云原生网关的插件市场提供了多种认证鉴权和安全防护插件可以增强网络安全防护能力 云原生网关插件市场
用户还可以基于 Wasm 技术用多种语言Go、JS、Rust 等实现网关功能动态扩展无需重启网关基于 Wasm 的沙箱机制即使你的代码逻辑访问了空指针也不会导致网关 crash。这种安全且简单的扩展机制也是 Ingress Nginx 不具备的。
参考链接
[1] CVE-2021-25745
https://github.com/kubernetes/ingress-nginx/issues/8502
[2] CVE-2021-25746
https://github.com/kubernetes/ingress-nginx/issues/8503
[3] CVE-2021-25748
https://github.com/kubernetes/ingress-nginx/issues/8686
[4] CVE-2021-25742
https://github.com/kubernetes/ingress-nginx/issues/7837
[5] 相关 issue
https://github.com/kubernetes/ingress-nginx/pull/8397
[6] 文档
https://help.aliyun.com/document_detail/424813.html
作者澄潭
原文链接
本文为阿里云原创内容未经允许不得转载。