この記事は Elasticsearch のベーシックライセンス(デフォルトの配布)で、Elastic Stack 6.8 および 7.1 から一部無料になったセキュリティ機能の設定を調査、実施した内容をまとめたものです。
目次
動機と前提
検証・調査のためにいろいろ試行錯誤できる Elasticsearch を設置したいと考えました。
検証用途なので、できるだけリーズナブルに運用するため、フルマネージドのサービスは使用せず、社用のVPS上に構築して、Elastic Stack 6.8 および 7.1 から一部が無料になっているセキュリティ機能の設定を行ってみました。
環境は CentOS 7 に Elasticsearch と Kibana(バージョンは 7.6.2)がインストールされている状態です。
また、Elasticsearch はシングルノードで構築しています。
セキュリティって?
ご存じの方には釈迦に説法ですが、セキュリティを有効化する前に、そもそも何を行えばセキュリティが有効になっている(扱う情報が守られた状態になっている)のかを考えてみたいと思います。
まずわかりやすいのは、 認証
かと思います。
ユーザー名とパスワードを用いて、ログインしようとしているユーザーがそのサービスの正当なユーザーかどうかを判別するサービスを目にする機会は多いかと思います。認証を行うことで、大切な情報を不正なユーザーに閲覧、操作されることを防ぐことができます。
次に 認可
です。
認証
によって、正当なユーザーかどうかを判別できたとしても、ログインできたユーザーが全ての情報にアクセスできる状態では、誤って他のユーザーに必要な情報を壊したり削除してしまうかもしれません。多くのサービスはユーザー毎に情報への適切なアクセス許可が必要になります。ロールの設定、などと呼ばれるようなアクセス権限を施すことで、適切なユーザーが適切な情報へアクセスすることができます。
最後に 暗号化
です。
単純に暗号化という言葉だけでは様々な意味が考えられますが、ここでは通信する情報の内容を第三者に盗聴されたり改ざんされたりすることを防ぐ手法を指します。
せっかく 認証
、 認可
をおこなっていても、通信中に情報が漏洩し、改ざんされてしまっては意味がありませんので、通信する情報を暗号化する必要があります。
認証
、認可
、暗号化
が揃うことで、最低限のセキュリティを有効にしたといえそうですので、これらの設定を行っていきたいと思います。
Elastic Security の有効化とビルトインユーザーのパスワードの設定
Elastic Security を有効化するためには、以下の一行を elasticsearch.yml
へ追記します。
xpack.security.enabled: true
追記できたら、サービスを再起動します。
$ sudo systemctl restart elasticsearch
パスワードの設定
次に、以下のコマンドでネイティブ認証を有効にして、ビルトインユーザーのパスワードをリセットします。
※今回はシングルノードで構成していますが、このパスワードは、クラスター全体で有効になるようです。
※<ES_HOME>
は Elasticsearch がインストールされているディレクトリです。
$ sudo <ES_HOME>/bin/elasticsearch-setup-passwords auto
ビルトインユーザー(elastic、kibana、apm_system、logstash_system、beats_system、remote_monitoring_user)のパスワードが表示されるので、控えておきます。
ちなみに、オプションを auto
ではなく interactive
にすると、対話形式で一つ一つパスワードの設定が行えます。
Kibana の設定
Kibana を使用するために、 kibana.yml
へ Elasticsearch のユーザーとして、先程生成したビルトインユーザー kibana
と、そのパスワードを追記してサービスを再起動します。
elasticsearch.username: "kibana" elasticsearch.password: "<KIBANA_PASSWORD>"
$ sudo systemctl restart kibana
ブラウザで Kibana にアクセスし、ビルトインユーザー elastic
でログオンできれば成功です。
この時点で、Kibana の Management
→ Security
から、ユーザーとロールの作成、設定、削除が行えるようになります。
任意のユーザーを作成、設定して、そのユーザーで Kibana へログインし直すこともできます。
これで、 認証
と 認可
が行えるようになりました。
通信の暗号化
続けて 暗号化
を行っていきます。
Elasticsearch ノードとクライアントの通信はデフォルトではメッセージを平文のままで送受信する HTTP で行われていますが、これを暗号化された HTTPS にすることができます。
Kibana との通信も同様です。
必要になるものは次のとおりです。
公開鍵、秘密鍵、認証局
公開鍵、秘密鍵、認証局をそれぞれ簡単に説明すると、次の通りです。
- 公開鍵: 通信を暗号化するための鍵(データ)です。秘密鍵から作られ、単に「証明書」と呼ばれたりします。
- 秘密鍵: 暗号化された通信を復号化するための鍵(データ)です。
- 認証局: 公開鍵証明書の発行者です。
暗号化の手法や規格は、Wikipedia 等でも確認することができます。
公開鍵暗号 - Wikipedia
公開鍵証明書 - Wikipedia
認証局 - Wikipedia
PKCS - Wikipedia (PKCS#12の解説が確認できます)
X.509 - Wikipedia (PEM形式の解説が確認できます)
認証局の作成
Elasticsearch に同梱されているツールを使って、認証局(ファイル)を作成することができます。
コマンドは以下のとおりです。
$ <ES_HOME>/bin/elasticsearch-certutil ca
コマンドを実行すると、対話形式で任意のファイル名とパスワードを求められますが、何も指定せずに進めることもできます。
その場合、認証局のファイル名は elastic-stack-ca.p12
となります。
作成したファイルには、認証局の公開鍵と、秘密鍵が含まれます。
openssl pkcs12 -in elastic-stack-ca.p12 -nodes
コマンドで、内容を確認することができます。
Elasticsearch ノードの証明書の発行
次に、認証局の秘密鍵を使って、Elasticsearchノードの証明書の発行します。
コマンドは以下のとおりです。
$ <ES_HOME>/bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12
こちらも対話形式で、任意のファイル名やパスワードを求められますが、指定なしで進めることができます。
指定なしで進めた場合の証明書のファイル名は elastic-certificates.p12
となります。
この証明書には、認証局の公開鍵、ノードの公開鍵、秘密鍵が含まれます。内容は openssl pkcs12 -in elastic-certificates.p12 -nodes
コマンドで確認することができます。
Elasticsearch と通信するための公開鍵の作成
Kibana が Elasticsearch と通信するために、認証局の公開鍵が必要になります。
以下のコマンドを用いると認証局の公開鍵をPEM形式で取り出すことができます。ファイル名は elastic-stack-cacert.pem
としています。
$ openssl pkcs12 -in elastic-stack-ca.p12 -out elastic-stack-cacert.pem
このとき、対話形式で認証局のパスワードが求められますので、設定していたパスワードを入力します(何も設定しなかった場合はそのまま進めます)。
続けてパスフレーズが求められますが、こちらは 4~1024文字のパスフレーズが必要
になるので、注意が必要です。
各証明書の配置と設定
Elasticsearch
Elasticsearch ノードの証明書 elastic-certificates.p12
を /etc/elasticsearch/certs
などのディレクトリへ配置します。
このとき、sudo chmod 660 elastic-certificates.p12
として、適切なアクセス権を設定する必要があります。
配置が行えたら、 elasticsearch.yml
へ以下の設定を追加します。
xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.verification_mode: certificate xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12 xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12 xpack.security.http.ssl.enabled: true xpack.security.http.ssl.keystore.path: certs/elastic-certificates.p12 xpack.security.http.ssl.truststore.path: certs/elastic-certificates.p12
サービスを再起動すると、先に設定していたユーザー名とパスワードで https://<ES_DOMAIN>:9200/
へアクセスできるようになります。
※ http://~
ではなく、https://~
になっています。
※ <ES_DOMAIN>
は、Elasticsearch が稼働しているサーバのドメイン名 or IPアドレスです。
Kibana(Kibana と Elasticsearch の通信)
Kibana から Elasticsearch へ通信するために、認証局の公開鍵 elastic-stack-cacerts.pem
を任意のディレクトリ /etc/kibana
等にコピーして、以下の設定を kibana.yml
に追加します。
elasticsearch.hosts: ["https://<ES_DOMAIN>:9200"] elasticsearch.ssl.certificateAuthorities: [ "/etc/kibana/elastic-stack-cacert.pem" ] elasticsearch.ssl.verificationMode: certificate
Kibana(クライアントと Kibana の通信)
今度はクライアントから Kibana への通信を暗号化します。
公的な認証局を介する代替として、最初に作成した認証局で Kibana の公開鍵と秘密鍵を作成する手段が提供されています。
以下のコマンドで、Kibana の公開鍵と秘密鍵を作成します。
$ <ES_HOME>/bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12 --pem --name kibana
実行すると、certificate-bundle.zip
という zip ファイルが出力されます。
zip には kibana.crt
と kibana.key
が含まれていて、公開鍵(証明書)と秘密鍵になります。
それぞれ、/etc/kibana
などのディレクトリへコピーします。
また、sudo chmod 660 kibana.key
で適切なアクセス権を設定する必要があります。
ファイルの配置が行えたら、 kibana.yml
へ以下の設定を追加します。
server.ssl.enabled: true server.ssl.key: /etc/kibana/kibana.key server.ssl.certificate: /etc/kibana/kibana.crt
再度、サービスを再起動して、ブラウザから https://<KIBANA_DOMAIN>:5601
へアクセスできれば成功です。
※<KIBANA_DOMAIN>
はKibanaを稼働させているサーバのドメイン名です。
※今回の例では、公的な認証局を通していないため、ブラウザの警告が出るかと思います。
以上で、Elasticsearch と Kibana の 暗号化
の設定が行えました。