Amazon Secrets Manager 密钥轮换问题排查 - Amazon Secrets Manager
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

Amazon Secrets Manager 密钥轮换问题排查

使用此处的信息可帮助您诊断和修复在轮换 Secrets Manager 密钥时可能遇到的常见错误。

在 Amazon Secrets Manager 中轮换密钥要求使用 Lambda 函数来定义如何与拥有密钥的数据库或服务交互。

我想查找我的 Lambda 轮换函数的诊断日志

在轮换函数没有按预期方式运行时,应先检查 CloudWatch 日志。Secrets Manager 提供 Lambda 轮换函数的模板代码,此代码会将错误消息写入到 CloudWatch 日志中。

检查您的 Lambda 函数的 CloudWatch 日志

  1. https://console.aws.amazon.com/secretsmanager/ 打开 Secrets Manager 控制台

  2. 选择您的密钥,然后在详细信息页面上的 Rotation configuration(轮换配置)下,选择 Lambda 轮换函数。Lambda 控制台将打开。

  3. 监控选项卡上,选择日志,然后选择查看 CloudWatch 中的日志

    将打开 CloudWatch 控制台并显示您的函数的日志。

在尝试为我的密钥配置轮换时,出现“访问被拒绝”错误

在将 Lambda 轮换函数的 Amazon Resource Name (ARN) 添加到密钥时,Secrets Manager 会检查该函数的权限。该函数的角色策略必须为 Secrets Manager 服务委托人授予 secretsmanager.amazonaws.com 权限才能调用该函数 (lambda:InvokeFunction)。

可以运行以下 Amazon CLI 命令来添加此权限:

aws lambda add-permission --function-name ARN_of_lambda_function --principal secretsmanager.amazonaws.com --action lambda:InvokeFunction --statement-id SecretsManagerAccess

在启用轮换后,我的第一次轮换失败

在为使用 "master" 密钥更改受保护服务上的凭证的密钥启用轮换时,Secrets Manager 自动配置轮换所需的大多数元素。不过,Secrets Manager 无法自动为 Lambda 函数授予读取控制密钥的权限。您必须自行明确授予该权限。具体来说,您需要将权限添加到附加到 IAM 角色(附加到 Lambda 轮换函数)的策略以授予该权限。该策略必须包含以下语句(这只是一个语句,而不是完整策略)。有关完整策略,请参阅CloudTrail 在轮换期间显示“访问被拒绝”错误一节中的第二个示例策略。

{ "Sid": "AllowAccessToMasterSecret", "Effect": "Allow", "Action": "secretsmanager:GetSecretValue", "Resource": "ARN_of_master_secret" }

这允许轮换函数从控制密钥中检索凭证,随后使用主密钥凭证更改轮换密钥的凭证。

因为密钥值未按轮换函数预期进行格式化,所以轮换失败。

如果您没有按照轮换函数的预期,将密钥值格式化为 JSON 结构,则轮换也可能失败。您使用的轮换函数决定了所使用的格式。有关每个轮换函数对密钥值要求的详细信息,请参阅Secrets Manager 轮换函数模板相关轮换函数下方的预期 SecretString 值条目。

例如,如果您使用 MySQL 单一用户轮换函数,SecretString 文本结构必须如下所示:

{ "engine": "mysql", "host": "<required: instance host name/resolvable DNS name>", "username": "<required: username>", "password": "<required: password>", "dbname": "<optional: database name. If not specified, defaults to None>", "port": "<optional: TCP port number. If not specified, defaults to 3306>" }

Secrets Manager 指出我已成功配置轮换,但未轮换密码

如果网络配置问题导致 Lambda 函数无法与受保护数据库/服务或 Secrets Manager 服务终端节点(位于公有 Internet 上)通信,则可能出现这种情况。如果您在 VPC 中运行数据库或服务,则为配置使用以下两个选项之一:

  • 使 Amazon VPC 中的数据库可使用 Amazon EC2 弹性 IP 地址进行公开访问。

  • 配置 Lambda 轮换函数以在与数据库/服务相同的 VPC 中运行。

  • 如果您的 VPC 无法访问公有 Internet(例如,如果您没有为访问配置具有 NAT 网关的 VPC),则您必须为该 VPC 配置用于 Secrets Manager 的私有服务终端节点,并且可从 VPC 内访问该终端节点。

要确定这种类型的配置问题是否导致轮换失败,请执行以下步骤。

