Elasticsearch、Kibana、Beats 和 Logstash 的安全設定

🔐Elasticsearch、Kibana、Beats 和 Logstash 的安全設定

tags: ELK, beats, security , SSL , TLS

0. 了解ELK_Xpack & 安全模式

  • Xpack

    X-Pack is an Elastic Stack extension that provides security, alerting, monitoring, reporting, machine learning, and many other capabilities.

ELK是有收費版本的 而Xpack部分功能只有付費才開放
請參考:X-Pack features

  • ELK叢集安全模式
    #ES設定中加入 就是開啟xpack
    xpack.security.enabled: true

    重要觀念:

    誰對誰 誰是server端 誰是client要分清楚
    一個服務可能又是server又是client

1. 使用憑證產生工具為每個es_node 產生憑證

  • 利用工具產生憑證(也可以用openssl指令)

    openssl ex:

    openssl ecparam -out ELK.key -name prime256v1 -genkey
    openssl req -new -sha256 -key ELK.key -out ELK.csr
    openssl x509 -req -sha256 -days 3650 -in ELK.csr -signkey ELK.key -out ELK.crt
    openssl pkcs12 -export -out ELK.ca.p12 -inkey ELK.key -in ELK.crt

產生CA

/usr/share/elasticsearch/bin/elasticsearch-certutil ca

產生各ES憑證串自簽的CA (是否加密碼,綁定域名,IP 關係後續驗證方式)

/usr/share/elasticsearch/bin/elasticsearch-certutil cert --ca /path/to/elastic-stack-ca.p12

產生http_ssl (是否加密碼,綁定域名,IP 關係後續驗證方式)

/usr/share/elasticsearch/bin/elasticsearch-certutil http --ca /path/to/elastic-stack-ca.p12

Ref: Encrypting HTTP client communicationsedit

2. 設定每個es_node的憑證:

  • TLS (transport 9300)

  • SSL (http 9200)

  • Elasticsearch Coordinating node config

    /etc/elasticsearch/elasticsearch.yml
    bootstrap.memory_lock: true
    cluster.initial_master_nodes:
    - jp-node-1
    - jp-node-2
    - jp-node-3
    - jp-node-4
    - jp-node-5
    - jp-node-6
    cluster.name: es-cluster-jp
    discovery.seed_hosts:
    - 10.20.30.47:9300
    - 10.20.30.48:9300
    - 10.20.30.49:9300
    - 10.20.30.50:9300
    - 10.20.30.51:9300
    - 10.20.30.52:9300
    gateway.recover_after_data_nodes: 2
    http.port: 9200
    #listen interface
    network.bind_host: 0.0.0.0
    #溝通網段
    network.publish_host: 10.20.30.247
    node.attr.rack: r1
    #宣告這個node的作用 請參照 ↓
    ##https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html
    node.data: false
    node.ingest: true
    node.master: false
    node.name: jp-tribe-node
    transport.port: 9300
    #安全性開關 不然預設ELK是完全沒有安全保護 ↓
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    #transport.ssl(9300)驗證方式 有certificate,none,full(域名+IP+憑證) ↓
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: /etc/elasticsearch/elastic.ca/${node.name}.p12
    xpack.security.transport.ssl.truststore.path: /etc/elasticsearch/elastic.ca/${node.name}.p12
    #這邊是http.ssl(9200)驗證用 ↓
    # This turns on SSL for the HTTP (Rest) interface
    xpack.security.http.ssl.enabled: true
    xpack.security.http.ssl.client_authentication: optional
    # This configures the keystore to use for SSL on HTTP
    xpack.security.http.ssl.keystore.path: "http.p12"
    xpack.security.http.ssl.truststore.path: "http.p12"

    #################################### Paths ####################################

    # Path to directory containing configuration (this file and logging.yml):
    path.data: /var/lib/elasticsearch
    path.logs: /var/log/elasticsearch
    action.auto_create_index: true
  • Elasticsearch Master-node-1 config

    /etc/elasticsearch/elasticsearch.yml
    bootstrap.memory_lock: true
    cluster.initial_master_nodes:
    - jp-node-1
    - jp-node-2
    - jp-node-3
    - jp-node-4
    - jp-node-5
    - jp-node-6
    cluster.name: es-cluster-jp
    #這裡各台有所不同 ↓
    discovery.seed_hosts:
    - 10.20.30.247:9300
    - 10.20.30.48:9300
    - 10.20.30.49:9300
    - 10.20.30.50:9300
    - 10.20.30.51:9300
    - 10.20.30.52:9300
    gateway.recover_after_data_nodes: 2
    http.port: 9200
    #根據角色不同監聽的位置有所不同增加安全性 ↓
    network.bind_host:
    - _local_
    - 10.20.30.47
    network.publish_host: 10.20.30.47
    node.attr.rack: r1
    #角色不同設定不同 ↓
    node.data: true
    node.ingest: false
    node.master: true
    node.name: jp-node-1
    transport.port: 9300
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: full
    xpack.security.transport.ssl.keystore.path: /etc/elasticsearch/elastic.ca/${node.name}.p12
    xpack.security.transport.ssl.truststore.path: /etc/elasticsearch/elastic.ca/${node.name}.p12

    #################################### Paths ####################################

    # Path to directory containing configuration (this file and logging.yml):
    path.data: /var/lib/elasticsearch
    path.logs: /var/log/elasticsearch
    action.auto_create_index: true

