使用最低权限 Amazon SQS 策略和 Amazon KMS 密钥政策管理对加密 Amazon SQS 队列的访问权限 - Amazon Simple Queue Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

使用最低权限 Amazon SQS 策略和 Amazon KMS 密钥政策管理对加密 Amazon SQS 队列的访问权限

您可以使用 Amazon SQS 通过与 Amazon Key Management Service (KMS) 集成的服务器端加密 (SSE) 在应用程序之间交换敏感数据。通过与 Amazon SQS 和 Amazon KMS 的集成,您可以集中管理保护 Amazon SQS 的密钥以及保护您的其他 Amazon 资源的密钥。

多个 Amazon 服务可以充当向 Amazon SQS 发送事件的事件源。要使事件源能够访问加密的 Amazon SQS 队列,您需要使用客户托管 Amazon KMS 密钥配置队列。然后,使用密钥政策允许服务使用所需的 Amazon KMS API 方法。该服务还需要对访问进行身份验证的权限才能使队列发送事件。您可以使用 Amazon SQS 策略来实现这一目标,该策略是一种基于资源的策略,可用于控制对 Amazon SQS 队列及其数据的访问。

以下各节提供有关如何通过 Amazon SQS 策略和 Amazon KMS 密钥政策控制对加密 Amazon SQS 队列的访问权限的信息。本指南中的策略将帮助您实现最低权限

本指南还介绍了基于资源的策略如何使用 aws:SourceArnaws:SourceAccountaws:PrincipalOrgID 全局 IAM 条件上下文键来解决混淆代理问题

概述

在本主题中,我们将为您介绍一个常见使用案例,以说明如何构建密钥政策和 Amazon SQS 队列策略。此使用案例如下图所示。


				将 Amazon SNS 消息发布到 Amazon SQS。

在此示例中,消息创建者是 Amazon Simple Notification Service (SNS) 主题,该主题配置为将消息扇出到您的加密 Amazon SQS 队列。消息使用者是一项计算服务,例如 Amazon Lambda 函数、Amazon Elastic Compute Cloud (EC2) 实例或 Amazon Fargate 容器。然后,将您的 Amazon SQS 队列配置为将失败的消息发送到死信队列 (DLQ)。这对于调试应用程序或消息传递系统非常有用,因为 DLQ 允许您隔离未使用的消息,以确定其处理失败的原因。在本主题中定义的解决方案中,使用 Lambda 函数等计算服务来处理存储在 Amazon SQS 队列中的消息。如果消息使用者位于虚拟私有云(VPC)中,则本指南中包含的 DenyReceivingIfNotThroughVPCE 策略语句允许您将消息接收限制在该特定 VPC 上。

注意

本指南仅以策略语句的形式包含所需的 IAM 权限。要构造策略,您需要将语句添加到您的 Amazon SQS 策略或 Amazon KMS 密钥政策中。本指南不提供有关如何创建 Amazon SQS 队列或 Amazon KMS 密钥的说明。有关如何创建这些资源的说明,请参阅创建 Amazon SQS 队列创建密钥

本指南中定义的 Amazon SQS 策略不支持将消息直接重新发送到相同或不同的 Amazon SQS 队列。

最低权限 Amazon SQS 密钥政策

在本节中,我们将介绍用于加密 Amazon SQS 队列的客户托管密钥在 Amazon KMS 中所需的最低权限。使用这些权限,您可以将访问权限限制为仅限目标实体,同时实施最低权限。密钥政策必须包含以下策略语句,我们将通过以下资源详细描述这些语句:

向 Amazon KMS 密钥授予管理员权限

要创建 Amazon KMS 密钥,您需要为用于部署 Amazon KMS 密钥的 IAM 角色提供 Amazon KMS 管理员权限。这些管理员权限在以下 AllowKeyAdminPermissions 策略语句中进行了定义。向 Amazon KMS 密钥政策添加此语句时,请务必将 <admin-role ARN> 替换为用于部署 Amazon KMS 密钥、管理 Amazon KMS 密钥(或两者兼而有之)的 IAM 角色的 Amazon 资源名称 (ARN)。这可以是您部署管道的 IAM 角色,也可以是 Amazon Organizations您组织的管理员角色

{ "Sid": "AllowKeyAdminPermissions", "Effect": "Allow", "Principal": { "AWS": [ "<admin-role ARN>" ] }, "Action": [ "kms:Create*", "kms:Describe*", "kms:Enable*", "kms:List*", "kms:Put*", "kms:Update*", "kms:Revoke*", "kms:Disable*", "kms:Get*", "kms:Delete*", "kms:TagResource", "kms:UntagResource", "kms:ScheduleKeyDeletion", "kms:CancelKeyDeletion" ], "Resource": "*" }
注意