诊断轮换函数和数据库或 Secrets Manager 之间的连接问题

  1. 通过执行我想查找我的 Lambda 轮换函数的诊断日志过程打开日志。

  2. 检查日志文件以查找指示 Lambda 函数和 Amazon Secrets Manager 服务或 Lambda 函数和受保护数据库或服务之间发生超时的信息。

  3. 有关如何配置服务和 Lambda 函数以在 VPC 环境中进行互操作的信息,请参阅 Amazon Lambda 开发人员指南Amazon Virtual Private Cloud 文档

轮换失败,并显示“内部故障”错误消息

当您的轮换函数生成一个新密码并尝试将该密码作为一组新的凭证存储在数据库中时,您必须确保密码仅包含对指定数据库有效的字符。如果密码包含数据库引擎不接受的字符,则为用户设置密码的尝试将失败。此错误显示为“内部故障”。有关可使用的字符的列表,请参阅数据库文档。然后在 GetRandomPassword API 调用中使用 ExcludeCharacters 参数,排除所有其他项。

CloudTrail 在轮换期间显示“访问被拒绝”错误

在配置轮换时,如果让 Secrets Manager 为您创建轮换函数,则 Secrets Manager 会自动为其提供附加到该函数的 IAM 角色的策略以授予相应的权限。如果您创建自定义函数,则需要为附加到该函数的角色授予以下权限。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "secretsmanager:DescribeSecret", "secretsmanager:GetRandomPassword", "secretsmanager:GetSecretValue", "secretsmanager:PutSecretValue", "secretsmanager:UpdateSecretVersionStage" ], "Resource": "*" } ] }

此外,如果您的轮换使用单独的控制密钥凭证轮换该密钥,您还必须授予权限以从控制密钥中检索密钥值。有关更多信息,请参阅在启用轮换后,我的第一次轮换失败。组合的策略可能类似于以下内容:

{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAccessToSecretsManagerAPIs", "Effect": "Allow", "Action": [ "secretsmanager:DescribeSecret", "secretsmanager:GetRandomPassword", "secretsmanager:GetSecretValue", "secretsmanager:PutSecretValue", "secretsmanager:UpdateSecretVersionStage" ], "Resource": "*" }, { "Sid": "AllowAccessToMasterSecret", "Effect": "Allow", "Action": "secretsmanager:GetSecretValue", "Resource": "MasterSecretArn" } ] }

我的数据库需要 SSL/TLS 连接,但 Lambda 轮换函数没有使用 SSL/TLS

如果您的数据库需要 SSL/TLS 连接,但轮换函数使用了未加密的连接,则轮换函数无法连接到数据库,并且轮换将失败。在 Amazon CloudWatch 中,轮换函数会记录以下错误之一:

  • 对于单用户轮换:

    setSecret: Unable to log into database with previous, current, or pending secret of secret arn SecretArn

  • 对于多用户轮换:

    setSecret: Unable to log into database using current credentials for secret SecretArn

适用于 Amazon RDS(Oracle 除外)和 Amazon DocumentDB 的轮换函数将自动使用安全套接字层 (SSL) 或传输层安全性 (TLS) 来连接到数据库(如果可用)。否则,他们将使用未加密的连接。

注意

如果您在 2021 年 12 月 20 日之前设置了自动密钥轮换,则您的轮换函数可能基于不支持 SSL/TLS 的较旧模板。为了支持使用 SSL/TLS 的连接,您需要重新创建您的轮换函数

确定您的轮换函数的创建时间

  1. 在 Secrets Manager 控制台 https://console.aws.amazon.com/secretsmanager/ 中,打开您的密钥。在 Rotation configuration(轮换配置)中的 Lambda rotation function(Lambda 轮换函数)下,您将看到 Lambda function ARN(Lambda 函数 ARN),例如,arn:aws:lambda:aws-region:123456789012:function:SecretsManagerMyRotationFunction。在此示例 SecretsManagerMyRotationFunction 中,从 ARN 末尾复制函数名称。

  2. 在 Amazon Lambda 控制台 https://console.aws.amazon.com/lambda/ 中的 Functions(函数)下,将您的 Lambda 函数名称粘贴到搜索框中,按 Enter 键,然后选择相应的 Lambda 函数。

  3. 在函数详细信息页面中,在 Configuration(配置)选项卡上的 Tags(标签)下,复制键 aws:cloudformation:stack-name 旁边的值。

  4. 在 Amazon CloudFormation 控制台 https://console.aws.amazon.com/cloudformation 中的 Stacks(堆栈)下,将键值粘贴在搜索框中,然后按 Enter 键。

  5. 堆栈列表将进行筛选,以便只显示创建 Lambda 轮换函数的堆栈。在 Created date(创建日期)列中,查看堆栈的创建日期。这是 Lambda 轮换函数的创建日期。