ELK 스택/Filebeat+ELK

[ELK] 보안처리를 위한 ELK 스택 구축 ( Docker-compose)

new_challenge 2020. 7. 7. 23:46
반응형

이번 포스팅은 엘라스틱과 키바나에 보안접속을 할 수 있도록

추가하여, 도커 컴포즈를 사용하여 구축하는 내용에 관한 포스팅

 

 

 

 

 

아래 내용은 Elasticsearch with docker-compose 내용을 기반으로 작성되었습니다. (엘라스틱 공식문서)

www.elastic.co/guide/en/elastic-stack-get-started/7.8/get-started-docker.html#get-started-docker-tls

 

Running the Elastic Stack on Docker | Getting Started [7.8] | Elastic

At this point, Kibana cannot connect to the Elasticsearch cluster. You must generate a password for the built-in kibana_system user, update the ELASTICSEARCH_PASSWORD in the compose file, and restart to enable Kibana to communicate with the secured cluster

www.elastic.co

 

Run in Docker with TLS enabled

Gold 혹은 Platinum licesnse를 가지고 있다면 보안을 가능하게 처리할 때, TLS는 엘라스틱의 transport layer를 위해 설정이 되어야 한다. 반면에 trial license는 TLS 세팅 없이 사용이 가능하다. 

 

docker-compose 및 설정 파일 생성

아래 설정 파일들은 elastic/stack-docs 깃허브 레파지토리에서 사용이 가능하다.

 

github.com/elastic/stack-docs/tree/master/docs/en/getting-started/docker

 

elastic/stack-docs

Elastic Stack Documentation. Contribute to elastic/stack-docs development by creating an account on GitHub.

github.com

> instances.yml : 인증서를 생성해야하는 인스턴스를 식별하기 위한 파일

> .env : 엘라스틱 버전과 인증서가 생성될 위치를 지정한 환경 변수가 세팅되어있는 파일

> create-certs.yml : 도커 컴포즈 파일로써, 엘라스틱과 키비나를 위한 인증서를 생성할 컨테이너를 생성

> elastic-docker-tls.yml : 도커 컴포즈 파일로써 TLS 가 설정된 키바나 인스턴스와 3개의 엘라스틱 클러스터의 생성을 정의

 

 

instance.yml

instances:
  - name: es01
    dns:
      - es01
      - localhost
    ip:
      - 127.0.0.1

  - name: es02
    dns:
      - es02
      - localhost
    ip:
      - 127.0.0.1

  - name: es03
    dns:
      - es03
      - localhost
    ip:
      - 127.0.0.1

  - name: 'kib01'
    dns:
      - kib01
      - localhost

 

.env

COMPOSE_PROJECT_NAME=es
CERTS_DIR=/usr/share/elasticsearch/config/certificates
VERSION=7.8.0

 

create-certs.yml

version: '2.2'

services:
  create_certs:
    image: docker.elastic.co/elasticsearch/elasticsearch:${VERSION}
    container_name: create_certs
    command: >
      bash -c '
        yum install -y -q -e 0 unzip;
        if [[ ! -f /certs/bundle.zip ]]; then
          bin/elasticsearch-certutil cert --silent --pem --in config/certificates/instances.yml -out /certs/bundle.zip;
          unzip /certs/bundle.zip -d /certs;
        fi;
        chown -R 1000:0 /certs
      '
    working_dir: /usr/share/elasticsearch
    volumes:
      - certs:/certs
      - .:/usr/share/elasticsearch/config/certificates
    networks:
      - elastic

volumes:
  certs:
    driver: local

networks:
  elastic:
    driver: bridge

 

elastic-docker-tls.yml

version: '2.2'