在 Amazon KMS 密钥政策中,Resource 元素的值需要为 *,表示“这个 Amazon KMS 密钥”。星号 (*) 用于标识密钥政策附加到的 Amazon KMS 密钥。

授予对密钥元数据的只读访问权限

要向其他 IAM 角色授予对您密钥元数据的只读访问权限,请将 AllowReadAccessToKeyMetaData 语句添加到您的密钥政策中。例如,以下语句允许您列出账户中的所有 Amazon KMS 密钥以供审计。此语句授予 Amazon 根用户对密钥元数据的只读访问权限。因此,账户中的任何 IAM 主体只要其基于身份的策略具有以下语句中列出的权限,就可以访问密钥元数据:kms:Describe*kms:Get*kms:List*。确保将 <account-ID> 替换为您自己的信息。

{ "Sid": "AllowReadAcesssToKeyMetaData", "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::<accountID>:root" ] }, "Action": [ "kms:Describe*", "kms:Get*", "kms:List*" ], "Resource": "*" }

授予 Amazon SNS KMS 对 Amazon SNS 向队列发布消息的权限

要允许您的 Amazon SNS 主题向加密的 Amazon SQS 队列发布消息,请将 AllowSNSToSendToSQS 策略语句添加到您的密钥政策中。此语句会授予 Amazon SNS 使用 Amazon KMS 密钥向 Amazon SNS 队列发布的权限。确保将 <account-ID> 替换为您自己的信息。

注意

语句中的 Condition 会限制仅在同一 Amazon 账户中使用 Amazon SNS 服务的权限。

{ "Sid": "AllowSNSToSendToSQS", "Effect": "Allow", "Principal": { "Service": [ "sns.amazonaws.com" ] }, "Action": [ "kms:GenerateDataKey", "kms:Decrypt" ], "Resource": "*", "Condition": { "StringEquals": { "aws:SourceAccount": "<account-id>" } } }

允许使用者解密来自队列的消息

以下 AllowConsumersToReceiveFromTheQueue 语句向 Amazon SQS 消息使用者授予解密从加密 Amazon SQS 队列收到的消息所需的权限。附加策略语句时,将 <consumer's runtime role ARN> 替换为消息使用者的 IAM 运行时角色 ARN。

{ "Sid": "AllowConsumersToReceiveFromTheQueue", "Effect": "Allow", "Principal": { "AWS": [ "<consumer's execution role ARN>" ] }, "Action": [ "kms:Decrypt" ], "Resource": "*" }

最低权限 Amazon SQS 策略

本节将引导您了解本指南所涵盖的使用案例的最低权限 Amazon SQS 队列策略(例如,从 Amazon SNS 到 Amazon SQS)。定义的策略旨在通过混合使用 DenyAllow 语句来防止意外访问。Allow 语句会向目标实体或实体授予访问权限。Deny 语句可防止其他意外实体访问 Amazon SQS 队列,同时将目标实体排除在策略条件之外。

Amazon SQS 策略包括以下语句,我们在下面对其进行了详细描述:

限制 Amazon SQS 管理权限

以下 RestrictAdminQueueActions 策略语句将 Amazon SQS 管理权限限制为仅限于您用于部署队列、管理队列或两者兼而有之的 IAM 角色。确保将 <placeholder values> 替换为您自己的信息。指定用于部署 Amazon SQS 队列的 IAM 角色的 ARN,以及应具有 Amazon SQS 管理权限的任何管理员角色的 ARN。

{ "Sid": "RestrictAdminQueueActions", "Effect": "Deny", "Principal": { "AWS": "*" }, "Action": [ "sqs:AddPermission", "sqs:DeleteQueue", "sqs:RemovePermission", "sqs:SetQueueAttributes" ], "Resource": "<SQS Queue ARN>", "Condition": { "StringNotLike": { "aws:PrincipalARN": [ "arn:aws:iam::<account-id>:role/<deployment-role-name>", "<admin-role ARN>" ] } } }

限制指定组织的 Amazon SQS 队列操作

要帮助保护您的 Amazon SQS 资源不被外部访问(由 Amazon 组织外部实体访问),请使用以下语句。此语句会限制您在 Condition 中指定的组织访问 Amazon SQS 队列。确保将 <SQS queue ARN> 替换为用于部署 Amazon SQS 队列的 IAM 角色的 ARN;将 <org-id> 替换为您的组织 ID。

