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

AWS Elasticsearch Service IAM Role based Access Policy

我一直在努力弄清楚如何从我的 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 "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"}

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

我一定遗漏了什么,因为能够从使用 IAM 角色的 ec2 实例以编程方式与 Elasticsearch 交互对于使用 Amazon ES 服务完成任何事情至关重要。

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

IAM-based Policy Example You create IAM-based access policies by using the AWS IAM console rather than the Amazon ES console. For information about creating IAM-based access policies, see the IAM documentation.

IAM 文档的 link 是 IAM 的主页,并且包含关于如何操作的零信息。有人为我找到了解决方案吗?

在 AWS 上使用 IAM 服务时,您必须签署您的请求。 curl 不支持签名请求(包括散列请求和向请求的 header 添加参数)。您可以使用他们的一种内置签名算法的 SDK,然后提交该请求。

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

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

第一,你说不能登录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 并测试它。然后限制它,这样你就可以隔离问题。

此外,我认为您的访问策略中的 "Principal" 存在问题。您拥有 EC2 角色。我明白你为什么要那样做,但我认为校长需要一个用户,而不是一个角色。

见下文:

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

Principal

Specifies the AWS account or IAM user that is allowed or denied access to a resource. Specifying a wildcard (*) enables anonymous access to the domain, which is not recommended. If you do enable anonymous access, we strongly recommend that you add an IP-based condition to restrict which IP addresses can submit requests to the Amazon ES domain.

编辑 1

明确地说,您将 AmazonESFullAccess 策略添加到 my-ec2-role?如果您要使用 IAM 访问策略,我不认为您可以附加基于资源的策略(这就是您正在做的)。

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

For some AWS services, you can grant cross-account access to your resources. To do this, you attach a policy directly to the resource that you want to share, instead of using a role as a proxy. The resource that you want to share must support resource-based policies. Unlike a user-based policy, a resource-based policy specifies who (in the form of a list of AWS account ID numbers) can access that resource.

是否可以尝试完全删除访问策略?

我最近遇到了这个问题,根本问题是 none 的 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 集群上的访问策略以允许用户凭据(用户/

为什么你不用elastic ip创建代理,让你的代理访问你的ES? 基本上存在三种形式,您可以在 ES 中限制访问:

  • 允许所有人
  • 白名单
  • 签署AWS提供的access key和secret key

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

我必须建议您关闭对 ES 索引的访问,因为删除它们非常容易,curl -XDELETE https://your_es_address/index 任何人都可以做到,但您可以说:"how the others users will get my ES address?" 和我会回答你:"Security based in dimness isn't a real security"

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

http://pastebin.com/EUKT1ekX

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

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