本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用应用程序负载均衡器简化 Amazon ECS 中双向 TLS 的应用程序身份验证
Olawale Olaleye 和 Shamanth Devagari,Amazon Web Services
Summary
此模式可帮助您使用应用程序负载均衡器(ALB),通过 Amazon Elastic Container Service(Amazon ECS)中的双向 TLS 简化应用程序身份验证并减轻安全负担。使用 ALB,您可以对来自的 X.509 客户端证书进行身份验证。 AWS 私有证书颁发机构这种强大的组合有助于实现服务之间的安全通信,从而减少对应用程序中的复杂身份验证机制的需求。此外,该模式使用 Amazon Elastic Container Registry(Amazon ECR)存储容器映像。
此模式中的示例一开始使用公开映像浏览馆中的 Docker 映像创建示例工作负载;随后,将构建新的 Docker 镜像镜像并将其存储到 Amazon ECR 中。要获取来源,可以考虑基于 Git 的系统,例如 GitHub、或 Bitbucket GitLab,或者使用亚马逊简单存储服务 Amazon S3 (Amazon S3)。要构建 Docker 镜像,请考虑使用 AWS CodeBuild 作为后续镜像。
先决条件和限制
先决条件
限制
应用程序负载均衡器的双向 TLS 仅支持 X.509v3 客户端证书,不支持 X.509v1 客户端证书。
此模式的代码存储库中提供的 CloudFormation 模板不包括将 CodeBuild 项目配置为堆栈的一部分。
有些 AWS 服务 并非全部可用 AWS 区域。有关区域可用性,请参阅按区域划分的AWS 服务
。有关特定端点,请参阅服务端点和配额,然后选择相应服务的链接。
产品版本
Docker 版本 27.3.1 或更高版本
AWS CLI 版本 2.14.5 或更高版本
架构
下图显示了此模式的架构组件。

