エンジニアリング

SSL、TLS、HTTPSを設定してElasticsearch/Kibana/Beats/Logstashを安全に保つ

6.7.x / 7.0.x以前のElastic Stackをお使いですか? その場合は、お使いのバージョンで通信を安全に保つヒントとなるブログ記事"How to setup TLS for Elasticsearch, Kibana, Logstash and Filebeat with offline install in Linux(LinuxにオフラインインストールでElasticsearch、Kibana、Filebeat、LogstashにTLSを設定する)"をご参照ください。本記事は、Elastic Stack 6.8 / 7.1以降に搭載されている無料のセキュリティ機能について取り上げています。

Elastic Stack 6.8および7.1より一部のセキュリティ機能が無料になり、デフォルトの配布(ベーシックライセンス)に含まれるようになりました。 新たに無料化された機能に、SSLを使用したネットワークトラフィックの暗号化、ユーザーの作成と管理、インデックスとクラスターレベルのアクセスを保護するロール定義、Kibanaの安全な制御などがあります。前回、無料化のリリース直後にお届けしたブログ記事「Elasticsearch Securityを使いはじめる」では、ElasticsearchとKibanaの間でTLS通信を使用する方法をご説明しました。本記事はさらに一歩進んで、LogstashとBeatsを含むその他のElastic Stackコンポーネントでセキュリティ機能を活用するためのガイダンスです。具体的にはコンポーネント間でTLSを有効化する方法と、HTTPクライアント通信を暗号化する方法を取り上げます。

HTTPレイヤーでのTLS有効化は絶対に必要というわけではありませんが、データをエンドツーエンドで保護するために強く推奨されています。特に、ユーザー名/パスワード情報を盗難から保護し、クラスターの感染を防止する上で重要です。TLS暗号化や認証、制限付きスクリプト、分離などについて詳しく知りたいという方は、ぜひブログ記事「暗号化やユーザー認証の活用でElasticsearchクラスターを無料で、安全に保つ」をご覧ください。

また、本記事でご紹介するセキュリティ機能は、Elastic CloudのElasticsearch Serviceでは標準仕様で有効化されています。Elasticsearch Serviceをお使いの場合、手順5から開始していただくことができます。

Elastic Stackを安全に保つための手順

  1. 準備
  2. SSL証明書を作成し、ノード1でElasticsearch用にTLSを有効化する
  3. ノード1でKibana用にTLSを有効化する
  4. ノード2でElasticsearch用にTLSを有効化する
  5. ノード1にLogstashユーザーを準備する
  6. ノード1でLogstash用にTLSを有効化する
  7. ノード1でFilebeatを実行し、TLSをセットアップする
  8. Filebeatを使用してデータを投入する

Elastic Stackダイヤグラム

手順1:準備

Elastic Stack 7.1以降に含まれる、次のコンポーネントをダウンロードします。

[1-1] /etc/hostsファイルを設定する

この事例ではノード1(node 1)にブラウザをインストールし、kibana.localでKibanaのWebページにアクセスできるように設定します。

# ノード1の /etc/hosts ファイル(kibana.localおよびlogstash.localが必要です)
127.0.0.1 kibana.local logstash.local
192.168.0.2 node1.elastic.test.com node1
192.168.0.3 node2.elastic.test.com node2
# ノード2の /etc/hosts ファイル(こちらはkibana.localおよびlogstash.localは不要です)
192.168.0.2 node1.elastic.test.com node1
192.168.0.3 node2.elastic.test.com node2

手順2:SSL証明書を作成し、ノード1でElasticsearch用にTLSを有効化する

[2-1] 環境変数を設定する(Elasticsearchをダウンロードした場所と方法に応じて変数のパスを調整する)

[root@node1 ~]# ES_HOME=/usr/share/elasticsearch
[root@node1 ~]# ES_PATH_CONF=/etc/elasticsearch

[2-2] tmpフォルダーを作成する

[root@node1 ~]# mkdir tmp
[root@node1 ~]# cd tmp/
[root@node1 tmp]# mkdir cert_blog

[2-3] インスタンスyamlファイルを作成する

[root@node1 cert_blog]# vi ~/tmp/cert_blog/instance.yml
# インスタンス情報をymlファイルに追加
instances:
  - name: 'node1'
    dns: [ 'node1.elastic.test.com' ]
  - name: "node2"
    dns: [ 'node2.elastic.test.com' ]
  - name: 'my-kibana'
    dns: [ 'kibana.local' ]
  - name: 'logstash'
    dns: [ 'logstash.local' ]