設定完畢記得重啟服務

systemctl restart elasticsearch

有關ES服務滾動式升級🕳

Rolling upgrade

3. 設定監控 跟 帳密

  • 帳密設定

    # 互動式
    /usr/share/elasticsearch/bin/elasticsearch-setup-passwords interactive

    # 自動產生
    /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto

    密碼生出來後,就把帳號密碼收好,等等會用到。之後初次登入也是使用這些密碼

  • 監控設定

legacy collectors
Kibana ES 內建都有開啟 不用特別設定 logstash 要開啟Xpack設定監控(因為要開監控帳號)

Metricbeat

目前還是用legacy collectors監控所以這個請當參考用
官方推薦用metricbeat來監控 等到不支援時就要改這個
https://www.elastic.co/guide/en/elasticsearch/reference/current/secure-monitoring.html

4. 設定 Kibana

Configure passwords on client-side(keystore)

/usr/share/kibana/bin/kibana-keystore create
/usr/share/kibana/bin/kibana-keystore add elasticsearch.username
/usr/share/kibana/bin/kibana-keystore add elasticsearch.password

kibana.yml

/etc/kibana/kibana.yml
server.port: 5601
server.host: "0.0.0.0"
server.name: "JP-Kibana.246:5601"
elasticsearch.hosts: ["https://192.168.9.247:9200"]
xpack.security.session.idleTimeout: "30m"
xpack.security.session.lifespan: "8h"
xpack.security.encryptionKey: "something_at_least_32_characters"
xpack.encryptedSavedObjects.encryptionKey: "something_at_least_32_characters"
#↓下面是kibana當server 瀏覽器client的憑證
server.ssl.enabled: true
server.ssl.certificate: "/etc/kibana/cukgad.mis/cukgad.mis.crt"
server.ssl.key: "/etc/kibana/cukgad.mis/cukgad.mis.key"
#↓下面是kibana當client 到ES時需要的公鑰
elasticsearch.ssl.certificateAuthorities: "/etc/kibana/elasticsearch-ca.pem"
elasticsearch.ssl.verificationMode: full

5. 設定 Logstash

Configure passwords on client-side(keystore)

  • logstash-keystore
    #比較不同的是logstash是java寫的 所以要用比較有點不同的方式加keystore
    $ set +o history
    $ export LOGSTASH_KEYSTORE_PASS=!QAZxsw2
    $ set -o history
    $ sudo -E /usr/share/logstash/bin/logstash-keystore --path.settings /etc/logstash create
    $ sudo -E /usr/share/logstash/bin/logstash-keystore --path.settings /etc/logstash add LS_USER
    $ sudo -E /usr/share/logstash/bin/logstash-keystore --path.settings /etc/logstash add LS_PWD
    $ sudo -E /usr/share/logstash/bin/logstash-keystore --path.settings /etc/logstash add LW_USER
    $ sodu -E /usr/share/logstash/bin/logstash-keystore --path.settings /etc/logstash add LW_PWD
  • logstash.yml
    /etc/logstash/logstash.yml
    path.data: /var/lib/logstash
    pipeline.ordered: auto
    config.reload.automatic: true
    config.reload.interval: 15s
    path.logs: /var/log/logstash
    xpack.monitoring.enabled: true
    xpack.monitoring.elasticsearch.username: ${LS_USER}
    xpack.monitoring.elasticsearch.password: ${LS_PWD}
    xpack.monitoring.elasticsearch.hosts: [ "https://10.20.30.247:9200" ]
    xpack.monitoring.elasticsearch.ssl.certificate_authority: /etc/logstash/elasticsearch-ca.pem
    xpack.monitoring.elasticsearch.ssl.verification_mode: certificate
