Elasticsearchのセキュリティプラグイン「Shield」を使ってみた

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

今日はShieldを試してみたいと思います!

Shield__Enterprise_Security_for_Elasticsearch___Elastic

通常Elasticsearchをそのまま使っている場合、特に認証機構などが無いので、IPアドレスとポートだけ分かっていれば誰でも使えてしまいます。このためSecurity Groupなどを使って、ネットワークレベルのフィルタリングでアクセス制御を行う必要がありました。

ShieldはElasticsearchのセキュリティプラグインです。Shieldを使うことで、Elasticsearchへのアクセスに認証と権限制御ができるようになります。さらに通信の暗号化やSSLクライアント認証、IPフィルタリングも可能になります!ユーザ操作の監査証跡もできます。Shiledを使うことで、Elasticsearchをセキュアに使うことが可能になります。これはもう必須プラグインと言っても良いのでは無いでしょうか。

なお、Shieldは商用プロダクトであり、インストール後30日間は試用ライセンスで動作しますが、その後はライセンスの購入が必要です。外部からアクセスされるようなシステムでElasticsearchを使う場合には、ライセンスの購入もご検討されてはいかがでしょうか。

さて、ではやってみましょう!

やってみた

Shieldのインストール

Elasticsearch自体はrpmでインストール済みとします。

$ rpm -qa | grep elasticsearch
elasticsearch-1.7.2-1.noarch

ShieldはPluginとしてインストールできます。また商用プロダクトなのでlicenseのインストールが必要になります。

$ sudo /usr/share/elasticsearch/bin/plugin install elasticsearch/license/latest
$ sudo /usr/share/elasticsearch/bin/plugin install elasticsearch/shield/latest

Pluginをインストールしたら、Elasticsearchを起動します。

$ sudo service elasticsearch start
Starting elasticsearch:                                    [  OK  ]

Elasticsearch起動時のログ。Shieldのライセンスが読み込まれています。また試用ライセンスであり、いつexpireされるのかが出力されていますね。

[2015-09-17 16:33:34,471][INFO ][shield.license           ] [Doctor Minerva] enabling license for [shield]
[2015-09-17 16:33:34,471][INFO ][license.plugin.core      ] [Doctor Minerva] license for [shield] - valid
[2015-09-17 16:33:34,494][ERROR][shield.license           ] [Doctor Minerva]
# Shield license will expire on [Saturday, October 17, 2015]. Cluster health, cluster stats and indices stats operations are
# blocked on Shield license expiration. All data operations (read and write) continue to work. If you

管理者ユーザーを作る

では、管理者(admin)のロールで、ユーザーを追加します。

$ sudo /usr/share/elasticsearch/bin/shield/esusers useradd admin -r admin
Enter new password:
Retype new password:

この状態で普通にGETしようとすると...はい、できません。Shieldが入っているので認証なしではデータが取得できなくなっています。

$ curl -XGET 'http://localhost:9200/'
{"error":"AuthenticationException[missing authentication token for REST request [/]]","status":401}

では、ユーザーを指定してアクセスしてみましょう。パスワードが求められた上で、データが取得できました!

$ curl -XGET -u admin 'http://localhost:9200/'
Enter host password for user 'admin':
{
  "status" : 200,
  "name" : "Doctor Minerva",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "1.7.2",
    "build_hash" : "e43676b1385b8125d647f593f7202acbd816e8ec",
    "build_timestamp" : "2015-09-14T09:49:53Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.4"
  },
  "tagline" : "You Know, for Search"
}

管理者じゃないユーザーを作る

先ほど管理者ユーザーを追加した時、-rで"admin"と指定しました。これがロールです。 Shieldでは、デフォルトで複数のロールが用意されています。これは/etc/elasticsearch/shield/roles.ymlに記述されています。

$ sudo cat /etc/elasticsearch/shield/roles.yml
# All cluster rights
# All operations on all indices
admin:
  cluster: all
  indices:
    '*': all

# monitoring cluster privileges
# All operations on all indices
power_user:
  cluster: monitor
  indices:
    '*': all

# Read-only operations on indices
user:
  indices:
    '*': read
(...以下省略...)

では、"user"ロールにユーザーを追加してみましょう。このユーザーはreadの権限しかありません。

$ sudo /usr/share/elasticsearch/bin/shield/esusers useradd smokeymonkey -r user
Enter new password:
Retype new password:

管理者ユーザーでデータをPUTしてみます。

$ curl -XPUT -u admin http://localhost:9200/mytest/test/1 -d '
{
  "id" : "1",
  "name"  : "daisuke"
}'
Enter host password for user 'admin':
{"_index":"mytest","_type":"test","_id":"1","_version":1,"created":true}

次に、readしかできないユーザーでデータをGETしてみます。当然できますね。

$ curl -XGET -u smokeymonkey http://localhost:9200/mytest/test/1 
Enter host password for user 'smokeymonkey':
{"_index":"mytest","_type":"test","_id":"1","_version":1,"found":true,"_source":
{
  "id" : "1",
  "name"  : "daisuke"
}}

さて、readしかできないユーザーでデータをPUTしてみます。はい、できません!

$ curl -XPUT -u smokeymonkey http://localhost:9200/mytest/test/2 -d '
{
  "id" : "2",
  "name"  : "fumihiko"
}'
Enter host password for user 'smokeymonkey':
{"error":"AuthorizationException[action [indices:data/write/index] is unauthorized for user [smokeymonkey]]","status":403}

というように、認証と権限制御ができました!

監査証跡を有効にする

elasticsearch.ymlを編集し、以下行を追加します。

$ sudo vi /etc/elasticsearch/elasticsearch.yml
shield.audit.enabled: true

そしてElasticsearchを再起動します。

$ sudo service elasticsearch restart

この状態でElasticsearchにアクセスすると、監査ログが記録されます。

$ cat /var/log/elasticsearch/elasticsearch-access.log
[2015-09-17 16:51:36,991] [Cletus Kasady] [rest] [anonymous_access_denied]	origin_address=[/127.0.0.1:39232], uri=[/]

出力するログファイルやログのレベル、ログフォーマットについてはConfiguring Auditingをご覧下さい。

最後に

冒頭で述べた通り、セキュアにElasticsearchを使うためには必須のプラグインだと思います!さ、次はMarvelをやってみようかな!