106

我最近开始使用新的 Amazon Elasticsearch Service,但我似乎无法弄清楚我需要的访问策略,因此我只能从分配了特定 IAM 角色的 EC2 实例访问服务。

这是我目前为 ES 域分配的访问策略的示例:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::[ACCOUNT_ID]:role/my_es_role",
        ]
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:us-east-1:[ACCOUNT_ID]:domain/[ES_DOMAIN]/*"
    }
  ]
}

但正如我所说,这是行不通的。我登录到 EC2 实例(my_es_role附加了角色)并尝试在“https://*.es.amazonaws.com”端点上运行一个简单的 curl 调用,我收到以下错误:

{“消息”:“用户:匿名无权执行:es:ESHttpGet 资源:arn:aws:es:us-east-1:[ACCOUNT_ID]:domain/[ES_DOMAIN]/“}

有谁知道我必须在访问策略中进行哪些更改才能使其正常工作?

4

7 回答 7

64

您可以将访问权限锁定为仅限 IAM,但您将如何在浏览器中查看 Kibana?您可以设置代理请参阅 Gist和/或NPM 模块)或启用 IAM 和基于 IP 的访问以查看结果。

我能够通过以下访问策略获得 IAM 访问 IP 限制访问。请注意,顺序很重要:我无法在 IAM 语句之前使用基于 IP 的语句。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::xxxxxxxxxxxx:root"
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:us-west-2:xxxxxxxxxxxx:domain/my-elasticsearch-domain/*"
    },
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:us-west-2:xxxxxxxxxxxx:domain/my-elasticsearch-domain/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": [
            "192.168.1.0",
            "192.168.1.1"
          ]
        }
      }
    }
  ]
}

我的 EC2 实例有一个带有 arn:aws:iam::aws:policy/AmazonESFullAccess 策略的实例配置文件。Logstash 应该使用logstash-output-amazon-es 输出插件对请求进行签名。在我的 EC2 实例上运行的 Logstash 包含如下输出部分:

output {
    amazon_es {
        hosts => ["ELASTICSEARCH_HOST"]
        region => "AWS_REGION"
    }
    # If you need to do some testing & debugging, uncomment this line:
    # stdout { codec => rubydebug }
}

我可以从访问策略中的两个 IP(192.168.1.0 和 192.168.1.1)访问 Kibana。

于 2015-12-02T23:53:48.270 回答
38

根据 AWS 文档,正如您(和我)刚刚测试的那样,您不能将对 AWS ES 域的访问限制为角色/帐户/用户/... 并且只需 cURL 它!

标准客户端(例如 curl)无法执行基于身份的访问策略所需的请求签名。您必须使用允许匿名访问的基于 IP 地址的访问策略才能成功执行此步骤的说明。(http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-gsg-search.html

所以你基本上有两个解决方案:

如果您想保持访问策略不变(这比限制为 IP 更灵活),签署您的请求可能是最好的解决方案,但它似乎有点复杂。到目前为止我还没有尝试过,我找不到任何文档来帮助。

于 2015-10-07T09:43:27.313 回答
6

聚会有点晚了,但我能够通过在我的请求中添加签名来处理完全相同的问题。

如果您使用 Python(像我一样),您可以使用以下库使其特别容易实现: https ://github.com/DavidMuller/aws-requests-auth

它对我来说非常有效。

于 2016-09-28T15:48:53.887 回答
1

您只需要在弹性搜索策略中输入完整的用户名。

在这种情况下,您可以从错误消息本身中获取您的完整用户名。就我而言:“arn:aws:sts::[ACCOUNT_ID]:assumed-role/[LAMBDA_POLICY_NAME]/[LAMBDA_NAME]”

    {
        "Version": "2012-10-17",
        "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": [
              "arn:aws:sts::xxxxxxxxxxxx:assumed-role/[lambda-role]/[full-lambda-name]"
            ]
          },
          "Action": "es:*",
          "Resource": "arn:aws:es:[region]:xxxxxxxxxxxxx:domain/[elasticsearch-domain-name]/*"
        }
      ]

    }
于 2019-11-19T12:28:02.070 回答
0

角色 ARN 需要更改。它看起来像“arn:aws:iam::[ACCOUNT_ID]:role/service-role/my_es_role”

于 2020-02-03T14:59:07.587 回答
0

您可以使用基于资源的策略或基于身份的策略,而不是基于 IP 的策略,就像硬编码 IP 地址一样。

但是您需要使用 Signature 版本 4 来签署请求

对于 Java 实现,请参考http://mytechbites.blogspot.in/2017/04/secure-amazon-elastic-search-service.html

于 2017-04-04T12:26:17.290 回答
-2

我也在尝试这样做,并且我使用Allow access to the domain from specific IP(s)带有我的 EC2 实例的弹性 IP 的选项使其工作(也可以使用实例的私有 IP,但我不太确定)

于 2015-10-06T21:01:01.247 回答