LoginSignup
29
28

More than 5 years have passed since last update.

Amazon Elasticsearch Service を Python クライアントで、IAM アカウントを作ってセキュアにアクセスする

Last updated at Posted at 2016-01-07

Amazon Elasticsearch Service は、アクセス制御が IAM や IPアドレスでできます。最初は IPアドレスフィルタでいじってたのですが、将来的にドツボにはまりそうだったため IAM で行うようにしました。

なお、Amazon Elasticsearch Service のアクセスポリシーの変更は、指定してから20分ぐらい待たないと反映されないため、面倒です。早めの IAM 化が楽だと思います。(反映待ちの間もサービスは使えます)

IAM ユーザーの作成

IAM のユーザーページ
https://console.aws.amazon.com/iam/home#users
より「新規ユーザーの作成」
→適当に作ります

完成後、 「ユーザーのセキュリティ認証情報を表示」リンクをクリックして、
アカウント名、アクセスキー IDシークレットアクセスキー を記録しておきます。

できたら、左タブより「ユーザー」ページを表示し、先ほど作成したユーザーを選択。
ユーザーのARN」が表示されているので、これもコピーしておきます。

こんなの → arn:aws:iam::000000000000:user/xxxxxxxxxxxxx

Elasticsearch のアクセスポリシーの作成

Amazon Elasticsearch Service dashboard
https://ap-northeast-1.console.aws.amazon.com/es/home

を開き、ドメインを選択。

Modify access policy → Select a template → Allow or deny access to one or more AWS accounts or IAM users を選択。

Effect: Allow にして、 Account ID or ARN  に先ほどの ARN をペースト。

アクセスポリシーの JSON が生成されるので、「Submit」→「OK」とボタンを押します。

再度、Modify access policy ページを開くと、Status が Processing になります。反映されるとここが Active になります(ブラウザリロード不要)。20分ぐらいかかります。

IPアドレスでも許可する場合

この手順でアクセスポリシーを作った場合、IAM 認証をしないと ES にアクセスできないため、Kibana をブラウザから見たい場合ちょっと困ります。そのため、Kibana にアクセスする IPアドレスを OR 条件で許可した方が使い勝手が良いでしょう。

アクセスポリシーの Statement リストに、ポリシーを追加します。
(上のがIPアドレスホワイトリスト、下のが IAM での制御)

Edit_the_access_policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "es:*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": [
            "000.000.000.000"
          ]
        }
      },
      "Resource": "arn:aws:es:ap-northeast-1:000000000000:domain/hogehoge/*"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::000000000000:user/xxxxxxxxxxxxx"
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:ap-northeast-1:000000000000:domain/hogehoge/*"
    }
  ]
}

テストスクリプトの作成

https://github.com/elastic/elasticsearch-py/issues/280 この Issue を参考に

必要ライブラリのインストール

$ pip install elasticsearch requests_aws4auth

(もしかしたら requests も必要かもしれません。僕の環境では既に入ってたので必要かわかりませんでした)

コード

import elasticsearch
from requests_aws4auth import AWS4Auth

host = 'xxxxxxxx.ap-northeast-1.es.amazonaws.com'
awsauth = AWS4Auth(
    'アクセスキーID',
    'シークレットアクセスキー', 'ap-northeast-1', 'es')

es = elasticsearch.Elasticsearch(
    hosts=[{'host': host, 'port': 443}],
    http_auth=awsauth,
    use_ssl=True,
    verify_certs=True,
    connection_class=elasticsearch.connection.RequestsHttpConnection
)
print(es.info())
print(es.cluster.health())

先ほどの、AWSの Elasticsearch の アクセスポリシーページの、「Status」が「Active」になるまで待ちます。
ページを開きっぱなしで待ってて良いです。(ブラウザのリロードを連打しなくても良い)

Active になる前だと

elasticsearch.exceptions.AuthorizationException: TransportError(403, '{"Message":"User: arn:aws:iam::000000000000:user/xxxxxxxxxxxxx is not authorized to perform: es:ESHttpGet on resource: arn:aws:es:ap-northeast-1:000000000000:domain/hogehoge/"}')

このエラーになります。

Status が Active になった後は

{'version': {'lucene_version': '4.10.4', 'build_timestamp': '2015-04-27T09:21:06Z', 'build_snapshot': False, 'build_hash': '62ff9868b4c8a0c45860bebb259e21980778ab1c', 'number': '1.5.2'}, 'status': 200, 'cluster_name': '000000000000:hedgehoge', 'tagline': 'You Know, for Search', 'name': 'Ororo Munroe'}
{'active_primary_shards': 11, 'number_of_pending_tasks': 0, 'cluster_name': '000000000000:hedgehoge', 'relocating_shards': 0, 'active_shards': 11, 'status': 'yellow', 'timed_out': False, 'number_of_nodes': 1, 'unassigned_shards': 11, 'number_of_data_nodes': 1, 'initializing_shards': 0}

結果が返ってきます🎉

…ビルド古い…

29
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
28