ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ELK Stack의 보안
    Elixian의 Referenece 2020. 6. 17. 17:51

    ELK Stack  보안 (feat. X-PACK)

     

    ELK Stack

     

    Elastic Stack 6.8 7.1부터 TLS 암호화된 통신 기능이 기본 배포 내에서 무료로 제공됩니다. 

    실제로 ELK Production에 적용하면서 얻은 Lesson Learned를 공유합니다. 실제로 개발 모드에서는 아래와 같이 복잡하게 할 필요가 없습니다. 그러나 Production 으로 올라게게되면 보안 / Heap 셋팅 / Memlock 셋팅 등 자잘하게 손 대야 할 부분이 많이 생깁니다. 그 중, 보안을 적용하여 ELK Stack을 구축하는 부분을 간단하게 정리해 봅니다. 자세한 내용은 Elastic Stack 보안 설명서를 읽어보실 것을 권장합니다.

     

    ELK 보안 스펙은 별도로 설정하는 것이 아니라 yml 파일에 host 주소에 loop-back(127.0.0.1)  아닌 값이 들어가면 자동으로 X-PACK Bootstrap 시작합니다.

     

    또한 http.port transport.port 경우, 작성하지 않으면 default 9200/9300 잡을 것으로 예상했으나 그렇지 않았습니다. 해당 값을 넣지 않으면 아마도 elasticsearch 내부에서 http 9200~9299, transport 9300~9399 사이에 값을 사용하는  같습니다.

     

    인증서는 공인된 기관의 인정서가 있는 경우, 해당 인증서를 사용하면 됩니다. 그러나 ELK 경우, 거의 내부망 (Nginx / Apache / API Server 사용하여 통신하고 ELK 직접 인터넷 망에 붙이지는 않는다.)  위치하므로 별도의 도메인을 붙여야  필요가 없습니다.

     

    Elastic 아래와 같은 utility  제공합니다. 

    bin/elasticsearch-certutil  사용하여 훨씬 수월하게 만들  있습니다.

     

     bin/elasticsearch-certutil cert -out config/elastic-certificates.p12 -pass "" 

     

    위와 같이 p12 파일을 패스워드 없이 생성할  있습니다.

    가장 간단한 방법으로 인증서를 생성할  있는 방법입니다. 다만logstash / kibana 적용하려면 crt / key 파일을 별도로 만드는 것이 좋습니다.

     

    , ELK Stack 구축하려면 위의 방법 보다는 CA 파일과 인증서 / 키를 별도로 만드는 것이 좋습니다.

     

     bin/elasticsearch-certutil cert ca --pem --in instance.yml –out certs.zip

     

    Instances.yml 다음과 같이 구성합니다.

     

    instances:

      - name: "hb-es-node1"

         ip:

           -  "10.10.15.201"

      - name: 'hb-es-node2'

         ip:

           - "10.10.15.202"

      - name: "hb-es-node3"

         ip:

           - "10.10.15.203"

      - name: 'hb-kibana'

         ip:

           - "110.10.15.190"

      - name: 'logstash'

         ip:

           - "10.10.15.192"

     

       

    /etc/hosts 파일을 사용할 경우, ip dns 변경할  있으며 ip dns   사용해도 좋습니다.

     

    # yml 파일에 인스턴스 정보 추가

    instances: 

    - name: 'node1' 

      dns: [ 'node1.elastic.elixian.co.kr' ] 

    - name: "node2" 

      dns: [ 'node2.elastic.elixian.co.kr']

    - name: kibana' 

      dns: [ 'kibana.local' ] 

    - name: 'logstash' 

      dns: [ 'logstash.local' ]

     

    이렇게 인증 관련 파일을 생성하면  계정  비밀 번호를 생성해야 합니다.

    비밀 번호는 elasticsearch에서 제공하는 별도의 util 사용합니다.

     

    bin/elasticsearch-setup-passwords auto

     

    bin/elasticsearch-setup-passwords interactive

     

     

    Auto 경우, elasticsearch 자동으로 임의의 password 생성해 주고, interactive 경우, 사용자가 입력할  있습니다.

     

    Please confirm that you would like to continue [y/N]y

     

    Changed password for user apm_system

    PASSWORD apm_system = KwGA9NiowJiwle9PQHqo

     

    Changed password for user kibana

    PASSWORD kibana = cZAdtghFDIfdgU03tDzP

     

    Changed password for user logstash_system

    PASSWORD logstash_system = tKoKvBacSFPjEKdShmfY

     

    Changed password for user beats_system

    PASSWORD beats_system = 52tCYGE846D0BtvtGsXU

     

    Changed password for user remote_monitoring_user

    PASSWORD remote_monitoring_user = 4L3coyUwc8DRTB7y84ze

     

    Changed password for user elastic

    PASSWORD elastic = z2HGfIqeAoz1SwTRmXuV

     

    어디  적어줘야 합니다. 

     

    중요한 것은 비밀 번호는 항상 Master Node에서 하는 것이 좋습니다.

    Elasticsearch clustering으로 실행했을 , Master  군데서 비밀 번호를 만들면 다른 곳에서는 하지 않아도 됩니다.

    (실제로 node2 마스터였는데 node1 비밀 번호를 설정하면 인증 실패가 나올겁니다. – 테스트하지 않아서 확실하지 않습니다.

    인증 실패는 docker-compose down 하여 password 가 초기화 된 것이 원인 같다.)

     

     

    다음은 elasticsearch.yml 파일의 구성입니다.

    3개의 노드를 실행하고 각각의 노드는 Master / Data 속성이 true 입니다.

    많은 수의 노드를 구성할 것이 아니라면 별도로 Master 노드와 Data 노드를 분리하는 것은 낭비일  있습니다. 

    그리고Clustering 구축하여 Brain Split  피하기 위해서는 최소한 3개의 노드가 있어야 합니다.

     

    # cluster setting

    cluster.name: "hb-es-cluster"

    cluster.initial_master_nodes: ["hb-es-node1", "hb-es-node2", "hb-es-node3"]

     

    # node name

    node.name: "hb-es-node1"

     

    # host network setting

    network.host: 10.10.15.201

    http.port: 9200

    transport.port: 9300

     

    # node attribute setting

    node.master: true

    node.data: true

     

    # detail the private IPs of your nodes:

    discovery.seed_hosts: ["10.10.15.201", "10.10.15.202", "10.10.15.203"]

     

    # lock memory heap

    bootstrap.memory_lock: true

     

    # xpack setting

    xpack.security.enabled: true

     

    #xpack.security.transport.ssl.verification_mode: certificate

    #xpack.security.transport.ssl.keystore.path: elastic-certificates.p12

    #xpack.security.transport.ssl.truststore.path: elastic-certificates.p12

     

    xpack.security.transport.ssl.enabled: true

    xpack.security.transport.ssl.key: /usr/share/elasticsearch/config/cert/hb-es-node1.key

    xpack.security.transport.ssl.certificate: /usr/share/elasticsearch/config/cert/hb-es-node1.crt

    xpack.security.transport.ssl.certificate_authorities: /usr/share/elasticsearch/config/cert/ca.crt

     

    #xpack.security.http.ssl.verification_mode: certificate

    #xpack.security.http.ssl.keystore.path: elastic-certificates.p12

    #xpack.security.http.ssl.truststore.path: elastic-certificates.p12

     

    xpack.security.http.ssl.enabled: true

    xpack.security.http.ssl.key: /usr/share/elasticsearch/config/cert/hb-es-node1.key

    xpack.security.http.ssl.certificate: /usr/share/elasticsearch/config/cert/hb-es-node1.crt

    xpack.security.http.ssl.certificate_authorities: /usr/share/elasticsearch/config/cert/ca.crt

     

    위의 YAML 파일 , 주석 처리한 부분을 확인할  있습니다.

    #xpack.security.transport.ssl.verification_mode: certificate

    #xpack.security.transport.ssl.keystore.path: elastic-certificates.p12

    #xpack.security.transport.ssl.truststore.path: elastic-certificates.p12

    이렇게 설정하면 p12 파일로 비교적 간단하게 설정을   있습니다.

     

    하지만 위의 설정 코드를 logstash / kibana 넣으면 docker-compose up, 오류를 발생합니다. 

    해당 설정은elasticsearch에서만 가능해 보입니다.

     

    또한 logstash kibana 사이에도 속성이 미묘하게 다릅니다.

    예를 들어 Logstash에서는 CA 파일만 있으면 elasticsearch TLS 통신이 가능합니다.

     


    xpack.monitoring.elasticsearch.ssl.certificate_authority: /usr/share/logstash/config/cert/ca.crt

     

    여기에 반 Kibana 경우, 

    server.ssl.enabled: true

    server.ssl.certificate: /usr/share/kibana/config/cert/hb-kibana.crt

    server.ssl.key: /usr/share/kibana/config/cert/hb-kibana.key

     

    elasticsearch.ssl.certificateAuthorities: [ "/usr/share/kibana/config/cert/ca.crt" ]

    CA 파일 뿐만 아니라 crt / key 페어도 넣어줘야 정상적으로 연동됩니다.

     

     

     

    모든 설정이 끝났다면 테스트를 해봐야 합니다.

    # curl https 요청하기

    curl --insecure -X GET -u elastic:xxxxxxx "https://10.10.15.202:9200?pretty"

     

    curl --cacert ca.crt -u elastic: xxxxxxx 'https://node2.elastic.elixian.co.kr:9200/_cat/nodes?v'

     

     

    인증서가 있는 경우, --cacert 옵션을 이용하고, 테스트의 경우에는 간단하게 –insecure 옵션을 주고 테스트 합니다.

     

     

    인증 관련 작업이 마무리 되면 Elasticsearch가 운용되는 서버의 VM 설정을 해야 합니다.

    설정은 Elasticsearch 홈페이지를 캡쳐했습니다.

     

    vm.max_map_count=262144

    RPM 등으로 설치하면 자동으로 잡아주는데 Docker로 설치할 경우, 별도로 셋팅해야 합니다.

     

    셋팅은 Docker Host에서 잡습니다.

    'Elixian의 Referenece' 카테고리의 다른 글

    RabbitMQ Clustering  (0) 2020.06.18

    댓글

Elixian