Ingress Nginx 接连披露高危安全漏洞,是否有更好的选择?

本文涉及的产品
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 微服务引擎MSE面向业界主流开源微服务项目, 提供注册配置中心和分布式协调(原生支持Nacos/ZooKeeper/Eureka)、云原生网关(原生支持Ingress/Envoy)、微服务治理(原生支持Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服务治理规范)能力。

今年 K8s Ingress Nginx 项目接连披露了三个高危安全漏洞(CVE-2021-25745, CVE-2021-25746, CVE-2021-25748),该项目也在近期宣布将停止接收新功能 PR,专注修复并提升稳定性。Ingress Nginx 作为 K8s 项目自带的网关组件,被大量用户的 K8s 集群默认安装。作为处于 Internet 网络边界的基础软件,又被大规模使用,势必会成为一些攻击者的理想目标。一旦防线攻破,其代价是惨痛的,可以参考同样是网络边界的基础组件,OpenSSL 的 Heartbleed 心血漏洞殷鉴不远。

2014年 Heartbleed 漏洞释出不久,OpenBSD 开始自行维护 LibreSSL,Google 也推出了 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.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: service1
            port:
              number: 80
  - host: bar.foo.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: service2
            port:
              number: 80

《K8s 网关选型初判:Nginx 还是 Envoy》一文中,我们已经给出了这个新的选项:MSE 云原生网关。本文继续展开分析,为何 MSE 云原生网关有更好的安全性保障。


Ingress Nginx 架构设计缺陷

image.png

Ingress Nginx 容器架构(图片来自 kubernetes.io)


Ingress Nginx 安全漏洞频发的背后,是由其不安全的架构设计导致的:将控制面 Ingress Controller 组件(Go程序),和数据面 Nginx 组件放在一个容器内。控制面在这里是一个 Admin 的角色,可想而知其会管理一些敏感的信息,例如和 K8s API Server 通信的认证凭证。数据面和控制面共用容器,就给攻击者通过数据面获取这些敏感信息提供了可乘之机。举例来说:
K8s 使用了 RBAC 机制实现 API Server 接口的认证鉴权,而用于 RBAC 认证的凭证信息,会通过 volume 挂载到容器的/var/run/secrets/kubernetes.io/serviceaccount目录。CVE-2021-25745 就是利用了控制面拼接 nginx.conf 配置文件的漏洞,通过 Ingress Path 实现了配置注入,让 Nginx 提供一个静态文件代理的路由,从而获取到这个凭证。可以看下有了这个凭证能干什么事情:

image.png

Ingress Nginx 凭证权限(图片来自 blog.lightspin.io)


上图是 ingress-nginx这个ServiceAccount角色的ClusterRole权限描述,因为网关需要加载 TLS 证书,所以这个角色是具有查看集群内所有Secret的权限的。攻击者不但能通过这个凭证拿到所有 TLS 证书的私钥信息,还能拿到集群里所有密钥类配置!

image.png

导致漏洞的架构根因 (图片来自 blog.lightspin.io)


实际上,CVE-2021-25746CVE-2021-25748,包括更早的 CVE-2021-25742,根因都是这个问题。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:https://github.com/kubernetes/ingress-nginx/pull/8397


更安全的替代品——MSE 云原生网关


image.png

从上图可以看到,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 /abc"
        backend:
          service:
            name: service
            port:
              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:https://help.aliyun.com/document_detail/424813.html

此外,云原生网关的插件市场提供了多种认证鉴权和安全防护插件,可以增强网络安全防护能力:

image.png

云原生网关插件市场


用户还可以基于 Wasm 技术,用多种语言(Go、JS、Rust等)实现网关功能动态扩展(无需重启网关),基于 Wasm 的沙箱机制,即使你的代码逻辑访问了空指针,也不会导致网关 crash。这种安全且简单的扩展机制也是 Ingress Nginx 不具备的。


MSE 注册配置中心专业版首购享 9 折优惠,MSE 云原生网关预付费全规格享 9 折优惠。点击阅读原文,即享优惠!640.png


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
Kubernetes 负载均衡 应用服务中间件
k8s学习--ingress详细解释与应用(nginx ingress controller))
k8s学习--ingress详细解释与应用(nginx ingress controller))
109 0
|
5月前
|
Kubernetes 测试技术 应用服务中间件
基于 Nginx Ingress + 云效 AppStack 实现灰度发布
本文将演示结合云效 AppStack,来看下如何在阿里云 ACK 集群上进行应用的 Ingress 灰度发布。
65080 19
|
6月前
|
Kubernetes 负载均衡 应用服务中间件
Ingress Nginx 安装【亲测可用】
Ingress Nginx 安装【亲测可用】
410 2
|
6月前
|
域名解析 网络协议 应用服务中间件
nginx-ingress通过ipv6暴露服务,并在nginx ingress日志中记录客户端真实ipv6的ip地址
本文主要通过阿里云提供的clb和nlb来实现,建议是提前创建好双栈的vpc和vsw(使用clb可以不用双栈vpc和vsw)
609 1
|
6月前
|
Kubernetes 应用服务中间件 网络安全
kubernetes中Ingress Nginx 常用规则使用
kubernetes中Ingress Nginx 常用规则使用
69 0
|
6月前
|
Kubernetes 应用服务中间件 nginx
Nginx Ingress Controller
如果需要再部署一套完全独立的Nginx Ingress Controller,以下是推荐的详细步骤:
89 2
|
6月前
|
Kubernetes 负载均衡 应用服务中间件
Nginx Ingress
Nginx Ingress是Kubernetes的一个开源控制器,用于管理和配置外部访问Kubernetes集群中的服务。它可以提供负载均衡、SSL终结和基于名称的虚拟托管等功能,使得Kubernetes集群中的服务可以更加方便地对外提供服务。
122 2
|
Docker 容器
4. 安装ingress-nginx
ingress-nginx安装 这里假设你已经了解了ingress-nginx,如果你还没了解请询问搜索引擎。这篇文章只能让你快速的部署他们。 安装之前 安装之前需要确保你的集群正常运行或主节点再运行: 如果集群正常运行:你可以开始安装了。
12053 0
|
11天前
|
应用服务中间件 BI nginx
Nginx的location配置详解
【10月更文挑战第16天】Nginx的location配置详解
|
19天前
|
缓存 负载均衡 安全
Nginx常用基本配置总结:从入门到实战的全方位指南
Nginx常用基本配置总结:从入门到实战的全方位指南
192 0