[2-4] (Elasticsearchのインストール完了後、)CAとサーバー証明書を生成する

[root@node1 tmp]# cd $ES_HOME
[root@node1 elasticsearch]# bin/elasticsearch-certutil cert --keep-ca-key --pem --in ~/tmp/cert_blog/instance.yml --out ~/tmp/cert_blog/certs.zip

[2-5] 証明書を解凍する

[root@node1 elasticsearch]# cd ~/tmp/cert_blog
[root@node1 cert_blog]# unzip certs.zip -d ./certs

[2-6] Elasticsearch TLSをセットアップする

[2-6-1] SSL certificatesフォルダーに証明書ファイルをコピーする

[root@node1 ~]# cd $ES_PATH_CONF
[root@node1 elasticsearch]# pwd
/etc/elasticsearch
[root@node1 elasticsearch]# mkdir certs
[root@node1 elasticsearch]# cp ~/tmp/cert_blog/certs/ca/ca* ~/tmp/cert_blog/certs/node1/* certs
[root@node1 elasticsearch]# ll certs
total 12
-rw-r--r--. 1 root elasticsearch 1834 Apr 12 08:47 ca.crt
-rw-r--r--. 1 root elasticsearch 1834 Apr 12 08:47 ca.key
-rw-r--r--. 1 root elasticsearch 1509 Apr 12 08:47 node1.crt
-rw-r--r--. 1 root elasticsearch 1679 Apr 12 08:47 node1.key
[root@node1 elasticsearch]#

[2-6-2] elasticsearch.ymlを設定する

[root@node1 elasticsearch]# vi elasticsearch.yml 
## 以下のコンテンツを追加
node.name: node1
network.host: node1.elastic.test.com
xpack.security.enabled: true
xpack.security.http.ssl.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.http.ssl.key: certs/node1.key
xpack.security.http.ssl.certificate: certs/node1.crt
xpack.security.http.ssl.certificate_authorities: certs/ca.crt
xpack.security.transport.ssl.key: certs/node1.key
xpack.security.transport.ssl.certificate: certs/node1.crt
xpack.security.transport.ssl.certificate_authorities: certs/ca.crt
discovery.seed_hosts: [ "node1.elastic.test.com" ]
cluster.initial_master_nodes: [ "node1" ]

[2-6-3] 起動してクラスターのログを確認する

[root@node1 elasticsearch]# grep '\[node1\] started' /var/log/elasticsearch/elasticsearch.log 
[o.e.n.Node               ] [node1] started

[2-6-4] 内蔵のユーザーパスワードを設定する

[root@node1 elasticsearch]# cd $ES_HOME
[root@node1 elasticsearch]# bin/elasticsearch-setup-passwords auto -u "https://node1.elastic.test.com:9200"
Initiating the setup of passwords for reserved users elastic,apm_system,kibana,logstash_system,beats_system,remote_monitoring_user.
The passwords will be randomly generated and printed to the console.
Please confirm that you would like to continue [y/N] y
Changed password for user apm_system
PASSWORD apm_system = <apm_system_password>
Changed password for user kibana
PASSWORD kibana = <kibana_password>
Changed password for user logstash_system
PASSWORD logstash_system = <logstash_system_password>
Changed password for user beats_system
PASSWORD beats_system = <beats_system_password>
Changed password for user remote_monitoring_user
PASSWORD remote_monitoring_user = <remote_monitoring_user_password>
Changed password for user elastic
PASSWORD elastic = <elastic_password>

[2-6-5] HTTPS経由で_cat/nodes APIにアクセスする

[root@node1 elasticsearch]# curl --cacert ~/tmp/cert_blog/certs/ca/ca.crt -u elastic 'https://node1.elastic.test.com:9200/_cat/nodes?v'
Enter host password for user 'elastic':
ip          heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.0.2           16          95  10    0.76    0.59     0.38 mdi       *      node1
この記事の[2-4] - SSL証明書の生成の手順例は、--keep-ca-keyオプションを使っています。これは、certs.zipファイルにca/ca.crtファイルとca/ca.keyファイルを含めるオプションです。お使いのElasticsearchクラスターにノードを追加する際は、追加ノードの証明書を生成する必要があります。つまり上述の2つの"ca..."ファイル、および以前の生成に使用したパスワードが必要になります。このため[2-4]で生成に使用した"ca..."ファイルとパスワードは、安全な場所に保管してください。

