TLS应用在Elastic Statck:Elasticsearch,kibana,Beat和Logstash

原文作者:Jared Carey

本文翻译BLOG,原文地址:https://www.elastic.co/blog/tls-elastic-stack-elasticsearch-kibana-logstash-filebeat

传输层安全性(TransportLayerSecurity,TLS)可以部署在整个Elastic Statck中,允许加密通信,这样您就可以在夜间轻松地休息,因为知道通过您的网络传输的数据是安全的。这似乎不太必要,但是再次考虑不可能的情况,即确保没有开发人员开始将敏感数据记录到您要传送到中心位置的日志中。敏感数据大多数人认为是客户信息、密码等。然而,对于我们所处的网络安全时代来说,这种敏感数据的定义过于狭窄。假设有一个受威胁的路由器允许攻击者窥视网络上未加密的原始数据,在其中看到日志数据可以提供网络上使用的所有软件的软件和操作系统版本。这提供了攻击者查找已知软件漏洞所需的所有细节,这些漏洞可能允许攻击者直接访问这些服务器。整个组织的安全取决于最薄弱的环节,在当今网络安全攻击的世界里-不要让你的日志/搜索系统成为最薄弱的环节。

6.X需要Elasticsearch TLS节点,为节点通信当使用X-pack安全特性在多节点集群上。更多的信息参考这里

这个博客将引导您完成设置和配置TLS的过程,使所有数据保持来自Filebat->Logstash->Elasticsearch->Kibana->您的Web浏览器的所有数据。您将需要一个有可用内存的系统来运行其中的每一个,当你将设置两个Elasticsearch节点(默认每个节点需要1G内存,若要保留内存,则第二个节点是可选的),一个Logstash服务器(默认需要1G内存),一个Kibana服务器(~200M内存),和一个FileBeat(~10M)。你将需要总共6G的系统内存,但是,8GB将是理想的,因为我无法知道您正在运行的其他软件或内存饥饿的浏览器(打开50个选项卡)。

理解TLS/Certs

首先,我们应该从一些基本原理开始,讨论什么是证书以及如何使用证书。证书保存公共信息(包括公钥),该信息有助于加密双方之间的数据;其中只有具有匹配私钥的方才能从初始握手中解密数据。在不太深入细节的情况下,公钥和私钥代表了一个难以计算但易于验证的计算谜题,其中私钥包含非常大的数字,可以轻松地解决这个计算难题。在现代公钥密码学中,难以计算意味着解决这个计算难题所需的数学运算,用当前的计算资源需要数千年的时间。私钥保存容易验证谜题所需的源号,并且证书是从私钥生成的,以包含对此数学谜题的必要输入。在接下来的示例中,我将使用服务器的DNS名称作为标识。谜题的所有公共部分和证书的标识都是首先通过生成证书签名请求(CSR)来创建的。在接下来的示例中,我将使用服务器的DNS名称作为标识。谜题的所有公共部分和证书的标识都是首先通过生成证书签名请求(CSR)来创建的。

证书的认证/验证非常重要,因为客户端和服务器之间的握手需要客户端信任服务器证书的签名权威。客户端必须直接信任服务器的证书,或者由客户端信任的权威机构签名。例如,您的OS/浏览器有一个预先设置的证书列表,这些证书是“公开”受信任的。当您访问google.com时,这个证书是由一个授权链签名的,它可以为您的客户端OS/浏览器创建一个返回可信证书的路径。把它想象成签署法律文件的公证人,公证人必须经过某种方式的认证才能被认可。

以最简单的形式,证书颁发机构(也称为根授权机构)是自签名的-这意味着生成的证书是使用自己的私钥签名的。受公众信任的当局有非常严格的标准和审计做法,以确保在没有验证适当身份所有权的情况下不会创建证书。如果您想要生成一个证书为 http://elastic.example,你需要首先证明这个域名/身份的所有权。