下图显示了如下工作流:
创建 Git 存储库,并将应用程序代码提交至该存储库。
在中创建私有证书颁发机构 (CA) AWS 私有 CA。
创建 CodeBuild 项目。由提交更改触发,创建 Docker 映像并将构建的映像发布到 Amazon ECR。 CodeBuildproject
从 CA 复制证书链和证书正文,并将证书捆绑包上传至 Amazon S3。
使用您上传到 Amazon S3 的 CA 捆绑包创建信任存储。将信任存储与应用程序负载均衡器(ALB)上的双向 TLS 侦听器关联。
使用私有 CA 为容器工作负载颁发客户端证书。还可以使用创建私有 TLS 证书 AWS 私有 CA。
将私有 TLS 证书导入 AWS Certificate Manager (ACM),然后将其与 ALB 一起使用。
ServiceTwo中的容器工作负载与ServiceOne中的容器工作负载通信时,会使用已颁发的客户端证书对 ALB 进行身份验证。ServiceOne中的容器工作负载与ServiceTwo中的容器工作负载通信时,会使用已颁发的客户端证书对 ALB 进行身份验证。
自动化和扩展
这种模式可以通过使用 SDK 中的 CloudFormation AWS Cloud Development Kit (AWS CDK) 、或 API 操作来配置 AWS 资源来实现完全自动化。
您可以使用 AWS CodePipeline 来实现持续集成和持续部署 (CI/CD) 管道,用于自动执行容器映像构建过程并将新版本部署到 Amazon ECS 集群服务。 CodeBuild
工具
AWS 服务
AWS Certificate Manager (ACM) 可帮助您创建、存储和续订 X.509 公有和私有 SSL/TLS X.509 证书和密钥,以保护您的 AWS 网站和应用程序。
AWS CloudFormation帮助您设置 AWS 资源,快速一致地配置资源,并在和的整个 AWS 账户 生命周期中对其进行管理 AWS 区域。
AWS CodeBuild 是一项完全托管式构建服务,可编译源代码、运行单元测试和生成部署就绪的构件。
Amazon Elastic Container Registry(Amazon ECR)是一项安全、可扩展且可靠的托管容器映像注册表服务。
Amazon Elastic Container Service(Amazon ECS)是一项高度可扩展的快速容器管理服务,可助您轻松运行、停止和管理集群上的容器。您可以在由 AWS Fargate管理的无服务器基础架构上运行任务和服务。或者,为了更好地控制您的基础设施,您可以在您管理的亚马逊弹性计算云 (Amazon EC2) 实例集群上运行任务和服务。
Amazon ECS Exec 允许您直接与容器交互,而无需首先与主机容器操作系统交互、打开入站端口或管理 SSH 密钥。您可以使用 ECS Exec 在 Amazon EC2 实例上或上运行的容器中运行命令或获取外壳程序。 AWS Fargate
弹性负载均衡(ELB) 将传入的应用程序或网络流量分配到多个目标。例如,您可以在一个或多个可用区内的 Amazon EC2 实例、容器和 IP 地址之间分配流量。ELB 会监控已注册目标的运行状况,并仅将流量传输到运行状况良好的目标。ELB 根据传入流量随时间的变化对负载均衡器进行扩展。它可以自动扩缩来处理大部分工作负载。
AWS Fargate无需管理服务器或 Amazon EC2 实例,即可帮助您运行容器。Fargate 与 Amazon ECS 和 Amazon Elastic Kubernetes Service(Amazon EKS)兼容。您可以使用 Fargate 启动类型或 Fargate 容量提供程序来运行 Amazon ECS 任务和服务。为此,将应用程序打包到容器中、指定 CPU 和内存要求、定义联网和 IAM 策略并启动应用程序。每个 Fargate 任务都具有自己的隔离边界,不与其他任务共享底层内核、CPU 资源、内存资源或弹性网络接口。
AWS 私有证书颁发机构允许创建私有证书颁发机构 (CA) 层次结构,包括根和下级结构 CAs,而无需运营本地 CA 的投资和维护成本。
其他工具
Docker
是一组平台即服务(PaaS)产品,它们利用操作系统级的虚拟化技术在容器中提供软件。 GitHubGitLab
、和 Bitbucket 是一些常用的基于 Git 的源代码控制系统,用于跟踪源代码更改。 NGINX Open Source
是一款开源的负载均衡器、内容缓存服务器及 Web 服务器。本方案将其用作 Web 服务器。此模式将其用作 Web 服务器。 OpenSSL
是一个开源库,提供各类服务供 TLS 和 CMS 的 OpenSSL 实现使用。
代码存储库
此模式的代码可在 Amazon-ECS 存储库中的 GitHub mtls with-Application-Load-Balancer-Amazon-
最佳实践
使用 Amazon ECS Exec 在 Fargate 上运行的容器中运行命令或获取 Shell。您还可以使用 ECS Exec 来帮助收集用于调试的诊断信息。
使用安全组和网络访问控制列表 (ACLs) 来控制服务之间的入站和出站流量。Fargate 任务会从您的虚拟私有云(VPC)中配置的子网接收一个 IP 地址。
操作说明
| Task | 说明 | 所需技能 |
|---|---|---|
下载源代码。 | 要下载此模式的源代码,请复刻或克隆 GitHub MTLS with-Amazon- | DevOps 工程师 |
创建 Git 存储库。 | 要创建包含 Dockerfile 和
| DevOps 工程师 |
| Task | 说明 | 所需技能 |
|---|---|---|
在中创建私有 CA AWS 私有 CA。 | 要创建私有证书颁发机构(CA),请在终端中运行以下命令。将示例变量中的值替换为您自己的值。
有关更多详细信息,请参阅 AWS 文档AWS 私有 CA中的创建私有 CA。 | DevOps 工程师,AWS DevOps |
创建并安装私有 CA 证书。 | 要为私有根 CA 创建并安装证书,请在终端中运行以下命令:
| AWS DevOps, DevOps 工程师 |
申请托管证书。 | 要申请私有证书 AWS Certificate Manager 以用于您的私有 ALB,请使用以下命令:
| DevOps 工程师,AWS DevOps |
使用私有 CA 颁发客户端证书。 |
此命令会返回这两项服务的 CSR 和私钥。
有关更多信息,请参阅 AWS 文档中的颁发私有终端实体证书。 | DevOps 工程师,AWS DevOps |
| Task | 说明 | 所需技能 |
|---|---|---|
使用 CloudFormation 模板 AWS 服务 进行配置。 | 要配置虚拟私有云 (VPC)、亚马逊 ECS 集群、亚马逊 ECS 服务、Application Load Balancer 和亚马逊弹性容器注册表 (Amazon ECR) Container Registry,请使用该模板。 CloudFormation | DevOps 工程师 |
获取变量。 | 请确认您拥有运行两项服务的 Amazon ECS 集群。要检索资源详细信息并将其存储为变量,请使用以下命令:
| DevOps 工程师 |
创建 CodeBuild 项目。 | 要使用 CodeBuild 项目为您的 Amazon ECS 服务创建 Docker 镜像,请执行以下操作:
有关更多详细信息,请参阅 AWS 文档AWS CodeBuild中的创建构建项目。 | AWS DevOps, DevOps 工程师 |
构建 Docker 映像。 | 您可以使用 CodeBuild 来执行映像构建过程。 CodeBuild 需要权限才能与 Amazon ECR 交互和使用 Amazon S3。 作为该过程的一部分,将构建 Docker 映像并将其推送至 Amazon ECR 注册表。有关模板和代码的详细信息,请参阅其他信息。 (可选)要在本地构建以进行测试,请使用以下命令:
| DevOps 工程师 |
| Task | 说明 | 所需技能 |
|---|---|---|
将 CA 证书上传到 Amazon S3。 | 要将 CA 证书上传到 Amazon S3 存储桶,请使用以下示例命令:
| AWS DevOps, DevOps 工程师 |
创建信任存储。 | 要创建信任存储,请使用以下示例命令:
| AWS DevOps, DevOps 工程师 |
上传客户端证书。 | 要将客户端证书上传到 Amazon S3 以用于 Docker 映像,请使用以下示例命令:
| AWS DevOps, DevOps 工程师 |
修改侦听器。 | 要在 ALB 上启用双向 TLS,请使用以下命令修改 HTTPS 侦听器:
有关更多信息,请参阅 AWS 文档中的在 App lication Load Balancer 上配置双向 TLS。 | AWS DevOps, DevOps 工程师 |
| Task | 说明 | 所需技能 |
|---|---|---|
更新 Amazon ECS 任务定义。 | 要更新 Amazon ECS 任务定义,请修改新修订版中的 要获取相应服务的值,请使用您在前面的步骤中构建的新 Docker 映像 URI 更新任务定义:
有关更多信息,请参阅 AWS 文档中的使用控制台更新 Amazon ECS 任务定义。 | AWS DevOps, DevOps 工程师 |
更新 Amazon ECS 服务。 | 使用最新的任务定义来更新服务。此任务定义是新构建的 Docker 映像的“蓝图”,包含进行双向 TLS 身份验证所需的客户端证书。 要更新服务,请执行以下步骤:
对其他服务重复上述步骤。 | AWS 管理员、AWS DevOps、 DevOps 工程师 |
| Task | 说明 | 所需技能 |
|---|---|---|
复制应用程序 URL。 | 使用 Amazon ECS 控制台查看任务。当任务状态更新为正在运行时,选择该任务。在任务部分中,复制任务 ID。 | AWS 管理员,AWS DevOps |
测试您的应用程序。 | 要测试您的应用程序,请使用 ECS Exec 访问任务。
| AWS 管理员,AWS DevOps |
相关资源
Amazon ECS 文档
其他 AWS 资源
如何使用 AWS 私有 CA 在 Application Load Balancer 上配置 mTLS?
(AWS re:Post)
附加信息
编辑 Dockerfile
以下代码显示了您在服务 1 的 Dockerfile 中编辑的命令:
FROM public.ecr.aws/nginx/nginx:latest WORKDIR /usr/share/nginx/html RUN echo "Returning response from Service 1: Ok" > /usr/share/nginx/html/index.html ADD client_cert1.cert client_private-key1.pem /usr/local/share/ca-certificates/ RUN chmod -R 400 /usr/local/share/ca-certificates/
以下代码显示了您在服务 2 的 Dockerfile 中编辑的命令:
FROM public.ecr.aws/nginx/nginx:latest WORKDIR /usr/share/nginx/html RUN echo "Returning response from Service 2: Ok" > /usr/share/nginx/html/index.html ADD client_cert2.cert client_private-key2.pem /usr/local/share/ca-certificates/ RUN chmod -R 400 /usr/local/share/ca-certificates/
如果您使用构建 Docker 镜像 CodeBuild,则该buildspec文件会使用 CodeBuild 内部版本号将镜像版本唯一标识为标签值。您可以根据自身需求更改 buildspec 文件,如下列 buildspec 自定义代码所示:
version: 0.2 phases: pre_build: commands: - echo Logging in to Amazon ECR... - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ECR_REPOSITORY_URI - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7) - IMAGE_TAG=${COMMIT_HASH:=latest} build: commands: # change the S3 path depending on the service - aws s3 cp s3://$YOUR_S3_BUCKET_NAME/serviceone/ $CodeBuild_SRC_DIR/ --recursive - echo Build started on `date` - echo Building the Docker image... - docker build -t $ECR_REPOSITORY_URI:latest . - docker tag $ECR_REPOSITORY_URI:latest $ECR_REPOSITORY_URI:$IMAGE_TAG post_build: commands: - echo Build completed on `date` - echo Pushing the Docker images... - docker push $ECR_REPOSITORY_URI:latest - docker push $ECR_REPOSITORY_URI:$IMAGE_TAG - echo Writing image definitions file... # for ECS deployment reference - printf '[{"name":"%s","imageUri":"%s"}]' $CONTAINER_NAME $ECR_REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json artifacts: files: - imagedefinitions.json