AWS Elasticsearch Service IAM 基于角色的访问策略

Posted

技术标签:

【中文标题】AWS Elasticsearch Service IAM 基于角色的访问策略【英文标题】:AWS Elasticsearch Service IAM Role based Access Policy 【发布时间】:2016-01-17 05:51:33 【问题描述】:

我一直在努力弄清楚如何从我的 EC2 实例与 Amazon ES 服务进行通信。

文档明确指出,Amazon ES 服务支持基于 IAM 用户和角色的访问策略。 http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-createupdatedomains.html#es-createdomain-configure-access-policies

但是,当我的 ES 域具有此访问策略时:


  "Version": "2012-10-17",
  "Statement": [
    
      "Sid": "",
      "Effect": "Allow",
      "Principal": 
        "AWS": "arn:aws:iam::123456789:role/my-ec2-role"
      ,
      "Action": "es:*",
      "Resource": "arn:aws:es:us-west-2:123456789:domain/myDomain/*"
    
  ]

我无法登录到 ec2 实例并运行 curl 来访问我的 elasticsearch 集群。

尝试对 _search API 做一个简单的 curl:

curl "http://search-myDomain.es.amazonaws.com/_search"

产生身份验证错误响应:

"Message":"User: anonymous is not authorized to perform: es:ESHttpGet on resource: arn:aws:es:us-west-2:123456789:domain/myDomain/_search"

为了更加安全,我将 AmazonESFullAccess 策略放在我的 IAM 角色上,但仍然不起作用。

我一定遗漏了一些东西,因为能够通过使用 IAM 角色的 ec2 实例以编程方式与 Elasticsearch 交互对于使用 Amazon ES 服务完成任何事情都是必不可少的。

我在文档中也看到了这种矛盾的说法。

基于 IAM 的策略示例 您可以通过以下方式创建基于 IAM 的访问策略 使用 AWS IAM 控制台而不是 Amazon ES 控制台。为了 有关创建基于 IAM 的访问策略的信息,请参阅 IAM 文档。

指向 IAM 文档的链接是指向 IAM 主页的链接,其中包含有关如何操作的完全零信息。有没有人可以帮我解决?

【问题讨论】:

Proper Access Policy for Amazon Elastic Search Cluster的可能重复 @nackjicholson 您的问题解决了吗?现在有点类似的情况! 【参考方案1】:

在 AWS 中使用 IAM 服务时,您必须签署您的请求。 curl 不支持签名请求(包括对请求进行散列处理并将参数添加到请求的标头)。您可以使用其中一个内置签名算法的 SDK,然后提交该请求。

见: http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/what-is-amazon-elasticsearch-service.html#signing-requests

您可以在此处找到流行语言的 SDK: http://aws.amazon.com/tools/

【讨论】:

你可以通过 AWS CLI 来实现吗? FWIW,AWS sigv4 最近被添加到 curl。【参考方案2】:

首先,你说你不能登录EC2实例来curl ES实例?你不能登录?或者你不能从 EC2 卷曲它?

我的 Elasticsearch(服务)实例向全世界开放(上面没有任何内容)并且能够很好地卷曲它,而无需签名。我更改了访问策略以进行测试,但不幸的是,更改后需要永远恢复...

我的政策如下所示:

   "Version": "2012-10-17",   "Statement": [
    
      "Sid": "",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "es:*",
      "Resource": "arn:aws:es:us-east-1:843348267853:domain/myDomain/*"
    ,
    
      "Sid": "",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "es:*",
      "Resource": "arn:aws:es:us-east-1:843348267853:domain/myDomain"
       
   ] 

我意识到这并不完全是您想要的,但从这个(向世界开放)开始,从 AWS 外部进行 curl 并对其进行测试。然后限制它,这样你就可以隔离问题。

另外,我认为您的访问策略中的“委托人”存在问题。您拥有自己的 EC2 角色。我理解你为什么这样做,但我认为校长需要一个用户,而不是一个角色。

见下文:

http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-createupdatedomains.html#es-createdomain-configure-access-policies

校长

指定允许或拒绝访问的 AWS 账户或 IAM 用户 到资源。指定通配符 (*) 启用匿名访问 域,不推荐。如果您启用匿名 访问,我们强烈建议您添加基于 IP 的条件 限制哪些 IP 地址可以向 Amazon ES 提交请求 域。