$LS_HOME/conf.d/output.conf
output {
elasticsearch {
user => "${LW_USER}"
password => "${LW_PWD}"
ssl => true
cacert => "/etc/logstash/elasticsearch-ca.pem"
hosts => "http://localhost:9200"
if "nginx" in [tags] {
if [@metadata][pipeline] {
#manage_template => false
index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
pipeline => "%{[@metadata][pipeline]}"
} else {
manage_template => false
ilm_enabled => true
ilm_rollover_alias => "nginx-log"
#ilm_pattern => "{now/d}-000001"
#index => "nginx-log-%{+YYYY.MM.dd}"
}
} else if "squid" in [tags] {
index => "%{[@metadata][beat]}-%{+YYYY.MM.dd}"
} else if "netscaler" in [tags] {
index => "ns-syslog-%{+YYYY.MM.dd}"
} else if "idrac" in [tags] {
index => "idrac-syslog-%{+YYYY.MM.dd}"
} else if "pure" in [tags] {
index => "pure-syslog-%{+YYYY.MM.dd}"
} else if "vmware" in [tags] {
index => "vmware-syslog-%{+YYYY.MM.dd}"
} else {
index => "logstash-%{+YYYY.MM.dd}"
}
}
# stdout { codec => rubydebug }
}

設定訪問帳號權限

ES api 設定

  • Internal Logstash User

    POST /_security/role/logstash_writer
    {
    "cluster": ["manage_index_templates", "monitor", "manage_ilm"],
    "indices": [
    {
    "names": [ "logstash-*", "nginx-*", "filebeat-*"],
    "privileges": ["write","create","delete","create_index","manage","manage_ilm"]
    }
    ]
    }

    POST /_security/user/logstash_internal
    {
    "password" : "x-pack-test-password",
    "roles" : [ "logstash_writer"],
    "full_name" : "Internal Logstash User"
    }
  • Kibana User for Logstash

    POST /_security/role/logstash_reader
    {
    "indices": [
    {
    "names": [ "logstash-*" ],
    "privileges": ["read","view_index_metadata"]
    }
    ]
    }

    POST /_security/user/logstash_user
    {
    "password" : "x-pack-test-password",
    "roles" : [ "logstash_reader", "logstash_admin"],
    "full_name" : "Kibana User for Logstash"
    }

    Kibana GUI 設定

  • 待補

Logstash Server端加密設定

$LS_HOME/conf.d/input.conf
input {   
beats {
port => 5044
host => "0.0.0.0"
#目前logsttash加密設定在這幾行 但目前沒加 因為加了各台beats要去裝公鑰
#ssl => true
#ssl_certificate => '/etc/logstash/certs/logstash.crt'
#ssl_key => '/etc/logstash/certs/logstash.key'
}
syslog {
port => 5041
type => syslog
tags => idrac
}
syslog {
port => 5042
type => syslog
tags => pure
}
tcp {
port => 5043
type => tcp
tags => netscaler
}
udp {
port => 5043
type => udp
tags => netscaler
}
syslog {
port => 1514
type => syslog
}
# stdin {}
}

6. 設定 Beats

  • 如果 beat 有設定送ES或logstash有設定加密就要做
    • 目前logstash沒有加密
    • ES 端待補充

Configure passwords on client-side

/usr/share/apm-server/bin/filebeat keystore create
/usr/share/apm-server/bin/filebeat add elasticsearch.username
/usr/share/apm-server/bin/filebeat add elasticsearch.password