在不重启容器的情况下轮换数据库凭证 - AWS Prescriptive Guidance

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

在不重启容器的情况下轮换数据库凭证

由 Josh Joy(AWS) 编写

环境:生产

技术:容器和微服务;数据库;基础设施 DevOps;安全、身份、合规;管理和治理

Amazon Web Services:Amazon ECS、Amazon Aurora、AWS Fargate、AWS Secrets Manager、Amazon VPC

Summary

在 Amazon Web Services (AWS) Cloud 上,您可使用 AWS Secrets Manager 在数据库凭证的整个生命周期中轮换、管理和检索数据库凭证。用户和应用程序通过调用 Secrets Manager API 来检索密钥,而不需要对明文形式的敏感信息进行硬编码。

如果您使用容器处理微服务工作负载,则可以将凭证安全地存储在 AWS Secrets Manager 中。为了将配置与代码分开,这些凭证通常被注入至容器中。但是,定期自动轮换您的凭证非常重要。支持撤销后刷新凭证的能力也很重要。同时,应用程序需要能够轮换凭证,同时减少对下游可用性的任何潜在影响。

此示例介绍了如何在不要求容器重启的情况下在容器中轮换使用 AWS Secrets Manager 保护的密钥。此外,这种模式通过使用 Secrets Manager 客户端缓存组件减少了对 Secrets Manager 的凭证查找次数。当您使用客户端缓存组件刷新应用程序中的凭证时,无需重新启动容器即可获取轮换后的凭证。

这种方法适用于 Amazon Elastic Kubernetes Service (Amazon EKS)和 Amazon Elastic Container Service (Amazon ECS)。

涵盖了两种场景。在单用户场景中,通过检测过期的凭证,在秘密轮转时刷新数据库凭证。指示凭证缓存刷新密钥,然后应用程序重新建立数据库连接。客户端缓存组件在应用程序中缓存凭证,有助于避免在每次凭证查询时联系 Secrets Manager。凭证在应用程序内轮换,无需通过重启容器来强制刷新凭证。

第二种情况是通过在两个用户之间交替轮换密钥。拥有两名活跃用户可以减少停机的可能性,因为一名用户的凭证始终处于活动状态。当您的大型部署中的集群中可能存在较小的凭证更新传播延迟时,双用户凭证轮换会很有用。

先决条件和限制

先决条件

  • 一个有效的 Amazon Web Services account。

  • 在 Amazon EKS 或 Amazon ECS 的容器中运行的应用程序。

  • 凭证存储在 Secrets Manager 中,且启用轮换

  • 如果部署双用户解决方案,则存储在 Secrets Manager 中的第二组凭证。代码示例可以在 GitHub 存储库 aws-secrets-manager-rotation- lambdas 中找到。

  • Amazon Aurora 数据库。

限制

架构

目标架构

场景 1 - 轮换单个用户的凭证

此图表显示从 Secrets Manager 到应用程序以及 Fargate 到 Aurora 的流程。

在第一种情况下,Secrets Manager 会定期轮换单个数据库凭证。应用程序容器在 Fargate 中运行。建立第一个数据库连接后,应用程序容器会获取 Aurora 的数据库凭证。然后,Secrets Manager 缓存组件会缓存凭证,以便将来建立连接。轮换期过后,凭证将过期,数据库将返回身份验证错误。然后,应用程序通过 Secrets Manager 客户端缓存组件获取轮换后的凭证,使缓存失效,并更新凭证缓存。

在这种情况下,在轮换凭证且过时的连接使用过时的凭证时,中断可能最小。这个问题可通过使用双用户场景来解决。

场景 2 - 轮换两个用户的凭证

该图显示了 Fargate 集群、Aurora 和 Secrets Manager 以及 Alice 和 Bob 的凭证。

在第二种情况下,Secrets Manager 会定期轮换两个数据库用户凭证(Alice 和 Bob)。应用程序容器在 Fargate 集群运行。建立第一个数据库连接后,应用程序容器将获取第一个用户 (Alice) 的 Aurora 数据库凭证。然后,Secrets Manager 缓存组件会缓存凭证,以便将来建立连接。

