1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Elasticsearch & Kibana】最低限のセキュリティを踏まえたElasticsearch with Docker

Posted at

こんにちは。

付録に記載したセキュリティ要件を満たしつつ、DockerでElasticsearchとKibanaを起動することを目的としたページです。

記載内容に間違いがあったり、改善点があったりしたら是非ご指摘をいただきたいです。

よろしくお願いいたします。

前提

Elasticsearchの設定ファイル elasticsearch.yml

Kibanaの設定ファイル kibana.yml

上記が入っている場所を設定ディレクトリという

Elasticsearch側 設定ディレクトリe (e.g. $ES_PATH_CONF)

Kibana側 設定ディレクトリ (e.g. $KBN_PATH_CONF)

ブラウザからElasticsearchにログインするユーザー: elastic

→これはsuperuser

KibanaからElasticsearchにログインするユーザー: kibana_system

Elasticsearchはシングルノードで作成する

⚠️マルチノードの場合本番環境では推奨されていないので注意

transport層のセキュリティも気にしないといけない(ノード間通信)

構成

今回は前段として、⓪証明書系の生成(ここは本番では使わないはず?)を行ったのち

① Elasticsearchの起動

①’ kibana_systemのパスワード変更

② Kibanaの起動

を行います。

パスワードを変更してKibanaを再起動する必要があるようなので、後から起動してしまう作戦です。

ではみていきます。

ネットワーク作成

docker network create elastic

証明書作成

docker run --rm --user=root --network=elastic -v certs:$ES_PATH_CONF/certs docker.elastic.co/elasticsearch/elasticsearch:$VERSION \
  /bin/bash -c "elasticsearch-certutil ca --silent --pem";

docker runを使ってコンテナ内でelasticsearch-certutil を実行する形です。

証明書はVolumeで管理してるので、docker runでやってしまいます。

composeファイル

services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:${VERSION}
    container_name: es01
    environment:
      - node.name=es01
      - discovery.type=single-node
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms${ES_HEAP_MEMORY_SIZE_MIN} -Xmx${ES_HEAP_MEMORY_SIZE_MAX}"
      - xpack.security.enabled=true
      - xpack.security.http.ssl.enabled=true
      - xpack.security.http.ssl.key=${ES_PATH_CONF}/certs/es01/es01.key
      - xpack.security.http.ssl.certificate=${ES_PATH_CONF}/certs/es01/es01.crt
      - xpack.security.http.ssl.certificate_authorities=${ES_PATH_CONF}/certs/ca/ca.crt
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data01:/usr/share/elasticsearch/data
      - ${HOME}/certs:${ES_PATH_CONF}/certs:ro
    ports:
      - 9200:9200
    networks:
      - elastic
    healthcheck:
      test: curl --cacert ${ES_PATH_CONF}/certs/ca/ca.crt -s https://${ES_HOST}:9200 >/dev/null || exit 1
      interval: 30s
      timeout: 10s
      retries: 5

  kib01:
    image: docker.elastic.co/kibana/kibana:${VERSION}
    container_name: kib01
    depends_on:
      - es01
    environment:
      - ELASTICSEARCH_USERNAME=kibana_system
      - ELASTICSEARCH_PASSWORD=${ES_PASSWORD}
      - ELASTICSEARCH_HOSTS=https://es01:9200
      - ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=${KIB_PATH_CONF}/certs/ca/ca.crt
      - ELASTICSEARCH_SSL_VERIFICATIONMODE=certificate
      - csp.strict=true
      - SERVER_HOST=0.0.0.0
      - SERVER_SSL_ENABLED=true
      - SERVER_SSL_CERTIFICATE=${KIB_PATH_CONF}/certs/es01/es01.crt
      - SERVER_SSL_KEY=${KIB_PATH_CONF}/certs/es01/es01.key
      - server.securityResponseHeaders.disableEmbedding=true
      - server.securityResponseHeaders.strictTransportSecurity="max-age=31536000"

    volumes:
      - kibanadata:/usr/share/kibana/data
      - ${HOME}/certs:${KIB_PATH_CONF}/certs:ro
    ports:
      - 5601:5601
    networks:
      - elastic
    healthcheck:
      test: curl -s https://${ES_HOST}:5601 >/dev/null || exit 1
      interval: 30s
      timeout: 10s
      retries: 5

volumes:
  certs:
    driver: local
  data01:
    driver: local
  kibanadata:
    driver: local

networks:
  elastic:
    driver: bridge

KibanaのEnvironmentについては以下でも書いた通り大文字で設定する必要があります。

設定したcomposeファイルを使って次のような順序でサービスを起動します。

docker-compose up es01 -d
bash set_password.sh # 下で触れます
docker-compose up kib01 -d

