在 Amazon EKS 上使用 AWS 私有 CA 在 AWS App Mesh 中激活 mTLS - AWS Prescriptive Guidance

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在 Amazon EKS 上使用 AWS 私有 CA 在 AWS App Mesh 中激活 mTLS

由奥马尔·卡希尔(AWS)、伊曼纽尔·萨利乌(AWS)、穆罕默德·沙扎德(AWS)和安迪·王(AWS)创作

环境:PoC 或试点

技术:容器和微服务

Amazon Web Services:AWS App Mesh、Amazon EKS、AWS Certificate Manager (ACM)

Summary

此模式展示了如何使用 AWS App Mesh 中的 AWS 私有证书颁发机构 (AWS Private CA) 的证书在 Amazon Web Services (AWS) 上实施相互传输层安全性 (mTLS)。它通过面向所有人的安全生产标识框架 (SPIFFE) 使用 Envoy 机密发现服务 (SDS) API。SPIFFE 是一个云原生计算基金会 (CNCF) 开源项目,具有广泛的社区支持,可提供细粒度和动态的工作负载身份管理。要实现 SPIFFE 标准,请使用 SPIRE SPIFFE 运行时环境。

在 App Mesh 中使用 mTLS 可提供双向对等身份验证,因为它在 TLS 上增加了一层安全性,并允许网格中的服务验证正在建立连接的客户端。客户端-服务器关系中的客户端还会在会话协商过程中提供 X.509 证书。服务器使用此证书来识别和验证客户端。这有助于验证证书是否由受信任的证书颁发机构 (CA) 颁发,以及证书是否有效。

先决条件和限制

先决条件

  • 具有自行管理或托管节点组的 Amazon Elastic Kubernetes Service(Amazon EKS)集群

  • 在已激活 SDS 的集群上部署的 App Mesh 控制器

  • 由 AWS Private CA 颁发的来自 AWS Certificate Manager(ACM)的私有证书

限制

  • 无法在 AWS Fargate 上安装 SPIRE,因为 SPIRE 代理必须作为 Kubernetes 运行。 DaemonSet

产品版本

  • AWS App Mesh Controller 图表 1.3.0 或更高版本

架构

下图显示了 VPC 中具有 App Mesh 的 EKS 集群。一个 Worker 节点中的 SPIRE 服务器与其他工作线程节点中的 SPIRE 代理以及 AWS 私有 CA 进行通信。Envoy 用于 SPIRE Agent Worker 节点之间的 mTLS 通信。

带有 SPIRE 代理和服务器、App Mesh 和 mTLS 的 Envoy 的 EKS 集群工作节点。

下图说明了以下步骤:

  1. 颁发证书。

  2. 请求证书签名和证书。

工具

Amazon Web Services

  • AWS Private CA – AWS 私有证书颁发机构 (AWS Private CA) 可创建私有证书颁发机构(CA)层次结构(包括根 CA 和从属 CA),而不会产生运营本地 CA 的投资和维护成本。

  • AWS App Mesh – AWS App Mesh 是一种服务网格,可轻松监控和控制服务。App Mesh 将服务通信方式标准化,为应用程序中的每个服务提供一致的可见性和网络流量控制。

  • Amazon EKS – Amazon Elastic Kubernetes Service (Amazon EKS) 是一项托管服务,可让您在 AWS 上轻松运行 Kubernetes,而无需安装、操作和维护您自己的 Kubernetes 控制面板或节点。

其他工具

  • Helm – Helm 是 Kubernetes 的软件包管理器,可帮助您在 Kubernetes 集群上安装和管理应用程序。此模式使用 Helm 部署 AWS App Mesh Controller。

  • AWS App Mesh 控制器图表 – 此模式使用 AWS App Mesh 控制器图表在 Amazon EKS 上启用 AWS App Mesh。

操作说明

任务描述所需技能

使用 Amazon EKS 设置 App Mesh。

