2018年9月6日 エンジニアリング

セキュリティ機能のはじめ方

著者 Kosho Owa

Elastic Stackがオプション機能の1つとして提供する「セキュリティ」には、Elastic Stackをセキュリティ上の脅威から守る様々な機能があります。本ブログポストでは、その中から以下のそれぞれのセットアップ方法をステップ・バイ・ステップで紹介します。

  • Elasticsearchへのアクセスの認証・認可
  • クライアント−Elasticsearchクラスター間の通信の暗号化(HTTPS)
  • Elasticsearchノード間の通信の暗号化
  • Kibanaへのアクセスの暗号化(HTTPS)
  • 監査ログの出力

前提条件

当社のウェブサイトから、Elastic Stackをダウンロードしてセットアップを終えてください。6.2以前のバージョンを利用する場合には、別途X-Packを入手しインストールします。本番環境での運用を考慮し、複数台のElasticsearchノードからなるクラスターで紹介している構成を対象とします。ElasticsearchとKibanaのオフィシャルマネージドサービスであるElasticsearch Serviceでは、こららの一部はすでに有効であることと、操作方法が異なりますので、本稿では取り扱いません。

トライアルの開始、もしくはライセンスの有効化

トライアルの開始

Kibanaにブラウザでアクセスし、Admin > License Management から Start Trial ボタンを押し、セキュリティを含むオプション機能のトライアルを開始します。すでにライセンスを入手している場合には、ライセンスファイルをアップロードすることにより、有効化することができます。Kibanaを利用しない場合には、以下のようなリクエストをElasticsearchクラスターに送ることにより、トライアルを開始することができます。

$ curl -XPOST http://<ES_NODE>:9200/_xpack/license/start_trial?acknowledge=true

現在のライセンス状態を知るには、

$ curl http://<ES_NODE>:9200/_xpack/license

などとして、statustypeを確認してください。
トライアル期間が終了している、または検証のために延長したい場合には、こちらよりお気軽にご連絡ください。

セキュリティの有効化と、ビルトインユーザーのパスワードの設定

sudo service elasticsearch stopコマンドなどで、全てのElasticsearchノード を停止します。セキュリティを有効にするために、

xpack.security.enabled: true

の一行をelasticsearch.ymlに追加してください。全てのサーバーで設定を終えたら、sudo service elasticsearch startコマンドで、それぞれのElasticsearchインスタンスを起動します。

この段階では、それぞれのElasticsearchノードにおいて、インストール時に生成されたelasticsearch.keystoreファイルを使ったファイルレルムによる認証が有効になっています。curl -I http://<ES_NODE>:9200コマンドなどでアクセスを試みると、HTTP/1.1 401 Unauthorizedが返されることがわかります。

いずれかのサーバーにログインし、以下のコマンドでネイティブ認証を有効にしパスワードをリセットします。このパスワードは、クラスター全体で有効です。

$ sudo <ES_HOME>/bin/elasticsearch-setup-passwords auto

RPMなどでインストールした場合には<ES_HOME>として/usr/share/elasticsearch/を指定します。そのほかの場合にはアーカイブを展開したディレクトリを確認してください。

ビルトインユーザ(elastic、kibana、logstash_system、beats_system)のパスワードが表示されますので、メモしておきます。早速elasticユーザーと、生成されたパスワードでアクセスしてみます。

$ curl -u elastic:<ELASTIC_PASSWORD> http://<ES_NODE>:9200/_cat/nodes?v

全てのElasticsearchノードが表示されれば成功です。

Kibanaを利用する場合には、kibana.ymlに以下の記述を追加して、起動します。

elasticsearch.username: "kibana"
elasticsearch.password: "<KIBANA_PASSWORD>"

sudo service kibana restartコマンドで、Kibanaを再起動します。ブラウザでKibanaにアクセスし、先のelasticユーザーでログオンできるか確認してください。そのほかのユーザーやロールを作成したい場合には、Management > Security より行うか、APIを使用して下さい。