{ "Sid": "DenyQueueActionsOutsideOrg", "Effect": "Deny", "Principal": { "AWS": "*" }, "Action": [ "sqs:AddPermission", "sqs:ChangeMessageVisibility", "sqs:DeleteQueue", "sqs:RemovePermission", "sqs:SetQueueAttributes", "sqs:ReceiveMessage" ], "Resource": "<SQS queue ARN>", "Condition": { "StringNotEquals": { "aws:PrincipalOrgID": [ "<org-id>" ] } } }

向使用者授予 Amazon SQS 权限

要接收来自 Amazon SQS 队列的消息,您需要向消息使用者提供必要的权限。以下策略语句会向您指定的使用者授予使用来自 Amazon SQS 队列的消息所需的权限。将该语句添加到您的 Amazon SQS 策略时,请务必将 <consumer's IAM runtime role ARN> 替换为使用者使用的 IAM 运行时角色的 ARN;将 <SQS queue ARN> 替换为用于部署 Amazon SQS 队列的 IAM 角色的 ARN。

{ "Sid": "AllowConsumersToReceiveFromTheQueue", "Effect": "Allow", "Principal": { "AWS": "<consumer's IAM execution role ARN>" }, "Action": [ "sqs:ChangeMessageVisibility", "sqs:DeleteMessage", "sqs:GetQueueAttributes", "sqs:ReceiveMessage" ], "Resource": "<SQS queue ARN>" }

要防止其他实体接收来自 Amazon SQS 队列的消息,请将 DenyOtherConsumersFromReceiving 语句添加到 Amazon SQS 队列策略中。此语句会限制消息仅供您指定的使用者使用,不允许其他使用者访问,即使他们的身份权限会授予他们访问权限,也是如此。确保将 <SQS queue ARN><consumer’s runtime role ARN> 替换为您自己的信息。

{ "Sid": "DenyOtherConsumersFromReceiving", "Effect": "Deny", "Principal": { "AWS": "*" }, "Action": [ "sqs:ChangeMessageVisibility", "sqs:DeleteMessage", "sqs:ReceiveMessage" ], "Resource": "<SQS queue ARN>", "Condition": { "StringNotLike": { "aws:PrincipalARN": "<consumer's execution role ARN>" } } }

实施传输中加密

以下 DenyUnsecureTransport 策略语句强制使用者和创建者使用安全通道(TLS 连接)发送和接收来自 Amazon SQS 队列的消息。确保将 <SQS queue ARN> 替换为用于部署 Amazon SQS 队列的 IAM 角色的 ARN。

{ "Sid": "DenyUnsecureTransport", "Effect": "Deny", "Principal": { "AWS": "*" }, "Action": [ "sqs:ReceiveMessage", "sqs:SendMessage" ], "Resource": "<SQS queue ARN>", "Condition": { "Bool": { "aws:SecureTransport": "false" } } }

将消息传输限制为特定的 Amazon SNS 主题

以下 AllowSNSToSendToTheQueue 策略语句允许指定的 Amazon SNS 主题向 Amazon SQS 队列发送消息。确保将 <SQS queue ARN> 替换为用于部署 Amazon SQS 队列的 IAM 角色的 ARN;将 <SNS topic ARN> 替换为 Amazon SNS 主题 ARN。

{ "Sid": "AllowSNSToSendToTheQueue", "Effect": "Allow", "Principal": { "Service": "sns.amazonaws.com" }, "Action": "sqs:SendMessage", "Resource": "<SQS queue ARN>", "Condition": { "ArnLike": { "aws:SourceArn": "<SNS topic ARN>" } } }

以下 DenyAllProducersExceptSNSFromSending 策略语句禁止其他创建者向队列发送消息。将 <SQS queue ARN><SNS topic ARN> 替换为您自己的信息。

{ "Sid": "DenyAllProducersExceptSNSFromSending", "Effect": "Deny", "Principal": { "AWS": "*" }, "Action": "sqs:SendMessage", "Resource": "<SQS queue ARN>", "Condition": { "ArnNotLike": { "aws:SourceArn": "<SNS topic ARN>" } } }

(可选)将消息接收限制为特定 VPC 端点

要限制仅向特定的 VPC 端点发送消息,请在您的 Amazon SQS 队列策略中添加以下策略语句。除非消息来自所需的 VPC 端点,否则此语句可防止消息使用者接收来自队列的消息。将 <SQS queue ARN> 替换为用于部署 Amazon SQS 队列的 IAM 角色的 ARN;将 <vpce_id> 替换为 VPC 端点 ID。

