Amazon Elasticsearch Service
开发人员指南 (API 版本 2015-01-01)
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

Amazon Elasticsearch Service 访问控制

Amazon Elasticsearch Service 提供了多种方式来控制对您的域的访问。本部分介绍了各种策略类型,其彼此交互的方式,以及如何创建您自己的自定义策略。

重要

VPC 支持为 Amazon ES 访问控制引入了一些其他注意事项。有关更多信息,请参阅 关于 VPC 域的访问策略

策略的类型

Amazon ES 支持三种类型的访问策略:

基于资源的策略

您将基于资源的策略附加到域。这些策略指定委托人可以对域的子资源执行哪些操作。子资源包括 Elasticsearch 索引和 API。

Principal 元素指定账户、用户或允许访问的角色。Resource 元素指定这些委托人可以访问哪些子资源。以下基于资源的策略将授予 test-useres:* 资源的完全访问权限 (test-domain)。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::123456789012:user/test-user" ] }, "Action": [ "es:*" ], "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/*" } ] }

两个重要注意事项适用于此策略:

  • 这些权限仅适用于此域。除非您创建其他策略,否则 test-user 无法访问其他域或在 Amazon ES 控制面板中查看这些域的列表。

  • /* 元素中尾随的 Resource 非常重要。尽管拥有完全访问权限,test-user 仍然只可以对域的子资源 (而不能对域的配置) 执行这些操作。

    例如,test-user 可以向索引 (GET https://search-test-domain.us-west-1.es.amazonaws.com/test-index) 发送请求,但不可以更新域的配置 (POST https://es.us-west-1.amazonaws.com/2015-01-01/es/domain/test-domain/config)。注意两个终端节点之间的差异。访问配置 API 需要一个基于身份的策略

要进一步限制 test-user,您可以应用以下策略:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::123456789012:user/test-user" ] }, "Action": [ "es:ESHttpGet" ], "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/test-index/_search" } ] }

现在,test-user 只能执行一个操作:搜索 test-index。域中的所有其他索引均不可访问,且如果没有使用 es:ESHttpPut 操作或 es:ESHttpPost 操作的权限,test-user 将无法添加或修改文档。

接下来,您可以决定为高级用户配置角色。此策略允许 power-user-role 访问所有 HTTP 方法,但不能删除关键索引及其文档:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::123456789012:role/power-user-role" ] }, "Action": [ "es:ESHttpDelete", "es:ESHttpGet", "es:ESHttpHead", "es:ESHttpPost", "es:ESHttpPut" ], "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/*" }, { "Effect": "Deny", "Principal": { "AWS": [ "arn:aws:iam::123456789012:role/power-user-role" ] }, "Action": [ "es:ESHttpDelete" ], "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/critical-index*" } ] }

有关所有可用操作的信息,请参阅策略元素参考

基于身份的策略

与基于资源的策略(附加到 Amazon ES 中的域)不同,您使用 AWS Identity and Access Management (IAM) 服务将基于身份的策略附加到用户或角色。与基于资源的策略一样,基于身份的策略指定谁可以访问服务,他们可以执行哪些操作,以及他们可以对哪些资源执行这些操作(如果适用)。

虽然不一定,但基于身份的策略往往更通用。它们通常管理用户可以执行的基本、服务级别的操作。您准备好这些策略后,可以在 Amazon ES 中使用基于资源的策略为用户提供其他权限。

由于基于身份的策略附加到用户或角色 (委托人),JSON 不会指定委托人。以下策略授予对以 DescribeList 开头的操作的访问权限,且允许对所有域发送 GET 请求。这一操作组合提供只读访问:

{ "Version": "2012-10-17", "Statement": [ { "Action": [ "es:Describe*", "es:List*", "es:ESHttpGet" ], "Effect": "Allow", "Resource": "*" } ] }

管理员可能具有对 Amazon ES 的完全访问权限:

{ "Version": "2012-10-17", "Statement": [ { "Action": [ "es:*" ], "Effect": "Allow", "Resource": "*" } ] }

有关基于资源的策略和基于身份的策略之间的区别的更多信息,请参阅 IAM 用户指南 中的 IAM 策略

注意

具有 AWS 托管的 AmazonESReadOnlyAccess 策略的用户无法查看控制台中的群集运行状况。要允许它们查看群集运行状况,请向访问策略添加 "es:ESHttpGet" 操作并将该操作附加到其账户或角色。

基于 IP 的策略

基于 IP 的策略将对域的访问限制在一个或多个 IP 地址或 CIDR 块。从技术上讲,基于 IP 的策略不是一种不同类型的策略。相反,它们仅仅是指定匿名委托人的基于资源的策略,且包含一个特殊的 Condition 元素。

基于 IP 的策略的主要吸引力在于,它们允许对 Amazon ES 域发送未签名请求,这可让您使用 curlKibana 等客户端或通过代理服务器访问域。要了解更多信息,请参阅“使用代理从 Kibana 访问 Amazon ES”。

注意

如果您为您的域启用了 VPC 访问,则无法配置基于 IP 的策略。但您可以使用安全组来控制哪些 IP 地址可以访问该域。有关更多信息,请参阅关于 VPC 域的访问策略

以下基于 IP 的访问策略向源自 12.345.678.901 的所有请求授予对 test-domain 的访问权限:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": [ "es:*" ], "Condition": { "IpAddress": { "aws:SourceIp": [ "192.0.2.0/24" ] } }, "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/*" } ] }

发出和签署 Amazon ES 请求

即使您配置了完全开放的基于资源的访问策略,对 Amazon ES 配置 API 的所有 请求也必须经过签名。如果您的策略指定 IAM 用户或角色,则对 Elasticsearch API 的请求也必须经过签名。签名方法因 API 而异:

  • 要调用 Amazon ES 配置 API,我们建议您使用一个 AWS 开发工具包。与创建和签署您自己的请求相比,开发工具包可大大简化流程,从而为您节省大量时间。配置 API 终端节点采用以下格式:

    es.region.amazonaws.com/2015-01-01/

    例如,以下请求将对 movies 域进行细微的配置更改,但您必须自行签名(不推荐):

    POST https://es.us-east-1.amazonaws.com/2015-01-01/es/domain/movies/config { "SnapshotOptions": { "AutomatedSnapshotStartHour": 3 } }

    如果您使用了其中一个开发工具包(如 Boto 3),该开发工具包将自动处理请求签名:

    import boto3 client = boto3.client('es') response = client.update_elasticsearch_domain_config( DomainName='movies', SnapshotOptions={ 'AutomatedSnapshotStartHour': 3 } )
  • 要调用 Elasticsearch API,您必须签署您自己的请求。有关示例代码,请参阅 签署对 Amazon Elasticsearch Service 的 HTTP 请求。Elasticsearch API 采用以下格式:

    domain.region.es.amazonaws.com

    例如,以下请求将在 movies 索引中搜索 thor

    GET https://search-my-domain.us-east-1.es.amazonaws.com/movies/_search?q=thor

Amazon ES 支持使用 AWS 签名版本 4 进行身份验证。有关更多信息,请参阅签名版本 4 签名流程

注意

对于用签名版本 4 签署的 HTTP POST 请求,服务会忽略在 URL 中传入的参数。

当策略发生冲突时

当策略不一致或没有明确提到某个用户时,复杂性将提高。IAM 用户指南 中的了解 IAM 的工作方式提供了策略评估逻辑的简明摘要:

  • 默认情况下,所有请求都将被拒绝。

  • 显式允许将取代此默认设置。

  • 显式拒绝将覆盖任何允许。

例如,如果某个基于资源的策略向您授予访问某个域的权限,但一个基于身份的策略拒绝您访问,则您将被拒绝方案。如果某个基于身份的策略授予访问权限,基于资源的策略不指定您是否应具有访问权限,则您将被允许访问。请参阅以下交叉策略表,了解结果的完整摘要。

在基于资源的策略中允许 在基于资源的策略中拒绝 在基于资源的策略中既不允许也不拒绝
Allowed in Identity-based Policy

允许

拒绝 允许
Denied in Identity-based Policy 拒绝 拒绝 拒绝
Neither Allowed nor Denied in Identity-based Policy 允许 拒绝 拒绝

策略元素参考

Amazon ES 支持 IAM 策略元素参考中的大多数策略元素,但 NotPrincipal 除外。下表显示了最常用的元素。

JSON 策略元素 摘要
Version

当前版本的策略语言为 2012-10-17。所有访问策略均应指定该值。

Effect

此元素指定该语句是允许还是拒绝对特定操作的访问。有效值为 AllowDeny

Principal

此元素指定被允许或拒绝访问资源的 AWS 账户或 IAM 用户或角色,可采用多种形式:

  • AWS 账户"Principal":{"AWS": ["123456789012"]}"Principal":{"AWS": ["arn:aws:iam::123456789012:root"]}

  • IAM 用户: "Principal":{"AWS": ["arn:aws:iam::123456789012:user/test-user"]}

  • IAM 角色: "Principal":{"AWS": ["arn:aws:iam::123456789012:role/test-role"]}

指定 * 通配符支持匿名访问域,我们不建议这样做,除非您添加一个基于 IP 的条件。

Action

Amazon ES 使用 HTTP 方法的以下操作:

  • es:ESHttpDelete

  • es:ESHttpGet

  • es:ESHttpHead

  • es:ESHttpPost

  • es:ESHttpPut

Amazon ES 使用配置 API 的以下操作:

  • es:AddTags

  • es:CreateElasticsearchDomain

  • es:DeleteElasticsearchDomain

  • es:DeleteElasticsearchServiceRole

  • es:DescribeElasticsearchDomain

  • es:DescribeElasticsearchDomainConfig

  • es:DescribeElasticsearchDomains

  • es:DescribeElasticsearchInstanceTypeLimits

  • es:ListDomainNames

  • es:ListElasticsearchInstanceTypeDetails

  • es:ListElasticsearchInstanceTypes

  • es:ListElasticsearchVersions

  • es:ListTags

  • es:RemoveTags

  • es:UpdateElasticsearchDomainConfig

提示

您可以使用通配符来指定一部分操作,如 "Action":"es:*""Action":"es:Describe*"

某些 es: 操作支持资源级权限。例如,您可以向用户授予删除一个特定域的权限,而无需向该用户授予删除任何 域的权限。其他操作仅适用于服务本身。例如,es:ListDomainNames 在单个域范围内没有意义,因此需要一个通配符。

重要

基于资源 的策略与资源级 权限不同。基于资源的策略是附加到域的完整 JSON 策略。资源级权限可让您将操作限制于特定域或子资源。在实际工作中,您可以将资源级权限视为基于资源的策略或基于身份的策略的可选部分。

以下基于身份的策略将列出所有 es: 操作并按照它们是适用于域子资源 (test-domain/*)、适用于域配置 (test-domain) 还是仅适用于服务 (*) 对其进行分组:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "es:ESHttpDelete", "es:ESHttpGet", "es:ESHttpHead", "es:ESHttpPost", "es:ESHttpPut" ], "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/*" }, { "Effect": "Allow", "Action": [ "es:CreateElasticsearchDomain", "es:DeleteElasticsearchDomain", "es:DescribeElasticsearchDomain", "es:DescribeElasticsearchDomainConfig", "es:DescribeElasticsearchDomains", "es:UpdateElasticsearchDomainConfig" ], "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain" }, { "Effect": "Allow", "Action": [ "es:AddTags", "es:DeleteElasticsearchServiceRole", "es:DescribeElasticsearchInstanceTypeLimits", "es:ListDomainNames", "es:ListElasticsearchInstanceTypeDetails", "es:ListElasticsearchInstanceTypes", "es:ListElasticsearchVersions", "es:ListTags", "es:RemoveTags" ], "Resource": "*" } ] }

注意

虽然 es:CreateElasticsearchDomain 的资源级权限可能看起来不直观(究竟为何要向用户授予创建已存在的域的权限?),但通配符的使用可让您强制实施一个简单的域命名架构,例如 "Resource": "arn:aws:es:us-west-1:987654321098:domain/my-team-name-*"

当然,您完全可以在限制性较低的资源元素旁包括如下操作:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "es:ESHttpGet", "es:DescribeElasticsearchDomain" ], "Resource": "*" } ] }

要了解有关配对操作和资源的更多信息,请参阅此表中的 Resource 元素。

Condition

Amazon ES 支持 IAM 用户指南可用的全局条件键中所述的大多数条件。值得一提的一个例外是 aws:SecureTransport 键,Amazon ES 不支持此键。

配置基于 IP 的策略时,您指定 IP 地址或 CIDR 块作为条件,如下所示:

"Condition": { "IpAddress": { "aws:SourceIp": [ "192.0.2.0/32" ] } }
Resource

Amazon ES 以三种基本方式使用 Resource 元素:

  • 对于应用于 Amazon ES 本身的操作(如 es:ListDomainNames),或若要允许完整访问权限,请使用以下语法:

    "Resource": "*"
  • 对于涉及域的配置的操作 (例如 es:DescribeElasticsearchDomain),您可以使用以下语法:

    "Resource": "arn:aws:es:region:aws-account-id:domain/domain-name"
  • 对于应用于域的子资源的操作 (例如 es:ESHttpGet),您可以使用以下语法:

    "Resource": "arn:aws:es:region:aws-account-id:domain/domain-name/*"

    您不必使用通配符。Amazon ES 可让您为每个 Elasticsearch 索引或 API 定义不同的访问策略。例如,您可以限制用户对 test-index 索引的权限:

    "Resource": "arn:aws:es:region:aws-account-id:domain/domain-name/test-index"

    与对 test-index 的完全访问权限相比,您可能更愿意将策略限制在仅搜索 API。

    "Resource": "arn:aws:es:region:aws-account-id:domain/domain-name/test-index/_search"

    您甚至可以控制对单个文档的访问:

    "Resource": "arn:aws:es:region:aws-account-id:domain/domain-name/test-index/test-type/1"

    基本上,如果 Elasticsearch 将子资源表示为一个终端节点,则您可以控制对其进行的访问。

有关哪些操作支持资源级权限的详细信息,请参阅此表中的 Action 元素。

高级选项和 API 注意事项

Amazon ES 有多个高级选项,其中一个具有访问控制影响:rest.action.multi.allow_explicit_index。在其默认设置为 true 时,它允许用户在某些情况下绕过子资源权限。

例如,请考虑以下基于资源的策略:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::123456789012:user/test-user" ] }, "Action": [ "es:ESHttp*" ], "Resource": [ "arn:aws:es:us-west-1:987654321098:domain/test-domain/test-index/*", "arn:aws:es:us-west-1:987654321098:domain/test-domain/_bulk" ] }, { "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::123456789012:user/test-user" ] }, "Action": [ "es:ESHttpGet" ], "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/restricted-index/*" } ] }

此策略向 test-user 授予对 test-index 和 Elasticsearch 批量 API 的完全访问权限。它还允许对 GET 发送 restricted-index 请求。

正如您可能预料的,以下索引请求将因权限错误而失败:

PUT https://search-test-domain.us-west-1.es.amazonaws.com/restricted-index/movie/1 { "title": "Your Name", "director": "Makoto Shinkai", "year": "2016" }

与索引 API 不同,批量 API 可让您在一次调用中创建、更新和删除许多文档。但是,您通常在请求正文中指定这些操作,而不是在请求 URL 中。由于 Amazon ES 使用 URL 控制对域子资源的访问,事实上,test-user 可以使用批量 API 对 restricted-index 进行更改。即使该用户缺乏对索引的 POST 权限,以下请求也将成功

POST https://search-test-domain.us-west-1.es.amazonaws.com/_bulk { "index" : { "_index": "restricted-index", "_type" : "movie", "_id" : "1" } } { "title": "Your Name", "director": "Makoto Shinkai", "year": "2016" }

在这种情况下,访问策略无法实现其意图。要防止用户绕过这些类型的限制,您可以将 rest.action.multi.allow_explicit_index 更改为 false。如果此值为 false,则对批量、mget 和 msearch API 的所有在请求正文中指定索引名称的调用都将停止工作。换句话说,对 _bulk 的调用不再有效,但对 test-index/_bulk 的调用仍然有效。这第二个终端节点包含一个索引名称,因此您无需在请求正文中指定一个索引名称。

Kibana 高度依赖于 mget 和 msearch,因此它不太可能在此更改后正常工作。若要进行部分补救,您可以将 rest.action.multi.allow_explicit_index 保留为 true 或拒绝特定用户访问这些 API 中的一个或多个。

有关更改此设置的信息,请参阅配置高级选项

同样,以下基于资源的策略包含两个小问题:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:user/test-user" }, "Action": "es:ESHttp*", "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/*" }, { "Effect": "Deny", "Principal": { "AWS": "arn:aws:iam::123456789012:user/test-user" }, "Action": "es:*", "Resource": "arn:aws:es:us-west-1:987654321098:domain/test-domain/restricted-index/*" } ] }
  • 即使显式拒绝,test-user 仍然可以进行 GET https://search-test-domain.us-west-1.es.amazonaws.com/_all/_searchGET https://search-test-domain.us-west-1.es.amazonaws.com/*/_search 等调用,以访问 restricted-index 中的文档。

  • 由于 Resource 元素引用 restricted-index/*test-user 无权直接访问索引的文档。但是,该用户有权删除整个索引。要防止访问和删除,策略必须改为指定 restricted-index*

与混合广泛的允许和集中的拒绝相比,最安全的方法是遵循最小特权原则,仅授予执行任务所需的权限。

配置访问策略

  • 有关在 Amazon ES 中创建或修改基于资源和基于 IP 的策略的说明,请参阅配置访问策略

  • 有关在 IAM 中创建或修改基于身份的策略的说明,请参阅 IAM 用户指南 中的创建 IAM 策略

其他示例策略

虽然本章包含许多示例策略,但 AWS 访问控制是一个复杂的主题,最好是通过示例理解。有关更多信息,请参阅 IAM 用户指南 中的示例策略