Amazon Elasticsearch ServiceのIAM Roleによるアクセス制御

Elasticsearch Service

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

藤本です。

Amazon Elasticsearch Service(以下、Amazon ES)のAWSアカウント、IAMを用いたアクセス制御時のDomainへのREST API利用方法がどうなるの?と気になったので調査してみました。

概要

Amazon ESのアクセス元制御として、AWSアカウント、IAMユーザー、IPアドレス等による制御が可能です。

Amazon ESはPublicな環境に作成されるため、IAM PolicyでIAM等で制御しない(Principalを*指定)場合、どこからでもアクセスが可能な状況となります。それは望ましくありません。Condition属性でIPアドレスベースのアクセス制御は可能ですが、アクセス元のインスタンス数が多い場合やAutoScaling内のインスタンスの場合、インスタンスの追加や入れ替えの度にIAM Policyを変更する必要があります。管理が煩雑となります。そういった場合、AWSアカウントやIAMによる権限管理が必要な場合が多々あります。
ElasticsearchはIndexやDocumentを作成したり、検索したりをREST APIによって操作します。Amazon ESは以下の画像にある通り、IAMの認証によりアクセス制御されます。ということは、AWSアカウントやIAMによる権限制御とした場合、DomainへのREST APIでも他のAWS API同様、リクエストにAWSの認証情報を組み込む必要があります。
_BDT209__Launch__Amazon_Elasticsearch_For_Real-Time_Data_Analytics

今回はPrincipal指定がないElasticsearch Domainに対して、AmazonESFullAccessを持つロールを設定したEC2インスタンスからREST APIを発行します。

環境

  • Amazon ESのIAM Policy:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Action": "es:*",
      "Resource": "arn:aws:es:ap-northeast-1:************:domain/fujimoto/*"
    }
  ]
}
  • EC2インスタンスのロールポリシー: AmazonESFullAccess
  • OS: Amazon Linux 2015.09

やってみた

まずはcurlでREST APIを利用してみます。

curl search-fujimoto-*******************.ap-northeast-1.es.amazonaws.com
{"Message":"User: anonymous is not authorized to perform: es:ESHttpGet on resource: arn:aws:es:ap-northeast-1:************:domain/fujimoto/"}

リクエストに認証情報がなく、権限なしエラーがレスポンスされました。

それでは、リクエストに認証情報を付けてみましょう。

今回は認証情報の生成にbotoパッケージを利用します。
botoパッケージを利用するとAWS APIリクエストの署名をした上で、任意のEndpoint、パス、メソッド、リクエストボディを指定したリクエストを発行する事が可能です。
サンプルスクリプトをGistに貼り付けました。

スクリプトにDomain Endpoint、リージョン、リクエストメソッド、リクエストパスの引数を与えて実行します。

# ./request_amazon_es.py search-fujimoto-******************.ap-northeast-1.es.amazonaws.com ap-northeast-1 GET /
{
  "status" : 200,
  "name" : "Flambe",
  "cluster_name" : "***********:fujimoto",
  "version" : {
    "number" : "1.5.2",
    "build_hash" : "62ff9868b4c8a0c45860bebb259e21980778ab1c",
    "build_timestamp" : "2015-04-27T09:21:06Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.4"
  },
  "tagline" : "You Know, for Search"
}

アクセスに成功しました。

まとめ

いかがでしたでしょうか?
簡単にまとめると。

  • Amazon Elasticsearch ServiceはAPI Endpoint、Domain Endpointの2つのEndpointが存在
  • API Endpoint(es.ap-northeast-1.amazonaws.com)への操作はaws-cli、boto3等のSDKで操作可能
  • Domain EndpointはIAM Policyによってアクセス制御
  • AWSアカウント、IAM等によりアクセス制御したい場合、AWS APIリクエストの署名を実装しないといけない
  • 今までElasticsearch標準のライブラリ、SDKを利用していた方はどうするんだろ?(ラッパのSDKが公開されるのかな)

脚注

Managing Amazon ES Domains