亚马逊AWS官方博客

使用可扩展的控件让亚马逊云科技服务访问您的资源

有时,您要配置亚马逊云科技以访问其他服务中的资源。例如,您可以配置 Amazon CloudTrail(一种监控亚马逊云科技基础架构中账户活动的服务),以将日志数据存储到 Amazon Simple Storage Service(Amazon S3) 中的存储桶。执行此操作时,您需要确保该服务仅代表您访问您的资源—而不希望不受信任的实体能够使用该服务访问您的资源。在今天之前,您可以使用两个 Amazon Identity and Access Management(IAM) 条件密钥(即 aws:SourceAccountaws:SourceArn)来实现。您可以使用这些条件密钥来帮助确保服务仅代表您信任的特定账户或资源访问您的资源。但是,由于这些条件密钥要求您指定个人账户和资源,因此可能很难对其进行大规模管理,尤其是在大型组织中。

最近,IAM 推出了两个新的条件密钥,可帮助您以更易于在组织内管理的、更具扩展性的方式实现这一点:

  • aws:SourceOrgID – 使用此条件密钥可确保亚马逊云科技仅在请求来自 Amazon Organizations 中的特定组织标识时才能访问您的资源。
  • aws:SourceOrgPaths – 使用此条件密钥确保亚马逊云科技仅在请求来自组织中的一个或多个组织单位时才能访问您的资源。

在这篇博文中,我们将介绍如何使用四个可用的条件密钥(包括两个新的条件密钥)来帮助您控制亚马逊云科技如何访问您的资源。

内容背景

想象一下,您将亚马逊云科技服务配置为在其他服务中访问您的资源。假设您正在使用 Amazon CloudWatch 观察亚马逊云科技环境中的资源,并且您创建了一个在发生某些情况时激活的警报。当警报激活时,您希望它将消息发布到您在 Amazon Simple Notification Service(Amazon SNS) 中创建的主题以生成通知。

图 1 描绘了这个过程。

图 1:Amazon CloudWatch 向 SNS 主题发布消息

在这种情况下,有一个基于资源的策略来控制对您的 SNS 主题的访问权限。要让 CloudWatch 向其发布消息,您必须将策略配置为允许 CloudWatch 进行访问。执行此操作时,您将使用亚马逊服务主体(在本例中为 cloudwatch.amazonaws.com)标识 CloudWatch。

跨服务访问

这是一种称为跨服务访问的常见模式的示例。通过跨服务访问,调用服务访问您的被调用服务中的资源,而附加到您的资源的基于资源的策略则授予对调用服务的访问权限。调用服务使用格式为 <SERVICE-NAME>.amazonaws.com 的亚马逊服务主体进行标识,它代表原始资源(例如 CloudWatch 警报)访问您的资源。

图 2 显示了跨服务访问。

图 2:跨服务访问

配置跨服务访问时,您需要确保调用服务只能代表您访问您的资源。这意味着您希望原始资源由您信任的人控制。例如,如果不受信任的实体在其亚马逊云科技环境中创建了自己的 CloudWatch 警报,那么他们的警报应该无法向您的 SNS 主题发布消息。

如果不受信任的实体可以使用调用服务代表他们访问您的资源,这将是一个被称为困惑的副手问题的示例。 令人困惑的副手问题是一个安全问题,在这个问题中,无权执行操作的实体会强迫特权更高的实体(在本例中为调用服务)执行操作。

使用条件密钥帮助防止出现跨服务困惑的副手问题

亚马逊云科技提供全局条件密钥,以帮助您防止跨服务困惑的副手问题。您可以使用这些条件密钥来控制亚马逊云科技服务如何访问您的资源。

在今天之前,您可以使用 aws:SourceAccountaws:SourceArn 条件密钥确保调用服务仅在请求来自特定账户(aws:SourceAccount)或特定原始资源(aws:SourceArn)时访问您的资源。例如,您可能希望在发布到中央 S3 存储桶的组织中创建许多 VPC 流日志。要使用 aws:SourceAccountaws:SourceArn 条件密钥实现,必须在基于资源的策略中分别枚举所有原始账户或资源。这可能很难管理,尤其是在大型组织中,并且可能导致基于资源的政策文件达到大小限制。

现在,您可以使用新的 aws:SourceOrgIDaws:SourceOrgPaths 条件密钥确保仅当请求来自特定组织(aws:SourceOrgID)或特定组织单位(aws:SourceOrgPaths)时,调用服务才访问您的资源。这有助于避免在添加或移除账户时需要更新政策,减少政策文档的大小,并简化了政策声明的创建和审阅。

