配置 SSL、TLS 以及 HTTPS 来确保 Elasticsearch、Kibana、Beats 和 Logstash 的安全
运行的是 Elastic Stack 6.7.x/7.0.x 或更早版本? 然后查看博文“如何设置 TLS...”,以获得有关如何在您的版本中确保通信安全的帮助信息。如想使用本篇博文中所讲的免费安全功能,您需要使用 Elastic Stack 6.8/7.1 或更新版本。 |
从 Elastic Stack 6.8 和 7.1 开始,Elastic 在默认分发包(基础许可证)中发布了一些免费安全功能。 新推出的功能包括:使用 SSL 对网络流量进行加密、创建和管理用户、定义角色来保护索引级和集群级访问权限,以及为 Kibana 提供全面保护。我们在新版本推出后不久便发布了开始使用博文,向大家解释如何在 Elasticsearch 和 Kibana 之间使用 TLS 通信。下面的博文对这一指南进行了扩展,向您讲解如何将 TLS 应用于 Elastic Stack 中的其他组件(包括 Logstash 和 Beats)。本文讨论了如何在组件之间启用 TLS,以及如何加密 HTTP 客户端通信。
请注意,尽管在 HTTP 层启用 TLS 并非硬性要求,但我们强烈建议如此做以实现端到端安全,进而保护数据,尤其是保护用户名/密码信息免遭泄露(这种情况可致使集群不安全)。如希望详细了解 TLS 加密、身份验证、受限脚本或隔离的相关信息,请查看我们的博文通过加密、用户等功能免费确保 Elasticsearch 集群安全性的几点提示。
额外补充一点,下方启用的安全功能在 Elasticsearch Service on Elastic Cloud 上为标配。所以如果您在 Elasticsearch Service 上进行操作,可直接跳转至第 5 步。
确保 Elastic Stack 安全性的步骤
- 准备工作
- 在 node1 上创建 SSL 证书并为 Elasticsearch 启用 TLS
- 在 node1 上为 Kibana 启用 TLS
- 在 node2 上为 Elasticsearch 启用 TLS
- 在 node1 上准备 Logstash 用户
- 在 node1 上为 Logstash 启用 TLS
- 在 node1 上运行 Filebeat 并设置 TLS
- 使用 Filebeat 采集数据
第 1 步:准备工作
下载 Elastic Stack 7.1 或更新版本的下列组件:
[1-1] 配置 /etc/hosts 文件
在本例中,我们的 node1 已安装一个浏览器,所以 kibana.local 将允许访问 Kibana 网页。
# [node1] 的 /etc/hosts 文件(我们需要 kibana.local 和 logstash.local) 127.0.0.1 kibana.local logstash.local 192.168.0.2 node1.elastic.test.com node1 192.168.0.3 node2.elastic.test.com node2
# [node2] 的 /etc/hosts 文件(我们这里不需要 kibana.local 和 logstash.local) 192.168.0.2 node1.elastic.test.com node1 192.168.0.3 node2.elastic.test.com node2
第 2 步:在 node1 上创建 SSL 证书并为 Elasticsearch 启用 TLS
[2-1] 设置环境变量(请根据 Elasticsearch 的下载方式和存储位置调整这些变量路径)
[root@node1 ~]# ES_HOME=/usr/share/elasticsearch [root@node1 ~]# ES_PATH_CONF=/etc/elasticsearch
[2-2] 创建 tmp 文件夹
[root@node1 ~]# mkdir tmp [root@node1 ~]# cd tmp/ [root@node1 tmp]# mkdir cert_blog
[2-3] 创建实例 yaml 文件
[root@node1 cert_blog]# vi ~/tmp/cert_blog/instance.yml # 将实例信息添加到 yml 文件 instances: - name: 'node1' dns: [ 'node1.elastic.test.com' ] - name: "node2" dns: [ 'node2.elastic.test.com' ] - name: 'my-kibana' dns: [ 'kibana.local' ] - name: 'logstash' dns: [ 'logstash.local' ]
[2-4] 生成 CA 和服务器证书(Elasticsearch 安装完毕之后)
[root@node1 tmp]# cd $ES_HOME [root@node1 elasticsearch]# bin/elasticsearch-certutil cert ca --pem --in ~/tmp/cert_blog/instance.yml --out ~/tmp/cert_blog/certs.zip
[2-5] 解压缩证书
[root@node1 elasticsearch]# cd ~/tmp/cert_blog [root@node1 cert_blog]# unzip certs.zip -d ./certs
[2-6] Elasticsearch TLS 设置
[2-6-1] 将 cert 文件复制到 config 文件夹
[root@node1 ~]# cd $ES_PATH_CONF [root@node1 elasticsearch]# pwd /etc/elasticsearch [root@node1 elasticsearch]# mkdir certs [root@node1 elasticsearch]# cp ~/tmp/cert_blog/certs/ca/ca* ~/tmp/cert_blog/certs/node1/* certs [root@node1 elasticsearch]# ll certs total 12 -rw-r--r--. 1 root elasticsearch 1834 Apr 12 08:47 ca.crt -rw-r--r--. 1 root elasticsearch 1834 Apr 12 08:47 ca.key -rw-r--r--. 1 root elasticsearch 1509 Apr 12 08:47 node1.crt -rw-r--r--. 1 root elasticsearch 1679 Apr 12 08:47 node1.key [root@node1 elasticsearch]#
[2-6-2] 配置 elasticsearch.yml
[root@node1 elasticsearch]# vi elasticsearch.yml ## add the following contents node.name: node1 network.host: node1.elastic.test.com xpack.security.enabled: true xpack.security.http.ssl.enabled: true xpack.security.transport.ssl.enabled: true xpack.security.http.ssl.key: certs/node1.key xpack.security.http.ssl.certificate: certs/node1.crt xpack.security.http.ssl.certificate_authorities: certs/ca.crt xpack.security.transport.ssl.key: certs/node1.key xpack.security.transport.ssl.certificate: certs/node1.crt xpack.security.transport.ssl.certificate_authorities: certs/ca.crt discovery.seed_hosts: [ "node1.elastic.test.com" ] cluster.initial_master_nodes: [ "node1" ]
[2-6-3] 启动并查看集群日志
[root@node1 elasticsearch]# grep '\[node1\] started' /var/log/elasticsearch/elasticsearch.log [o.e.n.Node ] [node1] started
[2-6-4] 设置内置用户的密码
[root@node1 elasticsearch]# cd $ES_HOME [root@node1 elasticsearch]# bin/elasticsearch-setup-passwords auto -u "https://node1.elastic.test.com:9200" Initiating the setup of passwords for reserved users elastic,apm_system,kibana,logstash_system,beats_system,remote_monitoring_user. The passwords will be randomly generated and printed to the console. Please confirm that you would like to continue [y/N] y Changed password for user apm_system PASSWORD apm_system = <apm_system_password> Changed password for user kibana PASSWORD kibana = <kibana_password> Changed password for user logstash_system PASSWORD logstash_system = <logstash_system_password> Changed password for user beats_system PASSWORD beats_system = <beats_system_password> Changed password for user remote_monitoring_user PASSWORD remote_monitoring_user = <remote_monitoring_user_password> Changed password for user elastic PASSWORD elastic = <elastic_password>
[2-6-5] 通过 HTTPS 访问 _cat/nodes API
[root@node1 elasticsearch]# curl --cacert ~/tmp/cert_blog/certs/ca/ca.crt -u elastic 'https://node1.elastic.test.com:9200/_cat/nodes?v' Enter host password for user 'elastic': ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name 192.168.0.2 16 95 10 0.76 0.59 0.38 mdi * node1
在步骤 2-4 中生成 SSL 证书时,我们提供--keep-ca-key</code选项,这意味着 <code>certs.zip 文件中包含 ca/ca.key 文件以及 ca/ca.crt 文件。只要您决定在 Elasticsearch 集群中添加更多节点,您将需要生成额外的节点证书,为此,您将需要上述两个“ca”文件以及用于生成这两个文件的密码。请将这两个“ca”文件的副本以及用于生成这两个文件的密码保存在安全的位置。 |
第 3 步:在 node1 上为 Kibana 启用 TLS
[3-1] 设置环境变量
根据 Kibana 的下载方式和存储位置调整这些变量路径:
[root@node1 ~]# KIBANA_HOME=/usr/share/kibana [root@node1 ~]# KIBANA_PATH_CONFIG=/etc/kibana
[3-2] 创建 config 和 config/certs 文件夹并复制 certs(Kibana 安装完毕后)
复制之前在步骤 2-4 中创建的证书文件,并粘贴到 kibana/config/certs 中。
[root@node1 kibana]# ls config/certs total 12 ca.crt my-kibana.crt my-kibana.key
[3-3] 配置 kibana.yml
切记使用在上面为内置用户生成的密码。您需要将
[root@node1 kibana]# vi kibana.yml server.name: "my-kibana" server.host: "kibana.local" server.ssl.enabled: true server.ssl.certificate: /etc/kibana/config/certs/my-kibana.crt server.ssl.key: /etc/kibana/config/certs/my-kibana.key elasticsearch.hosts: ["https://node1.elastic.test.com:9200"] elasticsearch.username: "kibana" elasticsearch.password: "<kibana_password>" elasticsearch.ssl.certificateAuthorities: [ "/etc/kibana/config/certs/ca.crt" ]
[3-4] 启动 Kibana 并测试 Kibana 登录信息
从浏览器访问 https://kibana.local:5601/。使用在步骤 2-6-4 中定义的 elastic
用户名和密码登录。在本例中,我们的 node1 已安装一个浏览器,所以 kibana.local 将允许访问 Kibana。
公共可信证书颁发机构拥有非常严格的标准和审计实践,以确保只有在验证正确的身份所有权之后,才会创建证书。在本篇博文中,我们会为 Kibana 创建一个自签名证书(意味着所生成证书是使用自己的私钥签署的)。由于客户端不信任自签署 Kibana 证书,您会在 Kibana 日志中看到类似下面的一条消息,直到使用企业或公共 CA 生成的证书建立正确信任关系为止(此处为 Kibana 存储库中这一问题的链接)。但这一问题并不影响您在 Kibana 中完成工作:
[18:22:31.675] [error][client][connection] Error:4443837888:error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown:../deps/openssl/openssl/ssl/s3_pkt.c:1498:SSL alert number 46
第 4 步:在 node2 上为 Elasticsearch 启用 TLS
[4-1] 设置环境变量
[root@node2 ~]# ES_HOME=/usr/share/elasticsearch [root@node2 ~]# ES_PATH_CONF=/etc/elasticsearch
[4-2] 在 node2 上设置 TLS
您可以使用 scp 命令将证书从 node1 复制到 node2。两个节点都需要证书和秘钥才能确保连接的安全性。在生产环境中,我们建议为每个节点使用按正确方式签署的秘钥。由于这里仅是演示,我们现在使用自动生成的 CA 证书,以及由所生成 CA 签署的多 DNS 主机名证书。
[root@node2 ~]# cd $ES_PATH_CONF [root@node2 elasticsearch]# pwd /etc/elasticsearch [root@node2 elasticsearch]# mkdir certs [root@node2 elasticsearch]# cp ~/tmp/cert_blog/certs/ca/ca.crt ~/tmp/cert_blog/certs/node2/* certs [root@node2 elasticsearch]# [root@node2 elasticsearch]# ll certs total 12 -rw-r--r--.1 root elasticsearch 1834 Apr 12 10:55 ca.crt -rw-r--r--.1 root elasticsearch 1509 Apr 12 10:55 node2.crt -rw-r--r--.1 root elasticsearch 1675 Apr 12 10:55 node2.key
[4-3] 配置 elasticsearch.yml
[root@node2 elasticsearch]# vi elasticsearch.yml node.name: node2 network.host: node2.elastic.test.com xpack.security.enabled: true xpack.security.http.ssl.enabled: true xpack.security.transport.ssl.enabled: true xpack.security.http.ssl.key: certs/node2.key xpack.security.http.ssl.certificate: certs/node2.crt xpack.security.http.ssl.certificate_authorities: certs/ca.crt xpack.security.transport.ssl.key: certs/node2.key xpack.security.transport.ssl.certificate: certs/node2.crt xpack.security.transport.ssl.certificate_authorities: certs/ca.crt discovery.seed_hosts: [ "node1.elastic.test.com" ]
[4-4] 启动并查看集群日志
[root@node2 elasticsearch]# grep '\[node2\] started' /var/log/elasticsearch/elasticsearch.log [o.e.n.Node ] [node2] started
[4-5] 通过 HTTPS 访问 _cat/nodes API
[root@node2 elasticsearch]# curl --cacert ~/tmp/cert_blog/certs/ca/ca.crt -u elastic:<password set previously> 'https://node2.elastic.test.com:9200/_cat/nodes?v' ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name 192.168.0.2 25 80 5 0.18 0.14 0.30 mdi * node1 192.168.0.3 14 96 44 0.57 0.47 0.25 mdi - node2
第 5 步:在 node1 上准备 Logstash 用户
[5-1] 创建 logstash_write_role
您可以通过多种方式创建角色。
既可以使用 Kibana Roles UI(Kibana 角色 UI)创建:
也可以使用 Kibana Dev Tools(Kibana 开发工具)标签卡中的 API 创建:
POST /_security/role/logstash_write_role { "cluster": [ "monitor", "manage_index_templates" ], "indices": [ { "names": [ "logstash*" ], "privileges": [ "write", "create_index" ], "field_security": { "grant": [ "*" ] } } ], "run_as": [], "metadata": {}, "transient_metadata": { "enabled": true } }
随后您会收到响应:
{"role":{"created":true}}
分配至此角色的用户将无法删除任何文档。此角色存在限制:只有用户在索引中以 logstash
或索引文档开始时,此角色才允许用户创建索引。
ILM 用户注意事项: 要使 logstash_writer_role 与索引生命周期管理 (ILM)(在 7.3+ 中默认启用)协同工作,必须包含以下权限:
"privileges": ["write","create","delete","create_index","manage","manage_ilm"] |
[5-2] 创建 logstash_writer 用户(请为用户 logstash_writer 更改密码)
您可以通过多种方式创建用户。
既可以使用 Kibana Users UI(Kibana 用户 UI)创建:
也可以使用 Kibana Dev Tools(Kibana 开发工具)标签卡中的 API 创建:
POST /_security/user/logstash_writer { "username": "logstash_writer", "roles": [ "logstash_write_role" ], "full_name": null, "email": null, "password": "<logstash_system_password>", "enabled": true }
随后您会收到响应:
{"user":{"created":true}}
第 6 步:在 node1 上为 Logstash 启用 TLS
[6-1] 创建文件夹并复制证书
[root@node1 logstash]# ls -l total 24 ca.crt logstash.crt logstash.key
[6-2] 针对 Beats 输入插件,将 logstash.key 转换为 PKCS#8 格式
[root@node1 logstash]# openssl pkcs8 -in config/certs/logstash.key -topk8 -nocrypt -out config/certs/logstash.pkcs8.key
[6-3] 配置 logstash.yml
切记对于 logstash_system 用户,要使用自动生成的密码。使用在步骤 2-6-4 中定义的密码。
[root@node1 logstash]# vi logstash.yml
然后编辑:
node.name: logstash.local path.config: /etc/logstash/conf.d/*.conf xpack.monitoring.enabled: true xpack.monitoring.elasticsearch.username: logstash_system xpack.monitoring.elasticsearch.password: '<logstash_system_password>' xpack.monitoring.elasticsearch.hosts: [ 'https://node1.elastic.test.com:9200' ] xpack.monitoring.elasticsearch.ssl.certificate_authority: /etc/logstash/config/certs/ca.crt
[6-4] 创建并配置 conf.d/example.conf
在 Elasticsearch 输出上,使用在步骤 5-2 中定义的密码。
[root@node1 logstash]# vi conf.d/example.conf input { beats { port => 5044 ssl => true ssl_key => '/etc/logstash/config/certs/logstash.pkcs8.key' ssl_certificate => '/etc/logstash/config/certs/logstash.crt' } } output { elasticsearch { hosts => ["https://node1.elastic.test.com:9200","https://node2.elastic.test.com:9200"] cacert => '/etc/logstash/config/certs/ca.crt' user => 'logstash_writer' password => <logstash_writer_password> } }
[6-5] 使用示例配置启动 Logstash 并查看 Logstash 日志
您应该会看到下面的日志消息:
[INFO ][logstash.pipeline ] Pipeline started successfully {:pipeline_id=>".monitoring-logstash", :thread=>"#<Thread:0x640c14d2@/usr/share/logstash/logstash-core/lib/logstash/pipeline.rb:246 run
然后在 Kibana Monitoring 标签卡中,将会显示 Logstash(节点信息、管道设置、OS 信息、JVM 信息、进程统计数据,以及管道运行时间统计数据):
第 7 步:在 node1 上运行 Filebeat 并设置 TLS
[7-1] 创建 config 文件夹并复制证书
[root@node1 filebeat]# mkdir config [root@node1 filebeat]# mkdir config/certs [root@node1 filebeat]# cp ~/tmp/cert_blog/certs/ca/ca.crt config/certs [root@node1 filebeat]# ll config/certs/ total 4 -rw-r--r--.1 root root 1834 Apr 20 00:18 ca.crt
[7-2] 创建一个新的 filebeat.yml
[root@node1 filebeat]# pwd /etc/filebeat [root@node1 filebeat]# mv filebeat.yml filebeat.yml.old
[7-3] 编辑您的新配置文件 filebeat.yml
filebeat.inputs: - type: log paths: - /etc/filebeat/logstash-tutorial-dataset output.logstash: hosts: ["logstash.local:5044"] ssl.certificate_authorities: - /etc/filebeat/config/certs/ca.crt
第 8 步:使用 Filebeat 采集数据
[8-1] 准备 Filebeat 要用的输入日志数据 (logstash-tutorial.log)
首先请下载输入日志数据。
[root@node1 filebeat]# pwd /etc/filebeat [root@node1 filebeat]# mkdir logstash-tutorial-dataset [root@node1 filebeat]# cp /root/logstash-tutorial.log logstash-tutorial-dataset/. [root@node1 filebeat]# ll logstash-tutorial-dataset/ total 24 -rwxr-x---.1 root root 24464 Apr 20 00:29 logstash-tutorial.log
[8-2] 启动 Filebeat
[root@node1 filebeat]# systemctl start filebeat [root@node1 filebeat]# systemctl enable filebeat Created symlink from /etc/systemd/system/multi-user.target.wants/filebeat.service to /usr/lib/systemd/system/filebeat.service.
[8-3] 查看日志
您应该会看到下面的日志消息:
INFO log/harvester.go:216 Harvester started for file: /etc/filebeat/logstash-tutorial-dataset/logstash-tutorial.log
[8-4] 创建索引模式
接下来,创建与所采集数据相匹配的索引模式。这将允许您在 Kibana 中对数据进行可视化,例如使用 Graph 或 Discover。
然后选择 Time Filter field name(时间筛选器字段名)。在我们的例子中,其为 @timestamp
:
大功告成!您已对 Elastic Stack 不同部分之间的通信进行加密,现在可以安心且安全地采集日志数据了。
最后几点提示……
如果您在配置安全性的过程中遇到任何问题,建议您首先查看我们文档中的安全故障排查页面。该页面能帮助解决很多常见问题。如果问题仍未得到解决,您可查看我们的 Elastic 论坛以寻求更多帮助。或者如果您想直接与 Elastic 支持团队对话,欢迎立即订阅 Elastic 服务,然后便可直接向我们的专家团队寻求帮助。祝您拥有安全的使用体验!