手順3:ノード1でKibana用にTLSを有効化する

[3-1] 環境変数を設定する

Kibanaをダウンロードした場所と方法に応じて変数のパスを調整します:

[root@node1 ~]# KIBANA_HOME=/usr/share/kibana
[root@node1 ~]# KIBANA_PATH_CONFIG=/etc/kibana

[3-2] (Kibanaのインストール完了後、)configとconfig/certsフォルダーを作成し、証明書をコピーする

手順2-4で作成した証明書ファイルをコピーし、kibana/config/certsにペーストします。

[root@node1 kibana]# ls config/certs
total 12
ca.crt
my-kibana.crt
my-kibana.key

[3-3] kibana.ymlを設定する

先行する手順で、内蔵ユーザー用に生成したパスワードを使用します。の部分を、手順2-6-4で定義したパスワードに置き換えます。

[root@node1 kibana]# vi kibana.yml 
server.name: "my-kibana"
server.host: "kibana.local"
server.ssl.enabled: true
server.ssl.certificate: /etc/kibana/config/certs/my-kibana.crt
server.ssl.key: /etc/kibana/config/certs/my-kibana.key
elasticsearch.hosts: ["https://node1.elastic.test.com:9200"]
elasticsearch.username: "kibana"
elasticsearch.password: "<kibana_password>"
elasticsearch.ssl.certificateAuthorities: [ "/etc/kibana/config/certs/ca.crt" ]

[3-4] Kibanaを起動し、ログインを試行する

Webブラウザーでhttps://kibana.local:5601/にアクセスします。elasticユーザー名と、手順2-6-4で定義したパスワードを使用してログインします。この事例ではノード1(node 1)にブラウザをインストールし、kibana.localでKibanaにアクセスできるように設定します。

Kibanaへのログイン

一般的な信頼ある認証機関は、非常に厳格な基準と監査手順を定めることにより、証明書が適切な身元所有者であることの検証を省いて証明書を作成することはできないようにしています。今回はこのブログ記事の目的に鑑み、Kibana用には自己署名証明書を作成(自身のプライベートキーを使用して署名した証明書を生成)します。クライアントは自己署名のKibana証明書を信頼しません。このため、エンタープライズや一般的な認証機関により生成された証明書を使用することで適切な信頼を確立しない限り、Kibanaのログには次のようなメッセージが表示されます(この問題に関するKibana repoのリンクはこちらです)。この問題が、Kibanaでの作業に影響することはありません:

[18:22:31.675] [error][client][connection] Error:4443837888:error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown:../deps/openssl/openssl/ssl/s3_pkt.c:1498:SSL alert number 46

手順4:ノード2でElasticsearch用にTLSを有効化する

[4-1] 環境変数を設定する

[root@node2 ~]# ES_HOME=/usr/share/elasticsearch
[root@node2 ~]# ES_PATH_CONF=/etc/elasticsearch

[4-2] ノード2でTLSをセットアップする

scpコマンドを使用して、ノード1の証明書をノード2にコピーすることができます。接続を安全に保つには、双方のノードに証明書とキーが必要です。本番環境では、各ノードに適切に署名されたキーを使用することが推奨されます。今回はデモンストレーションなので、自動的に生成されたCA証明書と、生成されたCAにより署名されたマルチDNSホスト名証明書を使用します。

[root@node2 ~]# cd $ES_PATH_CONF
[root@node2 elasticsearch]# pwd
/etc/elasticsearch
[root@node2 elasticsearch]# mkdir certs
[root@node2 elasticsearch]# cp ~/tmp/cert_blog/certs/ca/ca.crt ~/tmp/cert_blog/certs/node2/* certs  
[root@node2 elasticsearch]# 
[root@node2 elasticsearch]# ll certs
total 12
-rw-r--r--.1 root elasticsearch 1834 Apr 12 10:55 ca.crt
-rw-r--r--.1 root elasticsearch 1509 Apr 12 10:55 node2.crt
-rw-r--r--.1 root elasticsearch 1675 Apr 12 10:55 node2.key

[4-3] elasticsearch.ymlを設定する

