こんにちは、ちゃりおです。
今回は、アクセスポリシーでIAMロールを制限したElasticSearch(以下 ES)にcurlする方法です。
厳密には、curlでは署名をつけてリクエストできないためcurlは使えません。
代替手段として、「awscurl」について紹介します。
経緯
各システムで共通の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リソースにアクセスするためのツールです。
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とほぼ同じように使えるので試してみてください。