Edited at

API Keyを使ったElasticsearchへのアクセス


はじめに

まいどおなj(ry


API Keyとは

Elasticsearch 6.7以降に追加されるAPI Key Serviceを使うと、BASIC認証の代わりにAPI Keyを使ってElasticsearchにアクセスできるようになります。

ドキュメントは、このへんです。


使い方

さっそく使ってみます。


準備

API Keyを使うには、Securityを有効にした状態のElasticsearchで、さらにTLS/SSLを有効にするか、xpack.security.authc.api_key.enabledをtrueにします。

細かいことは、ここに書いてあります。


API Keyの作成(その1)

準備ができたところで、API Keyを作成します。

Keyの作成は、以下のようなリクエストを送ります。

このリクエストでは、clusterに対するすべての権限を持ち、test_idx*というIndexに対してread権限を持つAPI Keyを作成しています。

POST /_security/api_key

{
"name": "api-key-1",
"role_descriptors": {
"role-a": {
"cluster": ["all"],
"index": [
{
"names": ["test_idx*"],
"privileges": ["read"]
}
]
}
}
}

すると、レスポンスとしてidapi keyが返ってきます。

{

"id" : "HW2CxWgBpzHQiGdVVGQo",
"name" : "api-key-1",
"api_key" : "AFBTRIOlS3eF1whp9qvnIw"
}


API Keyの確認

確認してみます。

GET _security/api_key?name=api-key-1

{

"api_keys" : [
{
"id" : "HW2CxWgBpzHQiGdVVGQo",
"name" : "api-key-1",
"creation" : 1549501879290,
"invalidated" : false,
"username" : "elastic",
"realm" : "reserved"
}
]
}

今回作成したAPI Keyは有効期限を指定していないのでexpirationの項目はありません。

よくよく見ると、API Key自体は返ってきません。なので、作成時のレスポンスに記載されたAPI Keyは忘れないように、どっかに保存しておきましょう。


API Keyの作成(その2)

え?さっき作成したでしょ?

いえ。実際に使うには、「<id>:<api key>」をbase64でエンコードしたものを使います。

その辺の話は、ここの下の方に書いてあります。

というわけで早速API Keyを作ります。

# echo -n HW2CxWgBpzHQiGdVVGQo:AFBTRIOlS3eF1whp9qvnIw | base64

SFcyQ3hXZ0JwekhRaUdkVlZHUW86QUZCVFJJT2xTM2VGMXdocDlxdm5Jdw==

できましたね。この「SFcyQ3hXZ0JwekhRaUdkVlZHUW86QUZCVFJJT2xTM2VGMXdocDlxdm5Jdw==」も重要なのでどっかに保存しておきます。


検索してみる

では、作成したAPI Keyを使って検索してみます。

# curl -H 'Authorization: ApiKey SFcyQ3hXZ0JwekhRaUdkVlZHUW86QUZCVFJJT2xTM2VGMXdocDlxdm5Jdw==' -H 'Content-type: application/json' 'http://localhost:9200/test_idx1/_search?pretty' -d'{"size": 0}'

Securityが有効なので、通常であれば-uでユーザとパスワードを指定するところですが、上のリクエストでは書いてませんね。

でも、ちゃんと結果は返ってきます。

{

"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.0,
"hits" : [ ]
}
}

curlだと長ったらしいので、HTTPieを使ってみます(若干癖がありますが)。

# http localhost:9200/test_idx1/_search Content-type:"application/json" Authorization:"ApiKey SFcyQ3hXZ0JwekhRaUdkVlZHUW86QUZCVFJJT2xTM2VGMXdocDlxdm5Jdw=="

ちゃんと結果が返ってきます。

HTTP/1.1 200 OK

content-encoding: gzip
content-length: 202
content-type: application/json; charset=UTF-8

{
"_shards": {
"failed": 0,
"skipped": 0,
"successful": 5,
"total": 5
},
"hits": {
"hits": [
{
"_id": "OVu3JmgBLVkCxyA_LNSK",
"_index": "test_idx1",
"_score": 1.0,
"_source": {
"foo": "bar"
},
"_type": "docs"
}
],
"max_score": 1.0,
"total": 1
},
"timed_out": false,
"took": 1
}

権限のないIndexを検索してみます。

# curl -H 'Authorization: ApiKey SFcyQ3hXZ0JwekhRaUdkVlZHUW86QUZCVFJJT2xTM2VGMXdocDlxdm5Jdw==' -H 'Content-type: application/json' 'http://localhost:9200/metricbeat-*/_search?pretty' -d'{"size": 0}'

検索結果がありませんね。ただ、エラーが出るわけじゃないですね。

ちょっとわかりにくいかも。

{

"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 0,
"successful" : 0,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : 0.0,
"hits" : [ ]
}
}


API Keyの無効化

では、API Keyを無効化してみます。

# curl -XDELETE http://localhost:9200/_security/api_key -d'{"name": "api-key-1"}' -H 'Content-type: application/json' -u elastic:<elasticユーザのパスワード>

{"invalidated_api_keys":["HW2CxWgBpzHQiGdVVGQo"],"previously_invalidated_api_keys":[],"error_count":0}

無事に無効化できました。

それでは、再度API Keyを使って検索してみます。

# http localhost:9200/test_idx1/_search Content-type:"application/json" Authorization:"ApiKey SFcyQ3hXZ0JwekhRaUdkVlZHUW86QUZCVFJJT2xTM2VGMXdocDlxdm5Jdw=="

ちゃんと無効化されていることがわかります。

HTTP/1.1 401 Unauthorized

WWW-Authenticate: Basic realm="security" charset="UTF-8"
content-encoding: gzip
content-length: 177
content-type: application/json; charset=UTF-8

{
"error": {
"header": {
"WWW-Authenticate": "Basic realm=\"security\" charset=\"UTF-8\""
},
"reason": "api key has been invalidated",
"root_cause": [
{
"header": {
"WWW-Authenticate": "Basic realm=\"security\" charset=\"UTF-8\""
},
"reason": "api key has been invalidated",
"type": "security_exception"
}
],
"type": "security_exception"
},
"status": 401
}


おわりに

若干動きが不思議ちゃん(KibanaのConsoleから無効化ができない)とかありますが、色々と遊べそうな機能ですね。