在证书中,主题包含一个区分名称(DN),它至少具有公共名称(CN)。CN可以设置为任何内容,主题替代名称(SAN)应用于指定适当的标识,如DNS名称和/或IP地址。SAN还可以包含多个DNS和/或IP地址。此标识将用于客户端验证,以便服务器的证书与证书中存在的标识正确匹配。客户端将通过解析DNS名称来验证这一点,同时尝试建立新连接。

此时,您可能会想知道,当只有服务器才有要解密的信息时,如何对所有通信进行加密。这就是TLS握手的地方,最好用下面的图片来解释。若要启动此握手,客户端必须发出连接到服务器(1)的请求。服务器然后响应一个证书(2),然后,客户端负责验证/信任服务器的身份,如前所述(3)。如果您希望获得服务器还必须信任客户端(4)的附加安全性,服务器也可以请求客户端证书。客户端使用服务器的公钥创建一个新的对称密钥,即共享密钥,此时只有客户端了解该密钥。它使用服务器的公钥加密这个共享密钥,这允许服务器接收这个新的共享密钥并解密(5)。此时,共享密钥现在只为客户端和服务器(7)(8)所知,并且可以用于对双方之间的通信进行加密和保密(9)。

2.png

现在,让我们通过在每个产品之间设置带有TLS加密通信的弹性堆栈,将这些知识付诸实践。此设置将不涵盖所有功能和设置,只是应用TLS加密的最低限度。

设置和下载

为了让事情变得更简单,我们应该设置一个目录,以便在整个博客中使用。我将把它存储在我用户的主目录中。如果tmp文件夹在主目录中不存在,则-p选项将创建该文件夹。

$ mkdir -p ~/tmp/cert_blog

Beats、Logstash和Kibana在开源产品中都支持TLS。ElasticSearch需要我们的商业插件X-Pack,用于TLS和其他安全功能。X-Pack安全性提供身份验证和授权控制,以防止对文档中的索引、文档甚至字段的访问。X-Pack还提供警报、监控、报告、图表探索、机器学习和支持!更多细节请看这里

下载以下产品的最新预览版本。选择zip或tar文件格式,并将它们放在我们创建的~/tmp/cert_blog文件夹中:

ElasticSearch

Kibana

Logstash

FileBeat

(您也可以使用5.x弹性堆栈设置TLS。下面说明中唯一的主要变化是,您不会为ElasticSearch用户生成密码,因为这些密码是随默认密码设置一起提供的)

解压到相同的文件夹,例如ElasticSearch.6.0.0.tar.gz ---> ElasticSearch.6.0.0

Elastic certgen tool

