基本安全加上安全的 HTTPS 流量
-
在生产环境中,除非您在 HTTP 层启用 TLS,否则某些 Elasticsearch 功能(例如令牌和 API 密钥)将被禁用。这个额外的安全层确保进出集群的所有通信都是安全的。
-
当您在模式下运行该elasticsearch-certutil工具时http,该工具会询问几个有关您希望如何生成证书的问题。虽然有许多选项,但以下选项会生成适用于大多数环境的证书。
-
该elasticsearch-certutil工具提示您的第一个问题是您是否要生成证书签名请求 (CSR)。回答 n您是要签署自己的证书,还是y要签署中央 CA 的证书。
- 签署自己的证书
- 如果您想使用您自已生成的CA证书 。 回答 n,当系统询问您是否要生成 CSR 时。然后指定 CA 证书的位置,即由该工具签署和生成证书.p12。
- 使用中央 CA 签署证书
- 如果您在中央安全团队的环境中工作,他们可能会为您生成证书。您组织内的基础设施可能已经配置为信任现有的 CA,因此如果您使用 CSR 并将该请求发送给控制您的 CA 的团队,则客户端可能更容易连接到 Elasticsearch。要使用中央 CA,请回答y第一个问题。
先决条件
- 完成为 Elastic Stack 设置基本安全性中的所有步骤。请参考以下文档:
Elasticsearch 设置基本安全性
为 Elasticsearch 加密 HTTP 客户端通信
- 在集群中的每个节点 上,停止 Elasticsearch 和 Kibana(如果它们正在运行)。
root@ubuntu-x64_02:/usr/local/elasticsearch9201# systemctl stop elasticsearch9201
root@ubuntu-x64_02:/usr/local/elasticsearch9201# systemctl stop elasticsearch9202
root@ubuntu-x64_02:/usr/local/elasticsearch9201# systemctl stop elasticsearch9203
-
在任何单个节点上,从您安装 Elasticsearch 的目录运行 Elasticsearch HTTP 证书工具以生成证书签名请求 (CSR)。
-
此命令生成一个.zip文件,其中包含用于 Elasticsearch 和 Kibana 的证书和密钥。每个文件夹都包含一个README.txt 说明如何使用这些文件。
root@ubuntu-x64_02:/usr/local/elasticsearch9201#./bin/elasticsearch-certutil http
- 当系统询问您是否要生成 CSR 时,请输入: n
## Do you wish to generate a Certificate Signing Request (CSR)?
A CSR is used when you want your certificate to be created by an existing
Certificate Authority (CA) that you do not control (that is, you do not have
access to the keys for that CA).
If you are in a corporate environment with a central security team, then you
may have an existing Corporate CA that can generate your certificate for you.
Infrastructure within your organisation may already be configured to trust this
CA, so it may be easier for clients to connect to Elasticsearch if you use a
CSR and send that request to the team that controls your CA.
If you choose not to generate a CSR, this tool will generate a new certificate
for you. That certificate will be signed by a CA under your control. This is a
quick and easy way to secure your cluster with TLS, but you will need to
configure all your clients to trust that custom CA.
Generate a CSR? [y/N]N
- 当系统询问您是否要使用现有 CA 时,请输入: y
## Do you have an existing Certificate Authority (CA) key-pair that you wish to use to sign your certificate?
If you have an existing CA certificate and key, then you can use that CA to
sign your new http certificate. This allows you to use the same CA across
multiple Elasticsearch clusters which can make it easier to configure clients,
and may be easier for you to manage.
If you do not have an existing CA, one will be generated for you.
Use an existing CA? [y/N]y
- 输入您的 CA 的路径。elastic-stack-ca.p12 这是您为集群生成的文件 的绝对路径。如: /usr/local/elasticsearch9201/elastic-stack-ca.p12
- 输入您的 CA 的密码。如果没有,则为空,在这种情况下,您只需在提示符下按ENTER键
## What is the path to your CA?
Please enter the full pathname to the Certificate Authority that you wish to
use for signing your new http certificate. This can be in PKCS#12 (.p12), JKS
(.jks) or PEM (.crt, .key, .pem) format.
CA Path: /usr/local/elasticsearch9201/elastic-stack-ca.p12
Reading a PKCS12 keystore requires a password.
It is possible for the keystore is password to be blank,
in which case you can simply press <ENTER> at the prompt
Password for elastic-stack-ca.p12:
- 输入证书的到期值。您可以: 以年、月或日为单位输入有效期。例如,输入90D
## How long should your certificates be valid?
Every certificate has an expiry date. When the expiry date is reached clients
will stop trusting your certificate and TLS connections will fail.
Best practice suggests that you should either:
(a) set this to a short duration (90 - 120 days) and have automatic processes
to generate a new certificate before the old one expires, or
(b) set it to a longer duration (3 - 5 years) and then perform a manual update
a few months before it expires.
You may enter the validity period in years (e.g. 3Y), months (e.g. 18M), or days (e.g. 90D)
For how long should your certificate be valid? [5y] 3Y
- 当系统询问您是否要为每个节点生成一个证书时,输入Y , 每个证书都有自己的私钥,并针对特定的主机名或 IP 地址颁发
## Do you wish to generate one certificate per node?
If you have multiple nodes in your cluster, then you may choose to generate a
separate certificate for each of these nodes. Each certificate will have its
own private key, and will be issued for a specific hostname or IP address.
Alternatively, you may wish to generate a single certificate that is valid
across all the hostnames or addresses in your cluster.
If all of your nodes will be accessed through a single domain
(e.g. node01.es.example.com, node02.es.example.com, etc) then you may find it
simpler to generate one certificate with a wildcard hostname (*.es.example.com)
and use that across all of your nodes.
However, if you do not have a common domain name, and you expect to add
additional nodes to your cluster in the future, then you should generate a
certificate per node so that you can more easily generate new certificates when
you provision new nodes.
Generate a certificate per node? [y/N]Y
- 出现提示时,输入集群中第一个节点的名称。使用生成节点证书时使用的相同节点名称。
## What is the name of node #1?
This name will be used as part of the certificate file name, and as a
descriptive name within the certificate.
You can use any descriptive name that you like, but we recommend using the name
of the Elasticsearch node.
node #1 name: node-1
- 输入用于连接到您的第一个节点的所有主机名。这些主机名将作为 DNS 名称添加到证书的主题备用名称 (SAN) 字段中。
## Which hostnames will be used to connect to node-1?
These hostnames will be added as "DNS" names in the "Subject Alternative Name"
(SAN) field in your certificate.
You should list every hostname and variant that people will use to connect to
your cluster over http.
Do not list IP addresses here, you will be asked to enter them later.
If you wish to use a wildcard certificate (for example *.es.example.com) you
can enter that here.
Enter all the hostnames that you need, one per line.
When you are done, press <ENTER> once more to move on to the next step.
node-1.es.example.com
You entered the following hostnames.
- node-1.es.example.com
Is this correct [Y/n]Y
- 输入客户端可用于连接到您的节点的 IP 地址。这里使用本地回环地址
## Which IP addresses will be used to connect to node-1?
If your clients will ever connect to your nodes by numeric IP address, then you
can list these as valid IP "Subject Alternative Name" (SAN) fields in your
certificate.
If you do not have fixed IP addresses, or not wish to support direct IP access
to your cluster then you can just press <ENTER> to skip this step.
Enter all the IP addresses that you need, one per line.
When you are done, press <ENTER> once more to move on to the next step.
127.0.0.1
You entered the following IP addresses.
- 127.0.0.1
Is this correct [Y/n]Y
- 对集群中的每个附加节点重复这些步骤。
- 为每个节点生成证书后,在出现提示时输入私钥密码。或直接回车为空。
## What password do you want for your private key(s)?
Your private key(s) will be stored in a PKCS#12 keystore file named "http.p12".
This type of keystore is always password protected, but it is possible to use a
blank password.
If you wish to use a blank password, simply press <enter> at the prompt below.
Provide a password for the "http.p12" file: [<ENTER> for none]
- 默认保存到当前目录
## Where should we save the generated files?
A number of files will be generated including your private key(s),
public certificate(s), and sample configuration options for Elastic Stack products.
These files will be included in a single zip archive.
What filename should be used for the output zip file? [/usr/local/elasticsearch9201/elasticsearch-ssl-http.zip]
Zip file written to /usr/local/elasticsearch9201/elasticsearch-ssl-http.zip
- 解压生成的 elasticsearch-ssl-http.zip 文件。这个压缩文件包含一个用于 Elasticsearch 和 Kibana 的目录。
root@ubuntu-x64_02:/usr/local/elasticsearch9201# unzip elasticsearch-ssl-http.zip
Archive: elasticsearch-ssl-http.zip
creating: elasticsearch/
creating: elasticsearch/node-1/
inflating: elasticsearch/node-1/README.txt
inflating: elasticsearch/node-1/http.p12
inflating: elasticsearch/node-1/sample-elasticsearch.yml
creating: elasticsearch/node-2/
inflating: elasticsearch/node-2/README.txt
inflating: elasticsearch/node-2/http.p12
inflating: elasticsearch/node-2/sample-elasticsearch.yml
creating: elasticsearch/node-3/
inflating: elasticsearch/node-3/README.txt
inflating: elasticsearch/node-3/http.p12
inflating: elasticsearch/node-3/sample-elasticsearch.yml
creating: kibana/
inflating: kibana/README.txt
inflating: kibana/elasticsearch-ca.pem
inflating: kibana/sample-kibana.yml
- 查看证书生成目录 : es 节点证书
root@ubuntu-x64_02:/usr/local/elasticsearch9201# tree elasticsearch
elasticsearch
├── node-1
│ ├── http.p12
│ ├── README.txt
│ └── sample-elasticsearch.yml
├── node-2
│ ├── http.p12
│ ├── README.txt
│ └── sample-elasticsearch.yml
└── node-3
├── http.p12
├── README.txt
└── sample-elasticsearch.yml
3 directories, 9 files
- 查看证书生成目录 : kibana 证书
root@ubuntu-x64_02:/usr/local/elasticsearch9201# tree kibana/
kibana/
├── elasticsearch-ca.pem
├── README.txt
└── sample-kibana.yml
0 directories, 3 files
- 在集群中的每个节点上,完成以下步骤:
- 将相关http.p12证书复制到$ES_PATH_CONF目录中。
root@ubuntu-x64_02:/usr/local/elasticsearch9201# cp elasticsearch/node-1/http.p12 /usr/local/elasticsearch9201/config/
root@ubuntu-x64_02:/usr/local/elasticsearch9201# cp elasticsearch/node-2/http.p12 /usr/local/elasticsearch9202/config/
root@ubuntu-x64_02:/usr/local/elasticsearch9201# cp elasticsearch/node-3/http.p12 /usr/local/elasticsearch9203/config/
- 编辑该elasticsearch.yml文件以启用 HTTPS 安全并指定安全证书的位置http.p12。
cat >> /usr/local/elasticsearch9201/config/elasticsearch.yml <<EOF
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: http.p12
EOF
cat >> /usr/local/elasticsearch9202/config/elasticsearch.yml <<EOF
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: http.p12
EOF
cat >> /usr/local/elasticsearch9203/config/elasticsearch.yml <<EOF
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: http.p12
EOF
- 将您的私钥密码添加到 Elasticsearch 的安全设置中。
root@ubuntu-x64_02:/usr/local/elasticsearch9201# cd /usr/local/elasticsearch9201; ./bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password
Enter value for xpack.security.http.ssl.keystore.secure_password:
root@ubuntu-x64_02:/usr/local/elasticsearch9201# cd /usr/local/elasticsearch9202; ./bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password
Enter value for xpack.security.http.ssl.keystore.secure_password:
root@ubuntu-x64_02:/usr/local/elasticsearch9202# cd /usr/local/elasticsearch9203; ./bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password
Enter value for xpack.security.http.ssl.keystore.secure_password:
- 修改文件 权限
root@ubuntu-x64_02:/usr/local/elasticsearch9203# chown -R elk:elk /usr/local/elasticsearch9201
root@ubuntu-x64_02:/usr/local/elasticsearch9203# chown -R elk:elk /usr/local/elasticsearch9202
root@ubuntu-x64_02:/usr/local/elasticsearch9203# chown -R elk:elk /usr/local/elasticsearch9203
- 启动 Elasticsearch.
root@ubuntu-x64_02:/usr/local/elasticsearch9203# systemctl start elasticsearch9201
root@ubuntu-x64_02:/usr/local/elasticsearch9203# systemctl start elasticsearch9202
root@ubuntu-x64_02:/usr/local/elasticsearch9203# systemctl start elasticsearch9203
- 添加 hosts 解释
root@ubuntu-x64_02:/usr/local/elasticsearch9203# echo "127.0.0.1 node-1.es.example.com" >> /etc/hosts
root@ubuntu-x64_02:/usr/local/elasticsearch9203# echo "127.0.0.1 node-2.es.example.com" >> /etc/hosts
root@ubuntu-x64_02:/usr/local/elasticsearch9203# echo "127.0.0.1 node-3.es.example.com" >> /etc/hosts
- 使用 -k 选项,不较验 CA 证书 , 否则会 导致无法验证问题
root@ubuntu-x64_02:/usr/local/elasticsearch9201# curl -k -u elastic:123456 https://node-1.es.example.com:9201/_cat/nodes/?v;
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
127.0.0.1 56 97 6 0.28 0.14 0.21 cdfhilmrstw - node-1
127.0.0.1 48 97 6 0.28 0.14 0.21 cdfhilmrstw - node-3
127.0.0.1 63 97 6 0.28 0.14 0.21 cdfhilmrstw * node-2
为 Kibana 加密 HTTP 客户端通信
- 浏览器将流量发送到 Kibana,而 Kibana 将流量发送到 Elasticsearch。这些通信通道被单独配置为使用 TLS。您加密浏览器和 Kibana 之间的流量,然后加密 Kibana 和 Elasticsearch 之间的流量。
加密 Kibana 和 Elasticsearch 之间的流量
- 当您使用该选项运行该elasticsearch-certutil工具时http,它会创建一个/kibana包含elasticsearch-ca.pem文件的目录。您使用此文件将 Kibana 配置为信任 HTTP 层的 Elasticsearch CA。
- 将文件复制elasticsearch-ca.pem到 Kibana 配置目录,如路径所定义$KBN_PATH_CONF。
root@ubuntu-x64_02:/usr/local/elasticsearch9201# cp kibana/elasticsearch-ca.pem /usr/local/kibana/config/
- 打开kibana.yml并添加以下行以指定 HTTP 层的安全证书的位置。
cat >> /usr/local/kibana/config/kibana.yml <<EOF
elasticsearch.ssl.certificateAuthorities: /usr/local/kibana/config/elasticsearch-ca.pem
EOF
- 添加以下行以指定 Elasticsearch 集群的 HTTPS URL。
root@ubuntu-x64_02:/usr/local/elasticsearch9201# cat /usr/local/kibana/config/kibana.yml| grep "elasticsearch.hosts"
elasticsearch.hosts: ["https://127.0.0.1:9201" ,"https://127.0.0.1:9202" ,"https://127.0.0.1:9203"]
- 修改权限
root@ubuntu-x64_02:/usr/local/elasticsearch9201# chown -R elk:elk /usr/local/kibana
- 重启 kibana
root@ubuntu-x64_02:/usr/local/elasticsearch9201# systemctl restart kibana.service
加密浏览器和 Kibana 之间的流量
-
Kibana 为您创建服务器证书和私钥。Kibana 在从 Web 浏览器接收连接时使用此服务器证书和相应的私钥。
-
以下为 Kibana 创建证书签名请求 (CSR)。CSR 包含 CA 用于生成和签署安全证书的信息。证书可以是受信任的(由公共、受信任的 CA 签名)或不受信任的(由内部 CA 签名)。自签名或内部签名证书可用于开发环境和构建概念验证,但不应在生产环境中使用。
-
在投入生产之前,使用受信任的 CA(例如Let’s Encrypt)或您组织的内部 CA 来签署证书。使用签名证书建立浏览器信任以连接到 Kibana 以进行内部访问或在公共互联网上访问。
-
为 Kibana 生成服务器证书和私钥。
root@ubuntu-x64_02:/usr/local/elasticsearch9201# ./bin/elasticsearch-certutil csr -name kibana-server -dns kibana.example.com
- 解压缩csr-bundle.zip文件以获得kibana-server.csr未签名的安全证书和kibana-server.key未加密的私钥。
root@ubuntu-x64_02:/usr/local/elasticsearch9201# unzip csr-bundle.zip
Archive: csr-bundle.zip
creating: kibana-server/
inflating: kibana-server/kibana-server.csr
inflating: kibana-server/kibana-server.key
- 将证书kibana-server.csr签名请求发送给您的内部 CA 或受信任的 CA 进行签名以获得签名证书。签名文件可以是不同的格式,.crt 例如: kibana-server.crt.
- 使用自签CA生成证书签名
root@ubuntu-x64_02:/usr/local/elasticsearch9201# tree kibana-server/
kibana-server/
├── kibana-server.crt
├── kibana-server.csr
└── kibana-server.key
0 directories, 3 files
- 打开kibana.yml并添加以下行以配置 Kibana 以访问服务器证书和未加密的私钥。
root@ubuntu-x64_02:/usr/local/elasticsearch9201# cp ./kibana-server/kibana-server.crt /usr/local/kibana/config/
root@ubuntu-x64_02:/usr/local/elasticsearch9201# cp ./kibana-server/kibana-server.key /usr/local/kibana/config/
cat >> /usr/local/kibana/config/kibana.yml <<EOF
server.ssl.certificate: /usr/local/kibana/config/kibana-server.crt
server.ssl.key: /usr/local/kibana/config/kibana-server.key
EOF
# 目录结构
root@ubuntu-x64_02:/usr/local/elasticsearch9201# ls -tlh /usr/local/kibana/config/
total 44K
-rw-r--r-- 1 root root 989 Mar 23 15:24 kibana-server.crt
-rw-r--r-- 1 elk elk 5.5K Mar 23 15:20 kibana.yml
-rw-r--r-- 1 elk elk 1.7K Mar 23 14:56 kibana-server.key
-rw-r--r-- 1 elk elk 1.2K Mar 22 18:04 elasticsearch-ca.pem
-rw-r--r-- 1 elk elk 190 Mar 20 19:20 kibana.keystore
-rw-r--r-- 1 elk elk 5.2K Mar 20 17:26 kibana.yml.bak
-rwxr-xr-x 1 elk elk 5.2K Jul 9 2022 kibana.yml_20220709073134.bak
-rwxr-xr-x 1 elk elk 216 Jul 9 2022 node.options
- kibana.yml添加以下行入站连接启用 TLS
cat >> /usr/local/kibana/config/kibana.yml <<EOF
server.ssl.enabled: true
EOF
# 修改权限
root@ubuntu-x64_02:/usr/local/elasticsearch9201# chown -R elk:elk /usr/local/kibana
- 进行这些更改后,您必须始终通过 HTTPS 访问 Kibana。例如,https://<your_kibana_host>.com。
server.publicBaseUrl: "https://192.168.88.12:5601"
- 启动 kibana
root@ubuntu-x64_02:/usr/local/elasticsearch9201# systemctl restart kibana.service
- 检查状态
root@ubuntu-x64_02:/usr/local/elasticsearch9201# systemctl status kibana.service
● kibana.service - kibana
Loaded: loaded (/lib/systemd/system/kibana.service; disabled; vendor preset: enabled)
Active: active (running) since Thu 2023-03-23 15:26:50 CST; 6s ago
Process: 4306 ExecStop=/usr/bin/kill -15 $MAINPID (code=exited, status=203/EXEC)
Main PID: 4312 (node)
Tasks: 18
Memory: 200.5M
CPU: 6.855s
CGroup: /system.slice/kibana.service
├─4312 /usr/local/kibana/bin/../node/bin/node /usr/local/kibana/bin/../src/cli/dist
└─4325 /usr/local/kibana/node/bin/node --preserve-symlinks-main --preserve-symlinks /usr/local/kibana/src/cli/dist
Mar 23 15:26:50 ubuntu-x64_02 systemd[1]: kibana.service: Unit entered failed state.
Mar 23 15:26:50 ubuntu-x64_02 systemd[1]: kibana.service: Failed with result 'exit-code'.
Mar 23 15:26:50 ubuntu-x64_02 systemd[1]: Started kibana.
- 登录 kibana ,输入 elastic:123456登录密码,由于CA是自签,浏览器会提示未验证,开发环境可以使用
小结
- 此方案建立在基本安全方案的基础上,并使用 TLS 保护所有 HTTP 流量。除了在 Elasticsearch 集群的传输接口上配置 TLS 之外,您还可以在 Elasticsearch 和 Kibana 的 HTTP 接口上配置 TLS。如果您需要 HTTP 层上的双向(双向)TLS,则需要配置相互验证的加密。