下表总结了四个条件密钥,您可以使用这些条件密钥来帮助防止跨服务困惑的副手问题。这些密钥的工作方式类似,但粒度级别不同。

用例 条件密钥 允许的运算符 单值/多值 示例值
仅允许调用服务代表您信任的组织访问您的资源。 aws:SourceOrgID 提出跨业务访问请求的资源的亚马逊组织 ID 字符串运算符 单值密钥 o-a1b2c3d4e5
仅允许调用服务代表您信任的组织单位(OU) 访问您的资源。 aws:SourceOrgPaths 提出跨服务访问请求的资源的一个或多个组织实体路径 集合运算符字符串运算符 多值密钥 o-a1b2c3d4e5/r-ab12/ou-ab12-11111111/ou-ab12-22222222/
仅允许调用服务代表您信任的账户访问您的资源。 aws:SourceAccount 提出跨业务访问请求的资源的亚马逊云科技账户 ID 字符串运算符 单值密钥 111122223333
仅允许调用服务代表您信任的资源访问您的资源。 aws:SourceArn 提出跨业务访问请求的资源的 Amazon Resource Name (ARN) ARN 运算符(推荐)或字符串运算符 单值密钥 arn:aws:cloudwatch:eu-west-1:111122223333:myalarm

何时使用条件密钥

亚马逊云科技建议您在任何基于资源的策略语句中使用这些条件密钥,其中主体元素是亚马逊服务主体<SERVICE-NAME>.amazonaws.com),但服务尚不支持相关条件密钥的情况除外。要了解特定服务是否支持条件密钥,请参阅亚马逊身份和访问管理用户指南中的亚马逊全局条件上下文密钥

注:仅在主体是亚马逊服务主体的基于资源的策略中使用这些条件密钥。不要在其他用例中使用,包括基于身份的策略和服务控制策略(SCP),在这些用例中,这些条件密钥不会被填充。

使用条件密钥进行深度防御

亚马逊云科技服务使用各种机制来帮助防止跨服务困惑的副手问题,具体细节因服务而异。例如,如果您的资源是 S3 存储桶,则某些调用服务使用 S3 前缀来帮助防止出现困惑的副手问题。有关更多信息,请参阅相关的服务文档

在该服务支持的情况下,无论该服务是否有其他机制来帮助防止跨服务困惑的副手问题,亚马逊云科技都建议您使用这些条件密钥。这有助于明确您的意图,提供深度防御并防止配置错误。

用例示例

让我们来看一些示例用例,学习如何在实践中使用这些条件密钥。

首先,假设您正在使用 Amazon Virtual Private Cloud(Amazon VPC) 来管理逻辑上隔离的虚拟网络。在 Amazon VPC 中,您可以配置流日志,以捕获有关您的网络流量的信息。假设您希望流日志将数据写入 S3 存储桶供以后分析。此过程如图 3 所示。

图 3:Amazon VPC 将流日志写入 S3 存储桶

这构成了另一种跨服务访问场景。在本例中,Amazon VPC 是调用服务,Amazon S3 是被调用的服务,VPC 流日志是原始资源,S3 存储桶是您在被调用服务中的资源。

要允许访问,您的 S3 存储桶基于资源的策略(称为存储桶策略)必须允许 Amazon VPC 在那里放置对象。 此策略中的主体元素指定将访问资源的服务的亚马逊服务主体,对于 VPC 流日志,该主体为 delivery.logs.amazonaws.com

没有困惑的副手问题的初始策略

以下是存储桶策略的初始版本,该策略允许 Amazon VPC 将对象放入存储桶中,但尚未提供困惑的副手问题防护。我们显示此策略是为了进行说明;不要以当前的格式使用。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PARTIAL-EXAMPLE-DO-NOT-USE",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::<DOC-EXAMPLE-BUCKET>/*"
        }
    ]
}

注意:为简单起见,我们仅显示您允许 VPC 流日志写入存储桶所需的策略声明之一。在现实生活中的流日志存储桶策略中,您需要两个策略声明:一个允许对存储桶执行操作,另一个允许对存储桶内容执行操作。这些内容在将流日志发布到 Amazon S3 中有所说明。在困惑的副手问题预防方面,这两份政策声明的作用方式相同。

此政策声明允许 Amazon VPC 将对象放入存储桶中。但是,它允许 Amazon VPC 代表任何账户中的任何流日志执行此操作。策略中没有任何内容可以告知 Amazon VPC,仅当流日志属于您信任的特定组织、组织单位、账户或资源时,它才应访问此存储桶。

现在让我们更新政策,以帮助防止跨服务困惑的副手问题。在这篇文章的其余部分中,其余的政策样本提供了困惑的副手问题保护,但粒度不同。