编辑 1

为了清楚起见,您将 AmazonESFullAccess 策略添加到 my-ec2-role?如果您要使用 IAM 访问策略,我认为您不能附加基于资源的策略(这就是您正在做的事情)。

http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_compare-resource-policies.html

对于某些 AWS 服务,您可以授予跨账户访问您的 资源。为此,您将策略直接附加到资源 您想要共享的,而不是使用角色作为代理。这 您要共享的资源必须支持基于资源的策略。 与基于用户的策略不同,基于资源的策略指定谁(在 AWS 账户 ID 号列表的形式)可以访问 资源。

可能尝试完全删除访问策略?

【讨论】:

为什么你在你的保单中写了两次相同的内容? 对世界开放的政策不起作用,有什么建议吗? curl -XGET 'search-aa-kfrqkt7hi.sa-east-1.es.amazonaws.com/_cluster/…' "Message":"您的请求:'/_cluster/state' 不被允许。" “但不幸的是,更改后它需要永远恢复......”值得加粗和突出显示。 Amazon 上的大多数 IAM 更改都是即时的,但在 ElasticSearch 方面...【参考方案3】:

为什么不创建具有弹性 ip 的代理并允许您的代理访问您的 ES? 基本上存在三种形式,您可以在 ES 中限制访问:

允许所有人 白 IP 名单 签署 AWS 提供的访问密钥和秘密密钥。

我使用两种形式,在我的 php 应用程序中,我更喜欢在连接到 ES 后使用代理,在我的 nodejs 应用程序中,我更喜欢使用 http-aws-es 节点模块来签署我的请求。 创建代理环境很有用,因为我的用户需要访问 kibana 界面才能查看一些报告,这可能是因为他们在浏览器中配置了代理 =)

我必须建议您关闭对您的 ES 索引的访问,因为删除它们非常容易, curl -XDELETE https://your_es_address/index 任何人都可以这样做,但您可以说:“其他用户将如何获得我的 ES 地址? "我会回答你:“基于昏暗的安全并不是真正的安全”

我的安全访问策略基本上是这样的:

http://pastebin.com/EUKT1ekX

【讨论】:

【参考方案4】:

我最近遇到了这个问题,根本问题是 Amazon SDK 尚不支持调用 Elasticsearch 操作,如搜索、放置等。

目前唯一的解决方法是使用签名请求直接针对端点执行请求: http://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html

此处的示例用于调用 EC2,但可以修改为调用 Elasticsearch。只需将“service”值修改为“es”即可。从那里,您必须填写

端点(即集群的完整 URL,包括不带请求参数的操作) 主机(https:// 和您的规范 URI 之间的部分,例如 /_status 规范的 uri,它是第一个 / 包含后的 URI(如 /_status)但没有查询字符串 请求参数(包括 ? 之后的所有内容)

请注意,到目前为止,我仅使用 AWS 凭证来实现此功能,因为假设您将访问密钥和秘密密钥传递给各种签名调用(示例中的 access_key 和 secret_key)。 应该使用 IAM 角色是可行的,但您必须首先调用安全令牌服务以获取可用于签署请求的临时凭证。在您这样做之前,请务必在 Elasticsearch 集群上编辑您的访问策略以允许用户凭据(用户/

【讨论】:

【参考方案5】:

您需要签署您的请求,不幸的是,官方的 elasticsearch 库不再支持它。检查这个 Github 问题 (https://github.com/elastic/elasticsearch-js/issues/1182#issuecomment-630641702)

他们想要实施自己的云解决方案

【讨论】:

以上是关于AWS Elasticsearch Service IAM 基于角色的访问策略的主要内容,如果未能解决你的问题,请参考以下文章

将 AWS Kinesis Firehose 回填到 Elasticsearch Service 失败记录

将AWS Kinesis Firehose回填到Elasticsearch Service失败的记录

有什么方法可以监视AWS Elasticsearch Service节点的EBS IOPS / BurstBalance吗?

AWS Managed ElasticSearch 上的弹性传输客户端

如何使用Spring Data ElasticsearchTemplate连接到Amazon Elasticsearch Service?

签署 ElasticSearch AWS 调用