クライアントと、ノード間の通信の暗号化

Elasticsearchノードとクライアントの間の通信は、初期値ではHTTPで行われます。これをHTTPSにすることができます。また、Elasticsearchノード間の通信は平文で行われていますが、ノード同士で認証させ通信も暗号化することができます。

認証局とノード証明書の作成

組織でウェブサーバーなどの証明書の発行手順が定められている場合には、それに従います。必要なものは認証局の公開鍵(PKCS#12とPEM形式)、各Elasticsearchノード(もしくは全てのノードで共通)の公開鍵と秘密鍵(PKCS#12形式)、Kibanaの公開鍵と秘密鍵(PEM形式)です。公開鍵は単に「証明書」と呼ばれることがあります。

Elasticsearchに同梱されているツールを使って、公的な認証局(CA)の手を借りずに、自身が認証局となり証明書(cert)を発行することもできます。ここでは、その手順を紹介します。

まずは、認証局を作成するために、いずれかのElasticsearchノードで、以下のコマンドを実行して下さい。

# <ES_HOME>/bin/elasticsearch-certutil ca
Please enter the desired output file [elastic-stack-ca.p12]: <任意のファイル名もしくは空白>
Enter password for elastic-stack-ca.p12 : <任意のパスワードもしくは空白>

出力されたelastic-stack-ca.p12ファイルは認証局ですので、大切に保管して下さい。これには、認証局の公開鍵と、秘密鍵が含まれます。openssl pkcs12 -in elastic-stack-ca.p12 -nodesコマンドで、内容を確認することができます。

次に、この認証局の秘密鍵を使って、Elasticsearchノードの証明書を発行します。

ノード証明書を発行するには、以下のコマンドを入力して下さい。

# <ES_HOME>/bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12
Enter password for CA (elastic-stack-ca.p12) : <CAのパスワードもしくは空白>
Please enter the desired output file [elastic-certificates.p12]: <任意のノード証明書のファイル名もしくは空白>
Enter password for elastic-certificates.p12 : <ノード証明書のパスワードもしくは空白>

Elasticsearchノードは、同一の認証局によって署名された証明書をもつElasticsearchノードとの通信を許可します。先のコマンドに--name--dns--ipオプションを用いて、各ノードごとに異なる証明書を発行することもできますし、全く同一の証明書を配布することもできます。各ノードごとに異なる証明書を発行した場合には、これに追加してサーバー名やIPアドレスなどの情報が一致した場合にのみ、クラスターに受け入れるように設定することができます。

このノード証明書には、認証局の公開鍵、ノードの公開鍵、秘密鍵が含まれます。内容を確認するにはopenssl pkcs12 -in elastic-certificates.p12 -nodesコマンドを実行します。

KibanaやBeats、Logstash、その他のクライアントアプリケーションがElasticsearchとHTTPで通信するためには、認証局の公開鍵が必要です。以下のコマンドを用いると認証局の公開鍵をPEM形式で取り出すことができます。ファイル名はelastic-stack-cacert.pemとします。

$ openssl pkcs12 -in elastic-stack-ca.p12 -out elastic-stack-cacert.pem
Enter Import Password: <CAのパスワードもしくは空白>
MAC verified OK
Enter PEM pass phrase: <空白>

証明書の配布と設定

全てのElasticsearchノード、Kibanaを停止します。それぞれのElasticsearchノードに、ノード証明書elastic-certificates.p12を配布します。/etc/elasticsearch/certsディレクトリなどにコピーします。sudo chmod 660として、適切なアクセス権を設定して下さい。

以下の設定を、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

本例では、全てのElasticsearchノードで同一の証明書を使用していますが、ノード毎に異なる証明書を作成した場合には、xpack.security.transport.ssl.verification_mode: fullと設定(初期値)すると、証明書に加えて通信相手のホスト名やIPアドレスでも認証を行うことができます。設定を終えたら、全てのElasticsearchノードを起動します。

全てのノードが正常に通信できているかどうかは、以下のリクエストで確認することができます。

$ curl https://<ES_IP_ADDR>:9200/_cat/nodes?v -u elastic:<ELASTIC_PASSWORD> --insecure
ip            heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
172.16.82.27            11          78   1    0.01    0.04     0.01 mdi       *      2cXo9Re
172.16.85.237           12          78   1    0.00    0.05     0.02 mdi       -      NCQZASC
172.16.80.104           10          80  29    0.38    0.13     0.04 mdi       -      kQ6HNeQ

Kibanaを使用する場合には、先に作成したelastic-stack-cacerts.pemを任意のディレクトリにコピーし、以下のようにkibana.ymlの設定を変更、追加します。

elasticsearch.url: "https://<ES_IP_ADDR>:9200"
elasticsearch.ssl.certificateAuthorities: /etc/kibana/elastic-stack-cacert.pem
elasticsearch.ssl.verificationMode: certificate

elasticsearch.urlの接続先のURLが https になっていることに注意して下さい。
Kibanaを起動します。

Kibanaへの通信の暗号化

Kibanaはウェブサーバーとして機能します。HTTPSでユーザーにサービスを行う場合には、その証明書(公開鍵)と秘密鍵が必要です。組織で定められた手順に従って、それぞれ入手して下さい。すぐに入手できない場合には、elasticsearch-certutilコマンドで先に作った認証局を利用して、臨時に作成することができます。

$ bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12 --pem --name kibana

出力されたcertificate-bundle.zipには、kibana.crtkibana.keyが含まれ、それぞれ証明書と秘密鍵です。Kibanaを運用するサーバーの/etc/kibanaなどにコピーして下さい。秘密鍵にはsudo chmod 660 kibana.keyとして、適切なアクセス権を設定して下さい。以下の設定をkibana.ymlに追加し、Kibanaを再起動します。

server.ssl.enabled: true
server.ssl.key: /etc/kibana/kibana.key
server.ssl.certificate: /etc/kibana/kibana.crt

ブラウザでhttps://<KIBANA_IP_ADDR>:5601にアクセスします。自身で作成した認証局によって証明書を作成した場合には、警告メッセージが表示されます。

監査ログの出力

Elasticsearchノードへの接続や、インデックス、クラスターへの操作の成功・失敗などを、監査ログとして出力することができます。出力先として、ログファイルと、Elasticsearchのインデックスを指定することができます。初期値ではログファイルにのみ記録しますので、インデックスに記録するには以下のようにelasticsearch.ymlに設定します。

xpack.security.audit.enabled
xpack.security.audit.outputs: index

監査ログのインデックス名は.security_audit_log-YYYY.MM.DDです。

Kibanaへのログオンの成功・失敗なども監査ログとして記録することができます。これは、Kibanaの標準ログと共に出力されます。そのためには、以下の設定をkibana.ymlに追加します。

xpack.security.audit.enabled: true

監査ログを有効にするには、それぞれサービスの再起動が必要です。

まとめ

Elasticsearchへのアクセス認証、クライアント・ノード間通信の暗号化、監査ログの出力の方法を紹介しました。これらは「セキュリティ」として提供していますが、それぞれの機能は独立していますので、一部だけ有効にすることも可能です。また、豊富な設定オプションを用意していますので、ドキュメントもご覧ください。

「セキュリティ」が提供するのは、ここで紹介した機能に留まりません。IPアドレスによるアクセス制限や、Active Directory/LDAP連携やSAMLによるユーザー認証・認可、役割ベース・属性ベースのアクセス制御などもあります。ドキュメント検索から、ログ分析、セキュリティ分析、ビジネス分析など、幅広いユースケースでElastic Stackは使用されていますが、それ自身のセキュリティを担保することも非常に重要です。これらの設定を正しく行い、より安全に運用して下さい。