指定可信组织

继续上一个示例,假设您当前在亚马逊组织中有一个组织,并且您想要在组织内的各种账户中创建发布到中央 S3 存储桶的 VPC 流日志。只有当请求来自您的组织中的流日志时,您才希望 Amazon VPC 将对象放入存储桶中。

您可以使用新的 aws:SourceOrgID 条件密钥来实现此目的。在跨服务访问场景中,此条件密钥的计算结果为请求所属的组织 ID。您可以在基于资源的策略的条件元素中使用此条件密钥,以便仅当 aws:SourceOrgID 与特定组织的 ID 匹配时才允许操作,如以下示例所示。在您自己的策略中,请确保将 <DOC-EXAMPLE-BUCKET><MY-ORGANIZATION-ID> 替换为您自己的信息。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VPCLogsDeliveryWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::<DOC-EXAMPLE-BUCKET>/*",
            "Condition": {
                "StringEquals": {
                    "aws:SourceOrgID": "<MY-ORGANIZATION-ID>"
                }
            }
        }
    ]
}

修订后的政策规定,只有当请求来自您组织中的流日志时,Amazon VPC 才能将对象放入存储桶中。现在,如果有人在您的组织外部创建流日志并将其配置为访问您的存储桶,他们将收到拒绝访问的错误。

您可以通过这种方式使用 aws: SourceOrgID,仅当请求来自特定组织时,才允许调用服务访问您的资源,如图 4 所示。

图 4:使用 aws:SourceOrgID 指定可信组织

指定可信 OU

如果您不想信任整个组织,而只想信任其中的一部分,该怎么办? 让我们考虑一个不同的场景。 假设您要将消息从 Amazon SNS 发送到 Amazon Simple Queue Service(Amazon SQS) 中的队列,以便消费者可以处理。如图 5 所示。

图 5:Amazon SNS 向 SQS 队列发送消息

现在想象一下,您希望 SQS 队列仅接收来自组织中特定组织单位(OU) 中的 SNS 主题的消息。例如,您可能希望仅当消息源自受更改控制的生产 OU 时才允许消息。

您可以使用新的 aws:SourceOrgPaths 条件密钥来实现。和以前一样,您可以在附加到资源的基于资源的策略中使用此条件密钥。 在跨服务访问场景中,此条件密钥评估请求来自的亚马逊组织实体路径实体路径是组织内实体的文本表示形式。

您可以使用组织 ID、根 ID 以及向下到 OU(包括 OU)的路径中的 OU,为 OU 构建实体路径。例如,考虑图 6 所示的组织结构。

图 6:组织结构示例

在此示例中,您可以使用以下实体路径指定 Prod OU:

o-a1b2c3d4e5/r-ab12/ou-ab12-11111111/ou-ab12-22222222/

有关如何构建实体路径的更多信息,请参阅了解亚马逊组织实体路径

现在,让我们将 aws:SourceOrgPaths 条件密钥与 SQS 队列基于资源的策略的条件元素中的特定实体路径进行匹配。在您自己的策略中,请确保将 <MY-QUEUE-ARN><MY-ENTITY-PATH> 替换为您自己的信息。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Allow-SNS-SendMessage",
            "Effect": "Allow",
            "Principal": {
                "Service": "sns.amazonaws.com"
            },
            "Action": "sqs:SendMessage",
            "Resource": "<MY-QUEUE-ARN>",
            "Condition": {
                "Null": {
                    "aws:SourceOrgPaths": "false"
                },
                "ForAllValues:StringEquals" : {
                    "aws:SourceOrgPaths": "<MY-ENTITY-PATH>"
                }
            }
        }
    ]
}

注:aws:SourceOrgPaths 是一个多值条件密钥,这意味着它能够在请求上下文中具有多个值。在撰写本文时,如果请求来自组织中的账户,则它包含单个实体路径;如果请求来自不在组织中的账户,则包含一个空值。 由于此键是多值的,因此您需要同时使用集合运算符字符串运算符来比较值。

在此策略中,条件块中有两个条件。第一个使用带有假值的 Null 条件运算符来确认条件键的值不为空。第二个使用集合运算符 ForAllValues 和字符串运算符 StringEquals ,前者在请求中的每个条件键值至少与策略条件中的一个值匹配时返回 true,后者要求与策略条件中指定的值完全匹配。

空值检查的原因是,当条件密钥解析为空时,集合运算符 ForAllValues 返回 True。启用允许效果并启用空值检查后,如果请求来自不在组织中的账户,则访问将被拒绝。

将此策略应用于您的 SQS 队列后,只有当消息来自特定 OU 中的 SNS 主题时,Amazon SNS 才能向您的队列发送消息。

您可以通过这种方式使用 aws: SourceOrgPaths,以便仅当请求来自特定组织单位时,才允许调用服务访问您的资源,如图 7 所示。

图 7:使用 aws:SourceOrgPaths 指定受信任的 OU

指定受信任的 OU 及其子组织

在前面的示例中,我们指定了一个可信 OU,但其中不包括其子 OU。如果您也想包括其子级,该怎么办?

您可以通过将字符串运算符 StringEquals 替换为 StringLike 来实现此目的。这允许您在实体路径中使用通配符。使用上一示例中的组织结构,仅当条件键值不为空且请求源自 Prod OU 或其任何子 OU 时,以下条件才会计算为 true

"Condition": {
    "Null": {
        "aws:SourceOrgPaths": "false"
    },
    "ForAllValues:StringLike" : {
        "aws:SourceOrgPaths": "o-a1b2c3d4e5/r-ab12/ou-ab12-11111111/ou-ab12-22222222/*"
    }
}

指定可信账户

如果您想更精细,则仅当请求来自特定账户时,才允许服务访问您的资源。您可以使用 aws:SourceAccount 条件密钥来实现。在跨服务访问场景中,此条件键的计算结果为请求来自的账户的 ID。

只有当请求来自您在策略中指定的账户时,以下条件才会计算为 true。在您自己的策略中,请确保将 <MY-ACCOUNT-ID> 替换为您自己的信息。

"Condition": {
    "ForAnyValue:StringEquals" : {
        "aws:SourceAccount": "<MY-ACCOUNT-ID>"
    }
}

如图 8 所示,您可以在基于资源的策略中使用此条件元素,仅当请求来自特定账户时才允许调用服务访问您的资源 。

图 8:使用 aws:SourceAccount 指定可信账户

指定可信资源

如果您想更精细,则只有当请求来自特定资源时,才允许服务访问您的资源。例如,只有当请求源自 Amazon SNS 中的特定主题时,您才能允许 Amazon SNS 向您的 SQS 队列发送消息。

您可以使用 aws:SourceArn 条件密钥来实现。在跨服务访问场景中,此条件密钥评估为原始资源的 Amazon Resource Name(ARN)。这提供了最精细的跨服务困惑的副手问题预防形式。

只有当请求来自您在策略中指定的资源时,以下条件才会计算为 true。在您自己的策略中,请确保将 <MY-RESOURCE-ARN> 替换为您自己的信息。

"Condition": {
    "ArnEquals": {
        "aws:SourceArn": "<MY-RESOURCE-ARN>"
    }
}

注意:在比较 ARN 时,亚马逊云科技建议您使用 ARN 运算符而不是字符串运算符。此示例使用 ArnEquals 将条件键值与策略中指定的 ARN 进行匹配。

如图 9 所示,您可以在基于资源的策略中使用此条件元素,以便仅当请求来自特定原始资源时,才允许调用服务访问您的资源。

图 9:使用 aws:SourceArn 指定可信资源

指定多个可信资源、账户、OU 或组织

四个条件密钥允许您通过匹配值数组来指定多个受信任实体。这允许您在策略中指定多个可信资源、账户、OU 或组织。

结论

在本文中,您了解了跨服务访问,其中亚马逊云科技服务与其他亚马逊云科技服务通信以访问您的资源。您了解到,务必确保此类服务仅代表您访问您的资源,以帮助避免跨服务困惑的副手问题。

我们向您展示了如何使用两个新的条件密钥 aws:SourceOrgID 和 aws:SourceOrgPaths,以及其他可用的条件密钥 aws:SourceAccount and aws:SourceArn 来帮助防止跨服务困惑的副手问题。您已了解到,如果任何基于资源的策略语句的主体元素是亚马逊服务主体<SERVICE-NAME>.amazonaws.com),并且该服务支持条件密钥,则应在该语句中使用这些条件密钥。这有助于确保只有当请求来自您信任的特定组织、组织单位、账户或资源时,调用服务才能访问您的资源。

本篇作者

James Greenwood

James 是首席安全解决方案架构师,帮助 AWS 金融服务客户在亚马逊云科技云中实现其安全和合规性目标。James 拥有身份和访问管理、身份验证、凭证管理和数据保护方面的背景,在金融服务行业拥有 20 多年的经验。

Sophia Yang

Sophia 是 AWS 身份和访问管理 (IAM) 服务的高级产品经理。她热衷于让客户以安全的方式在 AWS 中进行构建和创新。