Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

まいどおな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から無効化ができない)とかありますが、色々と遊べそうな機能ですね。

tak7iji
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした