インフラ

IAMロールでアクセス制限したAmazon ElasticSearchにcurlする方法(aws curl)

es iamrole

こんにちは、ちゃりおです。

今回は、アクセスポリシーでIAMロールを制限したElasticSearch(以下 ES)にcurlする方法です。
厳密には、curlでは署名をつけてリクエストできないためcurlは使えません。
代替手段として、「awscurl」について紹介します。

Contents

経緯

各システムで共通のESを使用しています。ESはVPCエンドポイントです。
サービスごとにアクセスできるインデックスを制御したかったので、アクセスポリシーでIAMロールを制限しました。
(各チームが自チーム以外のインデックスの中身を見れるのは望ましくないため)

Amazon Elasticsearch Service の Identity and Access Management

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": 
      },
      "Action": "es:*",
      "Resource": [
        "/<ドメイン>/indexA*",
        "/<ドメイン>/indexA*/*",
        "/<ドメイン>/_cat/indices",
        "/<ドメイン>/_cat/indices/*"
      ]
    }
  ]
}

運用作業などで「_cat/indices」は見れる状態にしておきたかったため上記の設定になっています。

ポリシーを設定後、アプリケーション側でESへのリクエスト時にIAMロールの認証情報を使って署名するように変更すれば完了です。
これで各チームが他チームのインデックスの操作ができなくなりました。

しかし、ここで問題が発生します。
「運用サーバからcurlでESにリクエストができない。」

アクセスポリシーでIAMロールを指定すると、ESへのリクエスト時に署名が必要になります。
しかし、curlでは署名を含むことができません。

Amazon Elasticsearch Service への HTTP リクエストの署名

そこで、awscurlの出番です。

awscurl

awscurlとは

python製のAWS署名を使用してAWSリソースにアクセスするためのツールです。

okigan / awscurl

AWSサポートに聞いたところ、こういった用途で使用する推奨のツールはないとのことでした。
実績がある・pipでインストールが可能なためこのツールを導入しました。

awscurlのインストール方法

amazonlinux2の環境にインストールしました。

$ pip install awscurl

コマンド例

$ export AWS_ACCESS_KEY_ID="<アクセスキー>"
$ export AWS_SECRET_ACCESS_KEY="<シークレットアクセスキー>"
$ export AWS_SESSION_TOKEN="<セッショントークン>"
$ export AWS_DEFAULT_REGION="ap-norhteast-1"
$ awscurl --service es /_cat/indices

便利に使う方法

下記の記事のやり方がとても便利でした。
毎回、環境変数にセットするのは面倒なので、ラッパースクリプトを使うやり方おすすめです。(jqのインストールが必要です)

https://muziyoshiz.hatenablog.com/entry/2019/11/30/144213

ラッパースクリプトを配置します。

$vi /usr/local/bin/awscurl-on-ec2

「/usr/local/bin/awscurl-on-ec2」の内容は以下にします。
僕の環境では、ESのみでしか使わない・ap-northeast-1以外にはリソースがないため少し変えています。

#!/bin/env bash
ROLE_NAME=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/`
CRED=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${ROLE_NAME}`
AWS_ACCESS_KEY_ID=`echo $CRED | jq -r ".AccessKeyId"`
AWS_SECRET_ACCESS_KEY=`echo $CRED | jq -r ".SecretAccessKey"`
AWS_SESSION_TOKEN=`echo $CRED | jq -r ".Token"`

awscurl --service es "$@" --region ap-northeast-1

実行権限を与えて準備完了です。

$sudo chmod +x /usr/local/bin/awscurl-on-ec2

以下のように実行できます。

$awscurl-on-ec2 /_cat/indices

まとめ

今回は、awscurlについて紹介しました。
ESのアクセス制御は悩ましいですね。

ラッパースクリプトを使えば、curlとほぼ同じように使えるので試してみてください。

Amazonで「AWSの本」をみてみる!!

es書評
【書評】ElasticSearch実践ガイドこんにちは、ちゃりおです。 今回は、下記の本の書評です。 基本的な用語から解説されていて、初めてElasticSearch触る人にもお...
es workshop
Amazon Elasticsearch Service Intro Workshopをやってみたこんにちは、ちゃりおです。 最近ElasticsearchServiceを触る機会があり、チュートリアル的なものをやりたいと思っていま...
aws es 推奨
Amazon ElasticSearch Searviceの推奨構成についてこんにちは、ちゃりおです。 AWSのElasticSearchを使っているのですが、たまにトラブルが発生していました。 (データノード...