services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:${VERSION}
    container_name: es01
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es02,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - xpack.license.self_generated.type=trial 
      - xpack.security.enabled=true
      - xpack.security.http.ssl.enabled=true 
      - xpack.security.http.ssl.key=$CERTS_DIR/es01/es01.key
      - xpack.security.http.ssl.certificate_authorities=$CERTS_DIR/ca/ca.crt
      - xpack.security.http.ssl.certificate=$CERTS_DIR/es01/es01.crt
      - xpack.security.transport.ssl.enabled=true 
      - xpack.security.transport.ssl.verification_mode=certificate 
      - xpack.security.transport.ssl.certificate_authorities=$CERTS_DIR/ca/ca.crt
      - xpack.security.transport.ssl.certificate=$CERTS_DIR/es01/es01.crt
      - xpack.security.transport.ssl.key=$CERTS_DIR/es01/es01.key
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data01:/usr/share/elasticsearch/data
      - certs:$CERTS_DIR
    ports:
      - 9200:9200
    networks:
      - elastic

    healthcheck:
      test: curl --cacert $CERTS_DIR/ca/ca.crt -s https://localhost:9200 >/dev/null; if [[ $$? == 52 ]]; then echo 0; else echo 1; fi
      interval: 30s
      timeout: 10s
      retries: 5

  es02:
    image: docker.elastic.co/elasticsearch/elasticsearch:${VERSION}
    container_name: es02
    environment:
      - node.name=es02
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - xpack.license.self_generated.type=trial
      - xpack.security.enabled=true
      - xpack.security.http.ssl.enabled=true
      - xpack.security.http.ssl.key=$CERTS_DIR/es02/es02.key
      - xpack.security.http.ssl.certificate_authorities=$CERTS_DIR/ca/ca.crt
      - xpack.security.http.ssl.certificate=$CERTS_DIR/es02/es02.crt
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.security.transport.ssl.certificate_authorities=$CERTS_DIR/ca/ca.crt
      - xpack.security.transport.ssl.certificate=$CERTS_DIR/es02/es02.crt
      - xpack.security.transport.ssl.key=$CERTS_DIR/es02/es02.key
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data02:/usr/share/elasticsearch/data
      - certs:$CERTS_DIR
    networks:
      - elastic

  es03:
    image: docker.elastic.co/elasticsearch/elasticsearch:${VERSION}
    container_name: es03
    environment:
      - node.name=es03
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es02
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - xpack.license.self_generated.type=trial
      - xpack.security.enabled=true
      - xpack.security.http.ssl.enabled=true
      - xpack.security.http.ssl.key=$CERTS_DIR/es03/es03.key
      - xpack.security.http.ssl.certificate_authorities=$CERTS_DIR/ca/ca.crt
      - xpack.security.http.ssl.certificate=$CERTS_DIR/es03/es03.crt
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.security.transport.ssl.certificate_authorities=$CERTS_DIR/ca/ca.crt
      - xpack.security.transport.ssl.certificate=$CERTS_DIR/es03/es03.crt
      - xpack.security.transport.ssl.key=$CERTS_DIR/es03/es03.key
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data03:/usr/share/elasticsearch/data
      - certs:$CERTS_DIR
    networks:
      - elastic
  kib01:
    image: docker.elastic.co/kibana/kibana:${VERSION}
    container_name: kib01
    depends_on: {"es01": {"condition": "service_healthy"}}
    ports:
      - 5601:5601
    environment:
      SERVERNAME: localhost
      ELASTICSEARCH_URL: https://es01:9200
      ELASTICSEARCH_HOSTS: https://es01:9200
      ELASTICSEARCH_USERNAME: kibana_system
      ELASTICSEARCH_PASSWORD: CHANGEME
      ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES: $CERTS_DIR/ca/ca.crt
      SERVER_SSL_ENABLED: "true"
      SERVER_SSL_KEY: $CERTS_DIR/kib01/kib01.key
      SERVER_SSL_CERTIFICATE: $CERTS_DIR/kib01/kib01.crt
    volumes:
      - certs:$CERTS_DIR
    networks:
      - elastic
volumes:
  data01:
    driver: local
  data02:
    driver: local
  data03:
    driver: local
  certs:
    driver: local

networks:
  elastic:
    driver: bridge

> TLS (Transport Layer Security)를 지원하기 위한 trial 라이센스를 생성하고 정의한다.

> 클라이언트 통신을 암호화하기 위해 전송 계층 보안을 사용

> 노드 간 통신을 암호화 하기 위해 전송 계층 보안을 사용

> 호스트 이름 확인을 요구하지 않고 자체 서명된 인증서 사용을 허용

 

도커 컴포즈 실행 과정

📌 도커 엔진에게 적어도 4 Gib의 메모리가 할당된다.

 

엘라스틱을 위한 인증서 생성

$ docker-compose -f create-certs.yml run --rm create_certs

실행 시 출력 화면

 

클러스터 docker-compose up

$ docker-compose -f elastic-docker-tls.yml up -d

> 3개의 노드를 가진 엘라스틱 클러스터에 대해 docker-compose up으로 띄운다

> 이 시점에서, 키바나는 엘라스틱 클러스터에 연결할 수 없다. 내장 kibana_system 유저를 위한 비밀번호를 생성해야 한다. 그리고 compose file의 ELASTICSEARCH_PASSWORD를 업데이트한다. 그 후에 보안된 클러스터와 커뮤니케이션할 수 있도록 키바나를 재시작 

 

 

