Monitoringでログ表示(認証+TLS有効版)


はじめに

日本が令和を迎えた頃、ElasticではBASICサブスクリプションでSecurityが有効になっていました!
(おまけに、更新が止まったと思われていた6系にもバックポートされて、6.8が!)

今回は、以前 Monitoringでログ表示 の中で作ったdocker-compose.ymlでもセキュリティを有効にしてみます。
(2019.05.20 追記) セキュリティを有効にすると、TLSも有効にしないと怒られるようになりました。

準備

以下を見ながら、コンテナでTLSが使えるようにします。

設定変更する

docker-compose.ymlの修正

elasticsearchでセキュリティを有効にして、kibanaでユーザ名・パスワードを指定するようにします。
パスワードはELASTIC_PASSWORDで指定していますが、あくまでもテストということで適当なのを指定しています(実際に使うときは、ちゃんと設定しないとですが)。

docker-compose.yml
version: '2'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.0.0-SNAPSHOT
    container_name: elasticsearch4
    environment:
      - cluster.name=docker-cluster
      - node.name=node-1
      - cluster.initial_master_nodes=node-1
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - path.repo=/usr/share/elasticsearch/snapshots
      - xpack.security.enabled=true
      - ELASTIC_PASSWORD=elastic
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.security.transport.ssl.key=$CERTS_DIR/elasticsearch4/elasticsearch4.key
      - xpack.security.transport.ssl.certificate=$CERTS_DIR/elasticsearch4/elasticsearch4.crt
      - xpack.security.transport.ssl.certificate_authorities=$CERTS_DIR/ca/ca.crt    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata1:/usr/share/elasticsearch/data
      - ./certs:$CERTS_DIR
    ports:
      - 9204:9200
    networks:
      - esnet
  kibana:
    image: docker.elastic.co/kibana/kibana:8.0.0-SNAPSHOT
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch4:9200
      - ELASTICSEARCH_USERNAME=elastic
      - ELASTICSEARCH_PASSWORD=elastic
    container_name: kibana4
    ports:
      - 5605:5601
    networks:
      - esnet
  beats:
    image: docker.elastic.co/beats/filebeat:8.0.0-SNAPSHOT
    container_name: beats4
    user: root
    environment:
      - ELASTICSEARCH_CONTAINER_NAME=elasticsearch4
      - ELASTICSEARCH_HOSTS=http://elasticsearch4:9200
      - KIBANA_HOST=http://kibana4:5601
    volumes:
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./filebeat.yml:/usr/share/filebeat/filebeat.yml
    networks:
      - esnet

volumes:
  esdata1:
    driver: local

networks:
  esnet:

docker-compose.ymlと同じディレクトリに、.envも作っておきます。

.env
CERTS_DIR=/usr/share/elasticsearch/config/certs

filebeat.ymlの修正

filebeat.ymlでも、ユーザ名・パスワードを指定します。

filebeat.yml
filebeat.autodiscover:
  providers:
    - type: docker
      labels.dedot: true
      templates:
        - condition:
            contains:
              docker.container.name: ${ELASTICSEARCH_CONTAINER_NAME:elasticsearch}
          config:
             - module: elasticsearch
               server:
                 enabled: true
                 input:
                   type: docker
                   containers.ids:
                     - "${data.docker.container.id}"
setup.kibana:
  host: "${KIBANA_HOST:kibana:5601}"
  username: elastic
  password: elastic
output.elasticsearch:
  hosts: '${ELASTICSEARCH_HOSTS:elasticsearch:9200}'
  username: elastic
  password: elastic

起動する

以下のコマンドでコンテナを起動します。

$ docker-compose up -d

問題が無ければ、ログの収集が行われてMonitoringでログが表示できるはずです。
ですが、Monitoringを表示すると、次のエラーメッセージが表示されてしまいます。

[illegal_argument_exception] Fielddata is disabled on text fields by default. Set fielddata=true on [event.dataset] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.: Check the Elasticsearch Monitoring cluster network connection or the load level of the nodes.

何が起きているのか?

Set fielddata=true on [event.dataset] 

と表示されています。Mappingを見ると・・・

{
   "mapping": {
     "properties": {
       "@timestamp": {
         "type": "date"
       },
(snip)
       "event": {
         "properties": {
           "created": {
             "type": "date"
           },
           "dataset": {
             "type": "text",
             "fields": {
               "keyword": {
                 "type": "keyword",
                 "ignore_above": 256
               }
             }
           },
(snip)
}

event.datasettext型になっちゃってますね・・・
templateが入るはずなので、ちゃんとevent.datasetkeyword型になるはずなのに。

Filebeatの処理をちゃんとみたわけではありませんが、どうもtemplateが登録される前にRollover用Index(filebeat-8.0.0-{now/d}-000001)が登録されちゃってるようです。

ILMも有効になってないし。
やってることは同じはずなのに、なんで前はうまくいったんだろう???
templateが残ってたのかなぁ・・・
-> バグだったらしい。今(2019.05.15現在は修正されてます)

おまけにセキュリティに関係ないし orz

対処する

以下の手順で起動して見ます。

  1. docker-compose up -d elasticsearch kibana
  2. docker-compose run beats setup -e --modules elasticsearch
  3. DELETE filebeat-*
  4. Rollover用Indexを登録
  5. docker-compose up -d beats

Rollover用Indexは、以下のような感じで登録します。

PUT %3Cfilebeat-8.0.0-%7Bnow%2Fd%7D-000001%3E
{
   "aliases": {
     "filebeat-8.0.0": {}
   }
}

で、改めてIndexを確認すると・・・

ちゃんとできたようですね。

おわりに

セキュリティ自体は何の問題もなく使えました。
というか、BASICでセキュリティが有効になるのは良いですね。早く正式リリースされて欲しいです。