LoginSignup
9
6

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-02-07

はじめに

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

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6