Monitoringでログ表示（認証＋TLS有効版）

# はじめに

日本が令和を迎えた頃、ElasticではBASICサブスクリプションでSecurityが有効になっていました！
（おまけに、更新が止まったと思われていた6系にもバックポートされて、[6.8](https://github.com/elastic/kibana/tree/6.8)が！）

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

## 準備

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

https://www.elastic.co/guide/en/elasticsearch/reference/master/configuring-tls-docker.html

## 設定変更する

### `docker-compose.yml`の修正

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

```yaml: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`も作っておきます。

```properties:.env
CERTS_DIR=/usr/share/elasticsearch/config/certs
```

### `filebeat.yml`の修正

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

```yaml: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
```

## 起動する

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

```sh
$ 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を見ると・・・

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

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

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

![Screenshot_2019-05-08 Kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221612/483b1b82-8865-80a6-8e89-0c9f9207c552.png)

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は、以下のような感じで登録します。

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

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

![Screenshot_2019-05-08 Kibana(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221612/7c03f4b0-2a66-ab99-6ee8-45f4aba4a692.png)

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

# おわりに

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