Lambda 轮换函数 - Amazon Secrets Manager
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

Lambda 轮换函数

通过 Lambda 函数进行轮换 中,Lambda 函数完成轮换密钥的工作。轮换过程中,Secrets Manager 用暂存标注标注密钥的不同版本。

如果 Secrets Manager 没有为您的密钥类型提供轮换函数模板,则可以创建轮换函数。编写轮换函数时,请按照每个步骤的指导进行操作。

编写自己的轮换函数的技巧
  • 使用常规轮换模板作为编写自己的轮换函数的起点。

  • 编写函数时,请谨慎包括调试或日志记录语句。鉴于这些语句可能会导致函数中的信息写入 Amazon CloudWatch 中,因此您需要确保日志不包含开发期间收集的任何敏感信息。

    有关日志语句的示例,请参阅 Amazon Secrets Manager 轮换函数模板 源代码。

  • 出于安全考虑,Secrets Manager 仅允许 Lambda 轮换函数直接轮换密钥。轮换函数无法调用第二个 Lambda 函数来轮换密钥。

  • 有关调试建议,请参阅测试和调试无服务器应用程序

  • 例如,如果使用外部二进制文件和库来连接资源,则必须对其管理和修补,并使其保持最新状态。

  • 将轮换函数连同任何所需的依赖项一同保存在 ZIP 文件 my-function.zip 中。

轮换函数的四个步骤

create_secret:创建密钥的新版本

方法 create_secret 首先通过使用传入的 ClientRequestToken 调用 get_secret_value 来检查密钥是否存在。如果没有密钥,它会使用 create_secret 创建一个新密钥,并将令牌作为 VersionId。然后它使用 get_random_password 生成一个新的密钥值。接下来,它调用 put_secret_value 以将其与暂存标签 AWSPENDING 一起存储。将新的密钥值存储在 AWSPENDING 中有助于确保幂等性。如果由于任何原因轮换失败,您可以在后续调用中引用该密钥值。请参阅如何使我的 Lambda 函数具有幂等性

编写自己的轮换函数的技巧
  • 确保新的密钥值仅包含对数据库或服务有效的字符。使用 ExcludeCharacters 参数排除字符。

  • 测试函数时,使用 Amazon CLI 查看版本阶段:调用 describe-secret 并查看 VersionIdsToStages

  • 对于 Amazon RDS MySQL,在交替用户轮换中,Secrets Manager 会创建一个名称不超过 16 个字符的克隆用户。您可以修改轮换函数以允许使用更长的用户名。MySQL 5.7 及更高版本支持最多 32 个字符的用户名,但 Secrets Manager 会在用户名末尾附加“_clone”(六个字符),因此用户名最多必须保持在 26 个字符以内。

set_secret:更改数据库或服务中的凭证

方法 set_secret 更改数据库或服务中的凭证以匹配密钥的 AWSPENDING 版本中的新密钥值。

编写自己的轮换函数的技巧
  • 如果将语句传递给解释语句的服务(如数据库),请使用查询参数化。有关更多信息,请参阅 OWASP 网站上的 Query Parameterization Cheat Sheet

  • 轮换函数作为特权代理,有权访问和修改 Secrets Manager 密钥和目标资源中的客户凭证。为防范潜在的混淆代理攻击,您需要确保攻击者无法使用该函数访问其他资源。在更新凭证之前:

    • 检查密钥 AWSCURRENT 版本中的凭证是否有效。如果 AWSCURRENT 凭证无效,请放弃轮换尝试。

    • 检查 AWSCURRENTAWSPENDING 密钥值是否适用于同一资源。对于用户名和密码,检查 AWSCURRENTAWSPENDING 用户名是否相同。

    • 检查目标服务资源是否相同。对于数据库,检查 AWSCURRENTAWSPENDING 主机名是否相同。

  • 在极少数情况下,您可能希望为数据库自定义现有轮换功能。例如,对于交替用户轮换,Secrets Manager 通过复制第一个用户的运行时配置参数来创建克隆用户。如果要包含更多属性,或更改授予克隆用户的属性,则需要更新 set_secret 函数中的代码。

test_secret:测试新的密钥版本

然后,Lambda 轮换函数将使用该密钥来访问数据库或服务,从而测试密钥的 AWSPENDING 版本。基于 轮换函数模板 测试的轮换函数使用读取访问权限测试新的密钥。

finish_secret:完成轮换

最后,Lambda 轮换函数将标签 AWSCURRENT 从之前的密钥版本移动到此版本,这将同时在同一 API 调用中移除 AWSPENDING 标签。Secrets Manager 添加 AWSPREVIOUS 暂存标注到以前的版本,以便您保留密钥的上次已知良好的版本。

方法 finish_secret 使用 update_secret_version_stage 将暂存标签 AWSCURRENT 从早期密钥版本移动到新的密钥版本。Secrets Manager 会将 AWSPREVIOUS 暂存标签自动添加到早期版本,以便您保留上次已知良好的密钥版本。

编写自己的轮换函数的技巧
  • 在此之前请不要移除 AWSPENDING,也不要使用单独的 API 调用将其移除,因为这可能向 Secrets Manager 表明轮换未成功完成。Secrets Manager 添加 AWSPREVIOUS 暂存标注到以前的版本,以便您保留密钥的上次已知良好的版本。

成功轮换后,AWSPENDING 暂存标签可能附加到与 AWSCURRENT 版本相同的版本,也可能未附加到任何版本。如果 AWSPENDING 暂存标签存在但未附加到与 AWSCURRENT 相同的版本,则以后对轮换的任何调用都假定先前的轮换请求仍在进行中并返回错误。轮换不成功时,AWSPENDING 暂存标签可能会附加到空密钥版本。有关更多信息,请参阅 轮换问题排查