X-Pack添加的一个令人惊奇的特性是certgen工具。OpenSSL可以用于生成和签名证书;但是,即使是经验丰富的用户也很难使用它,并且在尝试插入公共项(如Subject Alternative Name(SAN)时,可能会导致无数个小时的挫折。certgen使生成必要的证书甚至签名授权变得容易。如果您打算让公共或公司/内部签名机构签署证书,甚至可以使用它来创建CSR。

要访问certgen工具,我们必须首先安装ElasticSearchX-Pack.

(安装将提示允许java安全管理器修改,请回答是)

$ cd ~/tmp/cert_blog/elasticsearch-6.0.0-beta2
$ bin/elasticsearch-plugin install x-pack

创建证书颁发机构/签名机构

用密码加密私钥是一种很好的做法,特别是如果它将用于签署其他证书。让我们创建这个密码,用于加密证书颁发机构的私钥。您可以在这里使用您想要的任何东西,也可以使用下面的命令来生成一个强密码。请确保安全保存您选择的任何密码,因为它是不可能恢复的,您将需要它来签署证书。

$ openssl rand -base64 32
 <long complex password>

进入ElasticSearch文件夹

$ cd ~/tmp/cert_blog/elasticsearch-6.0.0-beta2

在接下来的步骤中,我们将创建用于签名其他证书的根权限。使用您想要的任何名称(但保留CN=part)。在下面的示例中,生成的公共证书的寿命为10年,并将生成一个具有4096 bit的大私钥。当出现提示时,您将需要输入您选择或生成的密码。点击Enter可以跳过后续的实例名称问题,因为我们不想创建更多的服务器证书。

$ bin/x-pack/certgen --dn 'CN=MyExample Global CA' --pass --days 3650 --keysize 4096 --out ~/tmp/cert_blog/MyExample_Global_CA.zip
...
Enter password for CA private key:
Enter instance name:
Would you like to specify another instance? Press 'y' to continue entering instance information:

在某些时候,您可能希望查看Certgen文档的所有可能设置和使用,但我将提供完成本练习所需的所有命令。

现在应该有一个zip文件,其中包含根证书颁发机构的私钥和公共证书。解压缩此文件,但请记住,我们只分发ca/ca.crt文件。ca/ca.key文件应该存储起来,以便安全保存(以及解密之前所需的密码)。

$ cd ~/tmp/cert_blog
$ unzip MyExample_Global_CA.zip
Archive:  MyExample_Global_CA.zip
   creating: ca/
  inflating: ca/ca.crt
  inflating: ca/ca.key

我们可以使用OpenSSL检查这个新证书的细节。您将注意到Issuer=Subject,它指示证书是自签名的。扩展部分可以包含帮助识别当前证书或签名证书的SAN或指纹之类的信息。基本约束很重要,CA:true表明它可以用于签署其他证书。

$ openssl x509 -noout -text -in ca/ca.crt
...
        Issuer: CN=MyExample Global CA
        Validity
            Not Before: Sep 24 19:42:40 2017 GMT
            Not After : Sep 22 19:42:40 2027 GMT
        Subject: CN=MyExample Global CA
...
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                8F:6C:8B:20:B3:7A:D9:18:31:9B:99:CC:8C:93:25:98:75:F4:4B:60
            X509v3 Authority Key Identifier:
                keyid:8F:6C:8B:20:B3:7A:D9:18:31:9B:99:CC:8C:93:25:98:75:F4:4B:60
                DirName:/CN=MyExample Global CA
                serial:0C:0B:14:99:98:D6:7B:64:0D:00:03:64:B8:1F:7D:F7:9F:BF:6F:30
            X509v3 Basic Constraints: critical
                CA:TRUE
...

生成服务器证书

创建一个新文件~/tmp/cert_blog/certgen_example.yml

此示例将为两个ElasticSearch节点(kibana和logstash)生成公共证书和私钥;这些证书的使用将要求正确设置DNS名称。出于测试目的,我们可以编辑/etc/host,这样这些DNS名称将是有效的。

instances:
  - name: 'node1'
    dns: [ 'node1.local' ]
  - name: "node2"
    dns: [ 'node2.local' ]
  - name: 'my-kibana'
    dns: [ 'kibana.local' ]
  - name: 'logstash'
    dns: [ 'logstash.local' ]

在下一个命令中,我们将使用上面创建的YAML文件,并为每个实例生成有效期为3年的证书(使用您所熟悉的任何时间段,请记住,当证书过期时-它将需要被替换)。我们必须为前面创建的签名/根权限指定证书和密钥,--pass选项将提示我们解密签名权威的私钥所需的密码。

$ cd ~/tmp/cert_blog/elasticsearch-6.0.0-beta2
$ bin/x-pack/certgen --days 1095 --cert ~/tmp/cert_blog/ca/ca.crt --key ~/tmp/cert_blog/ca/ca.key --pass --in ~/tmp/cert_blog/certgen_example.yml --out ~/tmp/cert_blog/certs.zip

解压缩创建的文件

$ cd ~/tmp/cert_blog
$ unzip certs.zip -d ./certs
Archive:  certs.zip
   creating: ./certs/node1/
  inflating: ./certs/node1/node1.crt
  inflating: ./certs/node1/node1.key
   creating: ./certs/node2/
  inflating: ./certs/node2/node2.crt
  inflating: ./certs/node2/node2.key
   creating: ./certs/my-kibana/
  inflating: ./certs/my-kibana/my-kibana.crt
  inflating: ./certs/my-kibana/my-kibana.key
   creating: ./certs/logstash/
  inflating: ./certs/logstash/logstash.crt
  inflating: ./certs/logstash/logstash.key

检查node1的证书时,您将注意到 颁发者/签名权限为CN=MyExgroge Global CA。SUBJECT=我们在YAML中提供的名称,SAN有正确的DNS名称。我们已准备好了。

$ openssl x509 -text -noout -in certs/node1/node1.crt
...
        Issuer: CN=MyExample Global CA
        Validity
            Not Before: Sep 24 21:42:02 2017 GMT
            Not After : Sep 23 21:42:02 2020 GMT
        Subject: CN=node1
...
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                A0:26:83:23:A8:C6:FB:02:F3:7F:C9:BC:1A:C9:16:C9:04:62:3E:DE
            X509v3 Authority Key Identifier:
                keyid:8F:6C:8B:20:B3:7A:D9:18:31:9B:99:CC:8C:93:25:98:75:F4:4B:60
                DirName:/CN=MyExample Global CA
                serial:0C:0B:14:99:98:D6:7B:64:0D:00:03:64:B8:1F:7D:F7:9F:BF:6F:30
            X509v3 Subject Alternative Name:
                DNS:node1.local
            X509v3 Basic Constraints:
                CA:FALSE
...

要使用这些证书进行测试,我们需要解析DNS名称。我们可以修改/etc/host进行测试,但是在生产中您应该设置正确的DNS。/etc/host中127.0.0.1/localhost的行应该如下所示:

127.0.0.1 localhost node1.local node2.local kibana.local logstash.local

(测试完成后,请记住删除这些附加内容)

Elasticsearch TLS设置

在ElasticSearch配置文件夹中创建一个cert目录

$ cd ~/tmp/cert_blog/elasticsearch-6.0.0-beta2
$ mkdir config/certs

我们将启动两个节点,因此需要创建第二个配置文件夹

$ cp -r config config2

复制到ca.crt中,以及节点的私钥和公共证书中。

$ cp ~/tmp/cert_blog/ca/ca.crt ~/tmp/cert_blog/certs/node1/* config/certs
$ cp ~/tmp/cert_blog/ca/ca.crt ~/tmp/cert_blog/certs/node2/* config2/certs

配置Elasticsearch节点:

编辑config/elasticsearch.yml

node.name: node1
network.host: node1.local
xpack.ssl.key: certs/node1.key
xpack.ssl.certificate: certs/node1.crt
xpack.ssl.certificate_authorities: certs/ca.crt
xpack.security.transport.ssl.enabled: true
xpack.security.http.ssl.enabled: true
discovery.zen.ping.unicast.hosts: [ 'node1.local', 'node2.local']
node.max_local_storage_nodes: 2

edit config2/elasticsearch.yml

node.name: node2
network.host: node2.local
xpack.ssl.key: certs/node2.key
xpack.ssl.certificate: certs/node2.crt
xpack.ssl.certificate_authorities: certs/ca.crt
xpack.security.transport.ssl.enabled: true
xpack.security.http.ssl.enabled: true
discovery.zen.ping.unicast.hosts: [ 'node1.local', 'node2.local']
node.max_local_storage_nodes: 2

您将在上面的配置中注意到,network.host被设置为DNS名称。network.host是network.bind_host和network.publish_host的快捷方式。bind_host 控制是elasticsearch接口将能被使用,publish_host是告诉其他节点怎么与我们这个节点通信。这一点很重要,因为我们希望其他节点使用证书中设置的正确DNS名称进行连接,否则它们将因身份不匹配而拒绝连接。此外,发现使用DNS名称,因为该列表在初始启动阶段由节点使用,用于联系这些主机中的一个来发现/加入集群。此外,发现使用DNS名称,因为该列表在初始启动阶段由节点使用,用于联系这些主机中的一个来发现/加入集群。当这个新节点可以加入时,发现节点将返回集群中当前所有节点的列表(这是PUBLE_HOST发挥作用的地方)。

启动第一个节点

$ ES_PATH_CONF=config ./bin/elasticsearch

打开一个新的终端窗口,转到ElasticSearch文件夹,然后启动第二个节点

$ ES_PATH_CONF=config2 ./bin/elasticsearch

我们需要为各种系统帐户配置密码。在继续之前,确保两个节点都正确启动。您应该会看到类似于这条日志行的内容:

[2017-09-24T21:13:43,482][INFO ][o.e.n.Node               ] [node2] started

使用新的终端窗口,转到ElasticSearch文件夹

$ cd ~/tmp/cert_blog/elasticsearch-6.0.0-beta2
$ bin/x-pack/setup-passwords auto -u "https://node1.local:9200"
Initiating the setup of reserved user [elastic, kibana, logstash_system]  passwords.
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 elastic
PASSWORD elastic = #q^4uL*tIO@Sk~%iPwg*
Changed password for user kibana
PASSWORD kibana = %uhWtQCN-9GNa52vot_h
Changed password for user logstash_system
PASSWORD logstash_system = #3vs5PZDBrWTIVnCgOCh

保存这些密码

现在,让我们看看集群中正确列出了两个节点(提示:将?v添加到URL的末尾以获取列名,请参见_cat  API文档)

$ curl --cacert ~/tmp/cert_blog/ca/ca.crt -u elastic 'https://node1.local:9200/_cat/nodes'
127.0.0.1 42 100 14 1.91   mdi * node1
127.0.0.1 39 100 14 1.91   mdi - node2

让我们将该请求发送到应该在端口9201上运行的第二个节点。

curl --cacert ~/tmp/cert_blog/ca/ca.crt -u elastic 'https://node1.local:9201/_cat/nodes'
curl: (51) SSL: certificate verification failed (result: 5)

啊,我们只是改变了端口而不是DNS名称。curl客户端不允许这样做,因为服务器的身份与它所呈现的证书不匹配。让我们纠正这一点,然后再为第二个节点使用正确的DNS名称。

$ curl --cacert ~/tmp/cert_blog/ca/ca.crt -u elastic 'https://node2.local:9201/_cat/nodes'
127.0.0.1 20 100 24 2.04   mdi - node2
127.0.0.1 43 100 24 2.04   mdi * node1

我们现在有一个工作的两个节点ElasticSearch集群。请记住,对于一些快速测试来说,两个节点是很好的,但是对于除了快速测试之外的任何东西,在使用两个节点时,必须正确地将最小minimum_master_node 设置为2。

Kibana TLS设置

从kibana文件夹中安装x-pack。

$ bin/kibana-plugin install x-pack

这一步需要几分钟。去喝一杯,这是你应得的。

接下来,在config目录中创建一个cert文件夹,并在certs中复制。

$ mkdir config/certs
$ cp ~/tmp/cert_blog/ca/ca.crt ~/tmp/cert_blog/certs/my-kibana/* config/certs

编辑config/kibana.yml。确保插入前面生成的正确的kibana用户密码。

server.name: "my-kibana"
server.host: "kibana.local"
server.ssl.enabled: true
server.ssl.certificate: config/certs/my-kibana.crt
server.ssl.key: config/certs/my-kibana.key
elasticsearch.url: "https://node1.local:9200"
elasticsearch.username: "kibana"
elasticsearch.password: "%uhWtQCN-9GNa52vot_h"
elasticsearch.ssl.certificateAuthorities: [ "config/certs/ca.crt" ]

启动Kibana。

$ bin/kibana

当Kibana启动后,在浏览器访问 https://kibana.local:5601 。您应该得到证书不受信任的错误。这是因为浏览器既不信任直接证书,也不信任签名授权。您可以将新创建的证书颁发机构添加/信任到您的OS/浏览器中,但根据您使用的OS/浏览器,这些步骤可能有所不同。我把这个留给你和谷歌去弄清楚。

3.png

暂时取消/继续通过证书错误,并使用弹性用户和自动生成的密码登录。登录后,单击Monitoring选项卡,您将看到ElasticSearch有2个节点,kibana有1个实例。

4.png

我们现在对ElasticSearch和kibana通信进行了加密,并使用DNS对证书进行了完全验证。

在继续之前,让我们使用UI来设置logstash可以用来写到ElasticSearch的帐户。

Click on the management tab

5.png

我们将需要设置一个角色,该角色将授予日志存储配置所需的必要权限。

点击Role

6.png

点击创建角色

7.png

如下图所示创建角色并单击“保存”。

8.png

现在,我们将把这个角色分配给一个新用户。

点击User tab

9.png

点击创建用户

10.png

填写所有细节,如下图所示。这封电子邮件可以是任何你想要的,它不只是使用在ElasticSearch中有一个联系记录。分配新创建的logstash_Writer角色,然后单击Save。

11.png

Logstash TLS设置

安装Logstash的TLS并不需要X-Pack,但是我们将安装/使用它,因为它将允许我们查看Kibana监视UI中的日志存储信息-这是非常棒的。

From the logstash folder run

$ bin/logstash-plugin install x-pack

我们需要在config文件夹中创建一个certs目录,并在证书中复制。

$ mkdir config/certs
$ cp ~/tmp/cert_blog/ca/ca.crt ~/tmp/cert_blog/certs/logstash/* config/certs

logstash-输入-拍插件要求私钥为pkcs 8格式。下面的OpenSSL命令将生成一个pkcs 8格式的新文件。

$ openssl pkcs8 -in config/certs/logstash.key -topk8 -nocrypt -out config/certs/logstash.pkcs8.key

编辑config/logstash.yml。确保为logstash_system用户插入正确的自动生成密码。

node.name: logstash.local
xpack.monitoring.elasticsearch.username: logstash_system
xpack.monitoring.elasticsearch.password: '#3vs5PZDBrWTIVnCgOCh'
xpack.monitoring.elasticsearch.url: https://node1.local:9200
xpack.monitoring.elasticsearch.ssl.ca: config/certs/ca.crt

创建config/example.conf。对于ElasticSearch输出配置,用户和密码将使用您刚才在kibanaUI中创建的logstash_Writer帐户。

input {
  beats {
    port => 5044
    ssl => true
    ssl_key => 'config/certs/logstash.pkcs8.key'
    ssl_certificate => 'config/certs/logstash.crt'
  }
}
output {
  elasticsearch {
    hosts => ["https://node1.local:9200","https://node2.local:9201"]
    cacert => 'config/certs/ca.crt'
    user => 'logstash_writer'
    password => 'changeme'
    index => 'logstash-%{+YYYY.MM.dd}'
  }
}

使用示例配置启动logstash。

$ bin/logstash -f config/example.conf

在它启动和运行之后,访问Kibana监视页面现在将有一个日志存储部分,其中有一个节点和一个管道!

12.png

Filebeat TLS 设置

在FileBeat文件夹中,创建一个certs目录,并在CA cert中复制。我们只需要签名权限,因为FileBeat只会是一个与Logstash服务器对话的客户端。如果您想要某种形式的互操作,可以将Filebeat配置为还提供客户端证书,但这是另一天的主题。

$ mkdir certs
$ cp ~/tmp/cert_blog/ca/ca.crt certs

我们需要一个测试日志来配置FileBeat来读取。如果您在某个地方已经有一个日志文件,您可以跳过这一步,只需输入到该日志文件的正确路径即可。如果没有,请下载示例日志并将其解压缩到FileBeat目录中。

Create example-filebeat.yml:

filebeat.prospectors:
- type: log
  paths:
    - logstash-tutorial-dataset
output.logstash:
  hosts: ["logstash.local:5044"]
  ssl.certificate_authorities:
    - certs/ca.crt

然后使用此配置运行FileBeat:

$ ./filebeat -e -c example-filebeat.yml

现在,您可以访问Kibana发现页面,并单击“Create”按钮以获得新的索引模式。索引模式用于选择logstash-*命名索引进行搜索。

13.png

我们现在应该在KibanaUI中有日志数据!这些数据是从FileBeat->Logstash->Elasticearch传输的。Kibana把它从ElasticSearch中取出,加密后传送给你的浏览器。哇哈!

14.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章