配置 SSL、TLS 以及 HTTPS 来确保 Elasticsearch、Kibana、Beats 和 Logstash 的安全

1,444 阅读5分钟
运行的是 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 安全性的步骤

  1. 准备工作
  2. 在 node1 上创建 SSL 证书并为 Elasticsearch 启用 TLS
  3. 在 node1 上为 Kibana 启用 TLS
  4. 在 node2 上为 Elasticsearch 启用 TLS
  5. 在 node1 上准备 Logstash 用户
  6. 在 node1 上为 Logstash 启用 TLS
  7. 在 node1 上运行 Filebeat 并设置 TLS
  8. 使用 Filebeat 采集数据

Elastic Stack 示意图

第 1 步:准备工作

下载 Elastic Stack 7.1 或更新版本的下列组件:

[1-1] 配置 /etc/hosts 文件

在本例中,我们的 node1 已安装一个浏览器,所以 kibana.local 将允许访问 Kibana 网页。

# [node1] 的 /etc/hosts 文件(我们需要 kibana.local 和 logstash.local127.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.local192.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
-rwRead More

[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_authoritiesRead More

[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 likeRead More

[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

切记使用在上面为内置用户生成的密码。您需要将 替换为在步骤 2-6-4 中定义的密码。

[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.passwordRead More

[3-4] 启动 Kibana 并测试 Kibana 登录信息

从浏览器访问 kibana.local:5601/。使用在步骤 2-6-4 中定义的 elastic 用户名和密码登录。在本例中,我们的 node1 已安装一个浏览器,所以 kibana.local 将允许访问 Kibana。

登录 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 elasticsearchRead More

[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" ]
Read Less

[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)创建: 

创建 logstash_write_role

也可以使用 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)创建:

![创建 logstash_writer 用户](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/754565aeaffb4f0e9530f86f8226bb33~tplv-k3u1fbpfcp-zoom-1.image)

也可以使用 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](https://www.elastic.co/cn/blog/configuring-ssl-tls-and-https-to-secure-elasticsearch-kibana-beats-and-logstash#step-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: [ 'node1.elastic.test.com:9200' ] xpack.monitoring.elasticsearch.ssl.certificate_authorityRead More


### \[6-4] 创建并配置 conf.d/example.confElasticsearch 输出上,使用在[步骤 5-2](https://www.elastic.co/cn/blog/configuring-ssl-tls-and-https-to-secure-elasticsearch-kibana-beats-and-logstash#step-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 => ["node1.elastic.test.com:9200","https://node2.elas…"] cacert => '/etcRead More


### \[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](https://www.elastic.co/guide/en/logstash/7.1/monitoring-logstash.html)(节点信息、管道设置、OS 信息、JVM 信息、进程统计数据,以及管道运行时间统计数据):

![Kibana Monitoring 标签卡,正显示 Logstash](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/967fbfc985d4409e9dbb62c4821c0d90~tplv-k3u1fbpfcp-zoom-1.image)

## 第 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)

首先请下载[输入日志数据](https://download.elastic.co/demos/logstash/gettingstarted/logstash-tutorial.log.gz)。

[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] 创建索引模式

接下来,创建与所采集数据相匹配的[索引模式](https://www.elastic.co/guide/en/kibana/7.1/tutorial-define-index.html)。这将允许您在 Kibana 中对数据进行可视化,例如使用 Graph 或 Discover。

![在 Kibana 中创建索引模式。](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5ea24c8fe16149179b343f5a7bca69de~tplv-k3u1fbpfcp-zoom-1.image)

然后选择 Time Filter field name(时间筛选器字段名)。在我们的例子中,其为 `@timestamp`:

![指定一个 Time Filter field name(时间筛选器字段名)。](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3b4a09e01819495c83d28c367f9dfef5~tplv-k3u1fbpfcp-zoom-1.image)

大功告成!您已对 Elastic Stack 不同部分之间的通信进行加密,现在可以安心且安全地采集日志数据了。

## 最后几点提示……

如果您在配置安全性的过程中遇到任何问题,建议您首先查看我们文档中的[安全故障排查页面](https://www.elastic.co/guide/en/elastic-stack-overview/7.1/security-troubleshooting.html)。该页面能帮助解决很多常见问题。如果问题仍未得到解决,您可查看我们的 [Elastic 论坛](https://discuss.elastic.co/)以寻求更多帮助。或者如果您想直接与 Elastic 支持团队对话,欢迎立即[订阅 Elastic 服务](https://www.elastic.co/cn/subscriptions),然后便可直接向我们的专家团队寻求帮助。祝您拥有安全的使用体验!

转载:<https://www.elastic.co/cn/blog/configuring-ssl-tls-and-https-to-secure-elasticsearch-kibana-beats-and-logstash>