尽管有两个用户和凭证,但只有一个有效的凭证由 Secrets Manager 管理。在这种情况下,缓存组件会定期过期并获取最新的凭证。如果 Secrets Manager 轮换周期长于缓存超时时间,则缓存组件会为第二个用户 (Bob) 获取轮换后的凭证。例如如果缓存过期时间以分钟为单位,轮换周期以天为单位,则缓存组件将在定期刷新缓存时获取新的凭证。通过这种方式,可以最大限度地减少停机时间,因为每个用户的凭证在一次 Secrets Manager 轮换中都处于活动状态。

自动化和扩缩

您可以使用 AWS 通过使用基础设施即代码 CloudFormation来部署此模式。这将生成和创建应用程序容器,创建 Fargate 任务,将容器部署至 Fargate 中,并使用 Aurora 设置和配置 Secrets Manager。有关 step-by-step 部署说明,请参阅自述文件。

工具

工具

  • AWS Secrets Manager 启用将硬编码凭证(包括密码)替换为对 Secrets Manager 的 API 调用,以便检索密钥。由于 Secrets Manager 可以根据计划自动轮换密钥,因此您可将长期密钥替换为短期密钥,从而降低泄露的风险。

  • Docker 帮助开发人员将任何应用程序作为轻量级、便携且自给自足的容器打包、运输和运行。

代码

Python 代码示例

此模式使用 Secrets Manager 的 Python 客户端缓存组件在建立数据库连接时检索身份验证凭证。客户端缓存组件有助于避免每次联系 Secrets Manager。

现在,当轮换周期过后,缓存的凭证将过期,并且连接到数据库将导致身份验证错误。对于 MySQL,身份验证错误代码为 1045。此示例使用适用于 MySQL 的 Amazon Aurora,但您可使用其他引擎,例如 PostgreSQL。出现身份验证错误时,数据库连接异常处理代码将捕获错误。然后,它通知 Secrets Manager 客户端缓存组件刷新密钥,然后重新进行身份验证,并重新建立数据库连接。如果您使用 PostgreSQL 或其他引擎,则必须查找相应的身份验证错误代码。

容器应用程序现在可以使用轮换后的密码更新数据库密码,而无需重新启动容器。

将以下代码放入处理数据库连接的应用程序代码中。此示例使用 Django,它使用数据库包装器对数据库后端进行子类化,用于连接。如果您使用不同的编程语言或数据库连接库,请参阅您的数据库连接库以查看如何子类化数据库连接检索。

    def get_new_connection(self, conn_params):         try:             logger.info("get connection")             databasecredentials.get_conn_params_from_secrets_manager(conn_params)             conn =super(DatabaseWrapper,self).get_new_connection(conn_params)             return conn         except MySQLdb.OperationalError as e:             error_code=e.args[0]             if error_code!=1045:                 raise e               logger.info("Authentication error. Going to refresh secret and try again.")             databasecredentials.refresh_now()             databasecredentials.get_conn_params_from_secrets_manager(conn_params)             conn=super(DatabaseWrapper,self).get_new_connection(conn_params)             logger.info("Successfully refreshed secret and established new database connection.")             return conn

AWS CloudFormation 和 Python 代码

操作说明

任务描述所需技能

安装缓存组件。

下载并安装适用于 Python 的 Secrets Manager 客户端缓存组件。有关下载链接,请参阅相关资源部分。

开发人员

缓存工作凭证。

使用 Secrets Manager 客户端缓存组件在本地缓存工作凭证。

开发人员

更新应用程序代码,以在数据库连接出现未经授权的错误时刷新凭证。

更新应用程序代码,以使用 Secrets Manager 获取和刷新数据库凭证。添加处理未经授权的错误代码的逻辑,然后获取新轮换的凭证。请参阅 Python 代码示例部分。

开发人员

相关资源

创建 Secrets Manager 密钥

创建 Amazon Aurora 集群

创建 Amazon ECS 组件

下载和安装 Secrets Manager 客户端缓存组件

附件

要访问与此文档相关联的其他内容,请解压以下文件:attachment.zip