{ "Sid": "DenyReceivingIfNotThroughVPCE", "Effect": "Deny", "Principal": "*", "Action": [ "sqs:ReceiveMessage" ], "Resource": "<SQS queue ARN>", "Condition": { "StringNotEquals": { "aws:sourceVpce": "<vpce id>" } } }

死信队列的 Amazon SQS 策略语句

将以下策略语句(由其语句 ID 标识)添加到您的 DLQ 访问策略中:

  • RestrictAdminQueueActions

  • DenyQueueActionsOutsideOrg

  • AllowConsumersToReceiveFromTheQueue

  • DenyOtherConsumersFromReceiving

  • DenyUnsecureTransport

除了将上述策略语句添加到 DLQ 访问策略外,您还应添加一条语句,以限制向 Amazon SQS 队列传输消息,如下一节所述。

限制向 Amazon SQS 队列传输消息

要限制同一账户只能访问 Amazon SQS 队列,请在 DLQ 队列策略中添加以下 DenyAnyProducersExceptSQS 策略语句。此语句不会将消息传输限制到特定队列,因为您需要在创建主队列之前部署 DLQ,因此在创建 DLQ 时不会知道 Amazon SQS ARN。如果您需要将访问权限限制为仅一个 Amazon SQS 队列,请在知道时使用您的 Amazon SQS 源队列的 ARN 修改 Condition 中的 aws:SourceArn

{ "Sid": "DenyAnyProducersExceptSQS", "Effect": "Deny", "Principal": { "AWS": "*" }, "Action": "sqs:SendMessage", "Resource": "<SQS DLQ ARN>", "Condition": { "ArnNotLike": { "aws:SourceArn": "arn:aws:sqs:<region>:<account-id>:*" } } }
重要

本指南中定义的 Amazon SQS 队列策略不会将 sqs:PurgeQueue 操作限制在某个 IAM 角色或多个角色。sqs:PurgeQueue 操作允许您删除 Amazon SQS 队列中的所有消息。您也可以使用此操作更改消息格式,而无需替换 Amazon SQS 队列。调试应用程序时,您可以清除 Amazon SQS 队列以删除可能错误的消息。测试应用程序时,您可以通过 Amazon SQS 队列发送大量消息,然后在进入生产环境之前清除队列以重新开始。之所以不将此操作限制为某个角色,是因为在部署 Amazon SQS 队列时可能不知道此角色。您需要将此权限添加到角色基于身份的策略中,才能清除队列。

防范跨服务混淆代理问题

混淆代理问题是一个安全问题,即没有执行操作权限的实体可能会迫使更具权限的实体执行该操作。为了防止这种情况,如果您为账户中的资源提供第三方(称为跨账户)或其他 Amazon 服务(称为跨服务)的访问权限,则 Amazon 会提供用于保护您账户的工具。本节中的策略语句可以帮助您防范跨服务混淆代理问题。

一个服务(呼叫服务)调用另一项服务(所谓的服务)时,可能会发生跨服务模拟。可以操纵调用服务以使用其权限对另一个客户的资源进行操作,否则该服务不应有访问权限。为了帮助防范此问题,本文中定义的基于资源的策略使用 aws:SourceArnaws:SourceAccountaws:PrincipalOrgID 全局 IAM 条件上下文键。这会将服务拥有的权限限制在 Amazon Organizations 中的特定资源、特定账户或特定组织。

使用 IAM Access Analyzer 查看跨账户访问权限

您可以使用 Amazon IAM Access Analyzer 查看您的 Amazon SQS 队列策略和 Amazon KMS 密钥政策,并在 Amazon SQS 队列或 Amazon KMS 密钥授予外部实体访问权限时提醒您。IAM Access Analyzer 帮助标识您组织中的资源和与信任区域之外的实体共享的账户。此信任区域可以是您在启用 IAM Access Analyzer 时指定的 Amazon Organizations 内的 Amazon 账户或组织。

IAM Access Analyzer 使用基于逻辑的推理来分析 Amazon 环境中基于资源的策略,确定与外部主体共享的资源。对于在您的信任区域外共享的资源的每个实例,Access Analyzer 都会生成一个调查结果。调查结果包括有关访问权限以及该访问权限授予到的外部主体的信息。您可以查看调查结果,以确定该访问权限是按计划授予且安全,还是计划外的访问权限并存在安全风险。对于任何意外访问,请查看受影响的策略并进行修复。有关 Amazon IAM Access Analyzer 如何标识对您的 Amazon 资源的意外访问的更多信息,请参阅此博客文章

有关 Amazon IAM Access Analyzer 的更多信息,请参阅 Amazon IAM Access Analyzer 文档