按照存储库中提供的基本部署步骤进行操作。

DevOps 工程师

安装 SPIRE。

使用 spire_setup.yaml 在 EKS 集群上安装 SPIRE。

DevOps 工程师

安装 AWS 私有 CA 证书。

按照 AWS 文档中的说明为您的私有根 CA 创建并安装证书。

DevOps 工程师

向集群节点实例角色授予权限。

若要将策略附加到集群节点实例角色,请使用其他信息部分中的代码。

DevOps 工程师

添加适用于 AWS Private CA 的 SPIRE 插件。

若要将插件添加到 SPIRE 服务器配置中,请使用其他信息部分中的代码。将 certificate_authority_arnAmazon 资源名称(ARN)替换为您的私有 CA ARN。使用的签名算法必须与私有 CA 上的签名算法相同。将 your_region替换为您的 AWS 区域。

有关该插件的更多信息,请参阅服务器插件: UpstreamAuthority “aws_pca”。

DevOps 工程师

更新 bundle.cert。

创建 SPIRE 服务器后,将创建一个 spire-bundle.yaml 文件。将 spire-bundle.yaml 文件中的 bundle.crt 值从私有 CA 更改为公共证书。

DevOps 工程师
任务描述所需技能

向 SPIRE 注册节点和工作负载条目。

要向 SPIRE Server 注册节点和工作负载(服务),请使用存储库中的代码。

DevOps 工程师

在激活 mTLS 的情况下在 App Mesh 中创建网格。

在 App Mesh 中创建一个新网格,其中包含微服务应用程序的所有组件(例如,虚拟服务、虚拟路由器和虚拟节点)。

DevOps 工程师

检查已注册的条目。

您可以通过运行以下命令来检查节点和工作负载的已注册条目。

kubectl exec -n spire spire-server-0 -- /opt/spire/bin/spire-server entry show

这将显示 SPIRE 代理的条目。

DevOps 工程师
任务描述所需技能

验证 mTLS 流量。

  1. 从前端服务向后端服务发送 HTTP 标头,并使用在 SPIRE 中注册的服务验证响应是否成功。

  2. 对于双向 TLS 身份验证,可以通过运行以下命令来检查 ssl.handshake 统计信息。

    kubectl exec -it $POD -n $NAMESPACE -c envoy -- curl http://localhost:9901/stats | grep ssl.handshake

    运行上一个命令后,应会看到侦听器 ssl.handshake 计数,该计数将类似于以下示例:

    listener.0.0.0.0_15000.ssl.handshake: 2
DevOps 工程师

验证证书是否是从 AWS 私有 CA 颁发的。

您可以通过查看 SPIRE 服务器中的日志来检查插件是否已正确配置,以及证书是否从上游私有 CA 颁发。运行以下命令。

kubectl logs spire-server-0 -n spire

然后查看生成的日志。此代码假定您的服务器名为 spire-server-0,并托管在您的 spire 命名空间中。您应该看到插件已成功加载,并且正在与上游私有 CA 建立连接。

DevOps 工程师

相关资源

其他信息

将权限附加到集群节点实例角色

{ "Version": "2012-10-17", "Statement": [ { "Sid": "ACMPCASigning", "Effect": "Allow", "Action": [ "acm-pca:DescribeCertificateAuthority", "acm-pca:IssueCertificate", "acm-pca:GetCertificate", "acm:ExportCertificate" ], "Resource": "*" } ] } AWS Managed Policy: "AWSAppMeshEnvoyAccess"

添加适用于 ACM 的 SPIRE 插件

Add the SPIRE plugin for ACM Change certificate_authority_arn to your PCA ARN. The signing algorithm used must be the same as the signing algorithm on the PCA. Change your_region to the appropriate AWS Region. UpstreamAuthority "aws_pca" { plugin_data { region = "your_region" certificate_authority_arn = "arn:aws:acm-pca:...." signing_algorithm = "your_signing_algorithm" } }