パスワード生成

KibanaがElasticsearchにアクセスするためのパスワードを生成します。

前提でも書いたように、アクセス用のアカウントとしてkibana_system が用意されています。

パスワードのリセットにはElasticsearchのコンテナが必要で、特に再起動の予定もないので先に起動してます。

echo "Start Creating Containers...";

echo "Waiting for Elasticsearch availability";
until curl --cacert certs/ca/ca.crt -s https://$ES_HOST:9200 >/dev/null; do
sleep 5;
# certs/ca/ca.crtはローカルにある証明書
# なんらかの返答があればサービスの起動が確認できたことになるのでパスワードのリセット処理に入る

echo "Waiting for Elasticsearch...";
done;

# パスワードリセットして出力を保存
docker exec -it es01 elasticsearch-reset-password -u kibana_system --url https://$ES_HOST:9200 --batch  > pwd_output.txt

# 出力からパスワードを抽出して.envに追加
# ここはあんまいけてない
NEW_PWD=$(grep 'New value:' pwd_output.txt | sed 's/New value: //'| tr -d '\n\r')
if [ ! -z "$NEW_PWD" ]; then
  echo -e "ES_PASSWORD=\"$NEW_PWD\"" >> .env
  echo "パスワードを.envに追加しました"
fi

echo "Finish Creating Containers...";

これでKibanaがElasticsearchに接続できるようになったので、満を持してKibanaのサービスを起動します。

しばらく待ったら、
https://localhost:5601
などでアクセスできるはずです。

※localhostの箇所は設定したホストによって変わります。

ログインするときはelastic ユーザーを使うと良いです。

パスワードのリセットはローカルでkibana_system を参考にしてやってください。

以上です!

感想

とりあえず動かすことはできました。

現状の課題としては、内部で作成された鍵を用いている点とそれらをvolumeで共有していることです。

外部で生成した鍵をそれぞれで保存する形にすれば問題ないように思います。

問題があればぜひ教えてください。

付録)最低限のセキュリティ ざっくりまとめ

これらドキュメントをまとめただけ

xpack.security.enabled: trueelasticsearch.yml に設定

この設定によってユーザー名とパスワードによるbasic認証が通る

パスワードのリセット

./bin/elasticsearch-reset-password -u kibana_system

このコマンドでユーザーkibana_systemのパスワードをリセットできる 

elastic についても同コマンドでパスワードをリセットできる 

KibanaからElasticsearchへのパスワードによる接続

KibanaからElasticsearchに接続するうえで必要な設定

elasticsearch.username: "kibana_system"kibana.yml に設定

Kibana内のセキュアな情報を保護するための設定

キーストアの作成

./bin/kibana-keystore create

Elasticsearchのパスワードをキーストアに追加

./bin/kibana-keystore add elasticsearch.password

Kibanaをリスタートする

For HTTPs ElasticSearch & Client 編

動作を止める

以下コマンドを実行し、CAのパス等を指定

./bin/elasticsearch-certutil http

 

生成されるelasticsearch-ssl-http.zip を解凍する

http.p12 を設定ディレクトリeに移動

xpack.security.http.ssl.enabled: trueelasticsearch.yml に設定

xpack.security.http.ssl.keystore.path: http.p12elasticsearch.yml に設定

キーストアに追加

./bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password

For HTTPs Kibana & ElasticSearch 編

elasticsearch-ca.pem を設定ディレクトリkに移動

elasticsearch.ssl.certificateAuthorities: $KBN_PATH_CONF/elasticsearch-ca.pemkibana.yml に設定
elasticsearch.hosts: https://<your_elasticsearch_host>:9200kibana.yml に設定

Kibanaをリスタート

For HTTPs Kibana & Client 編

サーバーの証明書と秘密鍵を生成

./bin/elasticsearch-certutil csr -name kibana-server -dns example.com,www.example.com

生成されるcsr-bundle.zipを解凍

server.ssl.certificate: $KBN_PATH_CONF/kibana-server.crtkibana.yml に設定
server.ssl.key: $KBN_PATH_CONF/kibana-server.keykibana.yml に設定
server.ssl.enabled: truekibana.yml に設定

仲間を募集中!

株式会社ホープでは、福岡で働くエンジニアを募集中です。
ぜひ、求人を見てみてください!
▼ Wantedly求人
https://www.wantedly.com/projects/1684027
▼ コーポレートサイト
https://www.zaigenkakuho.com/recruit/
「自治体を通じて人々に新たな価値を提供し、会社及び従業員の成長を追求する」
この理念の実現に向けて、今後も自治体の課題解決に取り組んでいきます。
ご応募お待ちしております!

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?