> docker-compose up 후에 도커 컴포즈의 로그를 확인하고 싶다면 아래와 같이 입력

docker-compose logs

# 특정 컨테이너의 로그만 보고 싶다면 컨테이너 이름을 지정
docker-compose logs [컨테이너이름]

 

엘라스틱 패스워드 세팅

$ docker exec es01 /bin/bash -c "bin/elasticsearch-setup-passwords auto --batch --url https://es01:9200"

> elasticsearch-setup-passwordssms 내장 유저(kibana_system을 포함한)들을 위한 비밀번호를 생성해주는 도구이다

> 위 명령어를 통해 출력된 비밀번호를 따로 저장해놔야 한다.

> 그리고 키바나가 엘라스틱과 연결하기 위해 compose 파일에서 kibana_system유저에 대한 비밀번호를 설정한다

그리고 elasic 슈퍼바이저 유저가 키바나에 접속하고, 엘라스틱에 요청을 전송하기 위해 elastic에 대한 비밀번호가 필요한다.

 

아래와 같이 유저 별 비밀번호가 자동을 생성된다.

 

 

키바나 컨테이너에서 비밀번호 변경

kib01:
    image: docker.elastic.co/kibana/kibana:${VERSION}
    container_name: kib01
    depends_on: {"es01": {"condition": "service_healthy"}}
    ports:
      - 5601:5601
    environment:
      SERVERNAME: localhost
      ELASTICSEARCH_URL: https://es01:9200
      ELASTICSEARCH_HOSTS: https://es01:9200
      ELASTICSEARCH_USERNAME: kibana_system
      ELASTICSEARCH_PASSWORD: [새로 생성된 비밀번호 입력]
      ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES: $CERTS_DIR/ca/ca.crt
      SERVER_SSL_ENABLED: "true"
      SERVER_SSL_KEY: $CERTS_DIR/kib01/kib01.key
      SERVER_SSL_CERTIFICATE: $CERTS_DIR/kib01/kib01.crt
    volumes:
      - certs:$CERTS_DIR
    networks:
      - elastic

> kibana_system에 대해 생성된 비밀번호를 ELASTICSEARCH_PASSWORD에 입력한다.

 

실행 중인 도커 컴포즈 종료

$ docker-compose stop

실행 화면

 

도커 컴포즈 재시작

docker-compose -f elastic-docker-tls.yml up -d

> 여기서 -f는 yml 파일을 지정할 때 사용

> -d는 백그라운도 실행을 의미함

실행 결과 화면

> 기존 컨테이너는 그대로 시작하고, 변경된 kib01 컨테이너는 재생성된다. 

 

키바나 접속

https://localhost:5601

> 키바나와 유저 브라우저 사이의 커뮤니케이션을 위해 SSL이 활성화되어 있기 때문에, 키바나는 HTTPS 프로토콜을 통해 접속해야 한다.

 

> 보안 설정이 잘 되었다면 아래와 같은 화면이 보인다.

기본 유저인 elastic과 그에 해당하는 비밀번호 입력

 

> 현재는 trial license 이므로 basic license로 변경해준다.

Elasticsearch > License Management "Trial license"

 

Elasticsearch > License Management "Basic license"

 

클러스터 모니터링 설정

클러스터 모니터링 설정을 위해 Cluster 탭으로 이동 ( 아래와 같은 화면 출력 )

 

 

 

> 위 화면이 나오면 Turn on mornitoring 클릭

 

> 위 세팅까지 마치면, 아래와 같이 클러스터 모니터링 화면을 볼 수 있다.

 

파일로부터 세팅 값 로딩하기

컴포즈 파일에 엘라스틱과 키바나의 세팅을 지정하는 것은 시작하기에는 편리하다. 그러나 한번 경험해본 뒤에는 파일에서 세팅값을 로딩하는 것을 선호한다.

 

예를 들어, es01.yml을 es01 엘라스틱 노드를 위한 설정 파일로 생성하기 위해서는, 볼륨 부분에서 바인드 마운트를 생성하면 된다.

volumes:
  - data01: /usr/share/elasticsearch/data
  - certs:$CERTS_DIR
  - ./es01.yml:/usr/share/elasticsearch/config/elasticsearch.yml

 

비슷하게 파일을 사용하여 키바나 세팅을 로딩하고 싶을 때는, /usr/share/kibana/config/kibana.yml를 덮어쓰기 한다.

volumes:
  - certs:$CERTS_DIR
  - ./kibana.yml:/usr/share/kibana/config/kibana.yml

 

보안이 설정된 엘라스틱 클러스터에 인덱스 생성하기

키바나 Dev Tools에서 직접 생성

반응형