[root@node2 elasticsearch]# vi elasticsearch.yml 
node.name: node2
network.host: node2.elastic.test.com
xpack.security.enabled: true
xpack.security.http.ssl.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.http.ssl.key: certs/node2.key
xpack.security.http.ssl.certificate: certs/node2.crt
xpack.security.http.ssl.certificate_authorities: certs/ca.crt
xpack.security.transport.ssl.key: certs/node2.key
xpack.security.transport.ssl.certificate: certs/node2.crt
xpack.security.transport.ssl.certificate_authorities: certs/ca.crt
discovery.seed_hosts: [ "node1.elastic.test.com" ]

[4-4] 起動してクラスターのログを確認する

[root@node2 elasticsearch]# grep '\[node2\] started' /var/log/elasticsearch/elasticsearch.log 
[o.e.n.Node               ] [node2] started

[4-5] HTTPS経由で_cat/nodes APIにアクセスする

[root@node2 elasticsearch]# curl --cacert ~/tmp/cert_blog/certs/ca/ca.crt -u elastic:<password set previously> 'https://node2.elastic.test.com:9200/_cat/nodes?v'
ip          heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.0.2           25          80   5    0.18    0.14     0.30 mdi       *      node1
192.168.0.3           14          96  44    0.57    0.47     0.25 mdi       -      node2

手順5:ノード1にLogstashユーザーを準備する

[5-1] logstash_write_roleを作成する

ロールを作成する方法は、複数あります。

Kibanaの[Roles(ロール)]UIを使用して作成することができます。 

logstash_write_roleを作成する

または、Kibanaの[Dev Tools(開発ツール)]タブを使用して作成することもできます。

POST /_security/role/logstash_write_role
{
    "cluster": [
      "monitor",
      "manage_index_templates"
    ],
    "indices": [
      {
        "names": [
          "logstash*"
        ],
        "privileges": [
          "write",
          "create_index"
        ],
        "field_security": {
          "grant": [
            "*"
          ]
        }
      }
    ],
    "run_as": [],
    "metadata": {},
    "transient_metadata": {
      "enabled": true
    }
}

次の応答が返ってきます。

{"role":{"created":true}}

このロールをアサインされているユーザーは、ドキュメントの削除を行うことはできません。このロールのユーザーには、logstash、またはインデックスのインデックスドキュメントから開始した場合しかインデックスを作成できないという制約が設けられています。

ILMユーザーへの注記: logstash_writer_roleインデックスライフサイクル管理(ILM)(7.3以降でデフォルトで有効)で使用できるようにするには、次の特権が含まれている必要があります。


"privileges": ["write","create","delete","create_index","manage","manage_ilm"]
        

[5-2] logstash_writerユーザーを作成する(logstash_writerユーザーのパスワードを変更)

ユーザーの作成も、複数の方法で行うことができます。

Kibanaの[Users(ユーザー)]UIで作成することもできます。

logstash_writerユーザーの作成

または、Kibanaの[Dev Tools(開発ツール)]タブを使用して作成することもできます。

POST /_security/user/logstash_writer
{
  "username": "logstash_writer",
  "roles": [
    "logstash_write_role"
  ],
  "full_name": null,
  "email": null,
  "password": "<logstash_system_password>",
  "enabled": true
}

次の応答が返ってきます。

{"user":{"created":true}}

手順6:ノード1でLogstash用にTLSを有効化する

[6-1] フォルダーを作成し、証明書をコピーする

[root@node1 logstash]# ls -l
total 24
ca.crt
logstash.crt
logstash.key

[6-2] Beatsインプットプラグイン用に、ログスタッシュキーをPKCS#8フォーマットに変換する

[root@node1 logstash]# openssl pkcs8 -in config/certs/logstash.key -topk8 -nocrypt -out config/certs/logstash.pkcs8.key

[6-3] logstash.ymlを設定する

logstash_systemユーザー用に自動生成されたパスワードを使用します。手順2-6-4で定義したパスワードを使用してください。

[root@node1 logstash]# vi logstash.yml

編集します:

node.name: logstash.local
path.config: /etc/logstash/conf.d/*.conf
xpack.monitoring.enabled: true
xpack.monitoring.elasticsearch.username: logstash_system
xpack.monitoring.elasticsearch.password: '<logstash_system_password>'
xpack.monitoring.elasticsearch.hosts: [ 'https://node1.elastic.test.com:9200' ]
xpack.monitoring.elasticsearch.ssl.certificate_authority: /etc/logstash/config/certs/ca.crt

[6-4] conf.d/example.confを作成、設定する

Elasticsearchアウトプットで、手順5-2で定義したパスワードを使用します。

[root@node1 logstash]# vi conf.d/example.conf 
input {
  beats {
    port => 5044
    ssl => true
    ssl_key => '/etc/logstash/config/certs/logstash.pkcs8.key'
    ssl_certificate => '/etc/logstash/config/certs/logstash.crt'
  }
}
output {
  elasticsearch {
    hosts => ["https://node1.elastic.test.com:9200","https://node2.elastic.test.com:9200"]
    cacert => '/etc/logstash/config/certs/ca.crt'
    user => 'logstash_writer'
    password => <logstash_writer_password>
  }
}

[6-5] 事例の設定でLogstashを起動し、Logstashログを確認する

次のログメッセージを確認することができます:

[INFO ][logstash.pipeline        ] Pipeline started successfully {:pipeline_id=>".monitoring-logstash", :thread=>"#<Thread:0x640c14d2@/usr/share/logstash/logstash-core/lib/logstash/pipeline.rb:246 run

Kibanaの[Monitoring(監視)]タブにLogstash(ノード情報、パイプライン設定、OS情報、JVM情報、処理情報、パイプラインランタイム情報)が表示されます:

Kibanaの[Monitoring(監視)]タブにLogstashが表示される様子

手順7:ノード1でFilebeatを実行し、TLSをセットアップする

[7-1] configフォルダーを作成し、証明書をコピーする

[root@node1 filebeat]# mkdir config
[root@node1 filebeat]# mkdir config/certs
[root@node1 filebeat]# cp ~/tmp/cert_blog/certs/ca/ca.crt config/certs
[root@node1 filebeat]# ll config/certs/
total 4
-rw-r--r--.1 root root 1834 Apr 20 00:18 ca.crt

[7-2] 新規のfilebeat.ymlを作成する

[root@node1 filebeat]# pwd
/etc/filebeat
[root@node1 filebeat]# mv filebeat.yml filebeat.yml.old

[7-3] 新規の設定ファイルfilebeat.ymlを編集する

filebeat.inputs:
- type: log
  paths:
    - /etc/filebeat/logstash-tutorial-dataset
output.logstash:
  hosts: ["logstash.local:5044"]
  ssl.certificate_authorities:
    - /etc/filebeat/config/certs/ca.crt

手順8:Filebeatを使用してデータを投入する

[8-1] Filebeatへのインプットログデータ(logstash-tutorial.log)を準備する

はじめにインプットログデータをダウンロードします。

[root@node1 filebeat]# pwd
/etc/filebeat
[root@node1 filebeat]# mkdir logstash-tutorial-dataset
[root@node1 filebeat]# cp /root/logstash-tutorial.log logstash-tutorial-dataset/.
[root@node1 filebeat]# ll logstash-tutorial-dataset/
total 24
-rwxr-x---.1 root root 24464 Apr 20 00:29 logstash-tutorial.log

[8-2] Filebeatを起動する

[root@node1 filebeat]# systemctl start filebeat
[root@node1 filebeat]# systemctl enable filebeat
Created symlink from /etc/systemd/system/multi-user.target.wants/filebeat.service to /usr/lib/systemd/system/filebeat.service.

[8-3] ログを確認する

次のログメッセージを確認することができます:

INFO    log/harvester.go:216    Harvester started for file: /etc/filebeat/logstash-tutorial-dataset/logstash-tutorial.log

[8-4] インデックスパターンを作成する

投入するデータにマッチするインデックスパターンを作成します。この手順により、GraphやDiscoverなどのKibanaの機能を使って、データを可視化することができるようになります。

Kibanaでのインデックスパターンの作成

次に、"Time Filter(時間フィルター)"フィールド名を選択します。今回の事例でフィールド名は、@timestampに指定されています:

"Time Filter(時間フィルター)"フィールド名の選択

これで完了です!ここまでの手順でElastic Stackの異なる部分同士の通信を暗号化しました。これでログデータを安全に、保護された状態で投入することができます。

おわりに

セキュリティの設定に関して何か問題が生じた場合、Elasticではまずドキュメント『セキュリティトラブルシューティングガイド』をご覧いただくことを推奨しています。多くの一般的な問題に役立つドキュメントとなっています。それでも疑問が残る場合、Elasticフォーラムを参考にされてみてください。直接Elasticサポートチームにお問い合わせを希望される場合は、Elasticサブスクリプションをご利用ください。Elasticのエキスパートチームによるサポートが提供されます。安全なElastic Stackを、お楽しみください!