9.5 TLS SSL 加密


文档摘要

9.5 TLS/SSL 加密 Elasticsearch 安全领域:9.5 TLS/SSL 加密详解与实践 在 Elasticsearch 安全体系中,传输层安全(TLS/SSL)加密扮演着至关重要的角色。它为 Elasticsearch 集群节点之间、客户端与集群之间的通信提供了安全保障,防止数据在传输过程中被窃听或篡改。本篇文章将深入探讨 Elasticsearch 中 TLS/SSL 加密的配置、实践以及相关原理,帮助你全面理解并有效地应用这项安全技术。 TLS/SSL 加密的重要性 在分布式系统中,数据安全至关重要。Elasticsearch 集群通常处理敏感数据,例如用户日志、交易信息、安全事件等等。

9.5 TLS/SSL 加密

Elasticsearch 安全领域:9.5 TLS/SSL 加密详解与实践

在 Elasticsearch 安全体系中,传输层安全(TLS/SSL)加密扮演着至关重要的角色。它为 Elasticsearch 集群节点之间、客户端与集群之间的通信提供了安全保障,防止数据在传输过程中被窃听或篡改。本篇文章将深入探讨 Elasticsearch 中 TLS/SSL 加密的配置、实践以及相关原理,帮助你全面理解并有效地应用这项安全技术。

1. TLS/SSL 加密的重要性

在分布式系统中,数据安全至关重要。Elasticsearch 集群通常处理敏感数据,例如用户日志、交易信息、安全事件等等。如果不对集群通信进行加密,数据在网络中以明文形式传输,将面临以下风险:

  • 数据泄露: 攻击者可以监听网络流量,窃取敏感数据,造成信息泄露和经济损失。

  • 数据篡改: 攻击者可以篡改传输中的数据,破坏数据完整性,导致系统运行异常或决策失误。

  • 中间人攻击: 攻击者可以冒充集群节点或客户端,拦截并篡改通信内容,甚至获取控制权。

TLS/SSL 加密通过以下机制来解决这些安全问题:

  • 加密: 使用加密算法对传输数据进行加密,确保只有授权方才能解密,保护数据 confidentiality(机密性)。

  • 认证: 通过数字证书验证通信双方的身份,防止中间人攻击和身份冒充,实现 authentication(身份验证)。

  • 完整性: 使用消息摘要算法确保数据在传输过程中未被篡改,保证 data integrity(数据完整性)。

因此,在生产环境中,强烈建议为 Elasticsearch 集群启用 TLS/SSL 加密,构建安全可靠的 Elasticsearch 系统。

2. TLS/SSL 加密核心概念

在深入 Elasticsearch 的 TLS/SSL 配置之前,我们需要了解一些核心概念:

  • 对称加密与非对称加密:

    • 对称加密: 加密和解密使用相同的密钥。速度快,但密钥分发困难。例如:AES, DES。

    • 非对称加密: 加密和解密使用不同的密钥,分为公钥和私钥。公钥可以公开,私钥必须保密。解决密钥分发问题,但速度较慢。例如:RSA, ECC。

  • 数字证书 (X.509 Certificate): 用于证明身份的电子文档,包含公钥、证书持有者信息、证书颁发机构 (CA) 信息、有效期等。符合 X.509 标准。

  • 证书颁发机构 (Certificate Authority, CA): 受信任的第三方机构,负责颁发和管理数字证书。例如:Let's Encrypt, Verisign。

  • 密钥对 (Key Pair): 由一个公钥和一个私钥组成,用于非对称加密。公钥用于加密或验证签名,私钥用于解密或生成签名。

  • 握手协议 (Handshake Protocol): TLS/SSL 连接建立过程,通信双方协商加密算法、交换密钥、验证身份,最终建立安全连接。

下图使用 Mermaid 图展示了简化的 TLS/SSL 握手过程:

流程简述:

  1. Client Hello: 客户端发送 Client Hello 消息,包含客户端支持的 TLS 版本、密码套件列表等信息。

  2. Server Hello: 服务器收到 Client Hello 后,回复 Server Hello 消息,选择 TLS 版本和密码套件。

  3. Certificate (Server): 服务器将自己的数字证书发送给客户端,证明服务器身份。

  4. Server Key Exchange & Server Hello Done: 服务器发送密钥交换参数 (取决于选择的密钥交换算法) 并发送 Server Hello Done 消息,表示服务器端握手信息发送完毕。

  5. Client Key Exchange, Change Cipher Spec, Finished: 客户端验证服务器证书,生成会话密钥,并将密钥交换参数发送给服务器,然后发送 Change Cipher Spec 消息告知服务器后续报文将使用加密,最后发送 Finished 消息完成客户端握手。

  6. Change Cipher Spec, Finished: 服务器收到客户端的密钥交换参数后,计算出会话密钥,发送 Change Cipher Spec 和 Finished 消息完成服务器端握手。

  7. Application Data: 握手完成后,客户端和服务器之间就可以使用加密的通道进行应用数据传输。

3. 在 Elasticsearch 中启用 TLS/SSL 加密

Elasticsearch 支持在以下两个层面启用 TLS/SSL 加密:

  • 传输层 (Transport Layer): 用于节点间通信 (集群内部通信) 和客户端与节点之间的通信。

  • HTTP 层 (HTTP Layer): 用于客户端通过 HTTP REST API 与 Elasticsearch 交互。

3.1 配置传输层 TLS/SSL 加密

要启用传输层 TLS/SSL 加密,需要在 elasticsearch.yml 配置文件中进行配置。以下是关键配置项:

  • xpack.security.transport.ssl.enabled: true: 启用传输层 SSL/TLS 加密。

  • xpack.security.transport.ssl.keystore.path: 指定 Java Keystore (JKS) 文件的路径,该文件包含节点的私钥和证书。

  • xpack.security.transport.ssl.keystore.password: Keystore 文件的密码。

  • xpack.security.transport.ssl.truststore.path: 指定 Java Truststore (JKS) 文件的路径,该文件包含受信任的 CA 证书,用于验证其他节点的证书。

  • xpack.security.transport.ssl.truststore.password: Truststore 文件的密码。

  • xpack.security.transport.ssl.client_authentication: 配置客户端身份验证模式,可选值:

    • none: 不要求客户端提供证书进行身份验证 (默认值)。

    • optional: 如果客户端提供证书,则进行验证,否则不进行验证。

    • required: 强制客户端提供证书进行身份验证。

  • xpack.security.transport.ssl.supported_protocols: 指定支持的 TLS/SSL 协议版本,例如 [ "TLSv1.2", "TLSv1.3" ]。 推荐使用 TLSv1.2 或以上版本。

  • xpack.security.transport.ssl.cipher_suites: 指定支持的密码套件列表,例如 [ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_256_CBC_SHA256" ]。 可以根据安全需求和性能考虑进行选择。

示例 elasticsearch.yml 配置 (传输层 TLS/SSL 加密):

xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.keystore.path: /path/to/node.jks xpack.security.transport.ssl.keystore.password: keystore_password xpack.security.transport.ssl.truststore.path: /path/to/truststore.jks xpack.security.transport.ssl.truststore.password: truststore_password xpack.security.transport.ssl.client_authentication: required xpack.security.transport.ssl.supported_protocols: [ "TLSv1.2", "TLSv1.3" ] xpack.security.transport.ssl.cipher_suites: [ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_256_CBC_SHA256" ]

注意:

  • 你需要为每个 Elasticsearch 节点配置独立的 Keystore 和 Truststore 文件。

  • Keystore 文件应包含节点的私钥和证书,Truststore 文件应包含受信任的 CA 证书。

  • 路径 /path/to/node.jks/path/to/truststore.jks 需要替换为实际的文件路径。

  • 密码 keystore_passwordtruststore_password 需要替换为实际的密码。

3.2 配置 HTTP 层 TLS/SSL 加密

HTTP 层 TLS/SSL 加密配置与传输层类似,也在 elasticsearch.yml 中进行配置。以下是关键配置项:

  • xpack.security.http.ssl.enabled: true: 启用 HTTP 层 SSL/TLS 加密。

  • xpack.security.http.ssl.keystore.path: 指定 HTTP 层使用的 Keystore 文件路径。

  • xpack.security.http.ssl.keystore.password: HTTP 层 Keystore 文件的密码。

  • xpack.security.http.ssl.truststore.path: 指定 HTTP 层使用的 Truststore 文件路径。

  • xpack.security.http.ssl.truststore.password: HTTP 层 Truststore 文件的密码。

  • xpack.security.http.ssl.client_authentication: HTTP 层客户端身份验证模式,可选值同传输层。

  • xpack.security.http.ssl.supported_protocols: HTTP 层支持的 TLS/SSL 协议版本。

  • xpack.security.http.ssl.cipher_suites: HTTP 层支持的密码套件列表。

示例 elasticsearch.yml 配置 (HTTP 层 TLS/SSL 加密):

xpack.security.http.ssl.enabled: true xpack.security.http.ssl.keystore.path: /path/to/http.jks xpack.security.http.ssl.keystore.password: http_keystore_password xpack.security.http.ssl.truststore.path: /path/to/http_truststore.jks xpack.security.http.ssl.truststore.password: http_truststore_password xpack.security.http.ssl.client_authentication: none xpack.security.http.ssl.supported_protocols: [ "TLSv1.2", "TLSv1.3" ] xpack.security.http.ssl.cipher_suites: [ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_256_CBC_SHA256" ]

注意:

  • HTTP 层 TLS/SSL 配置可以与传输层 TLS/SSL 配置使用相同的 Keystore 和 Truststore 文件,也可以使用不同的文件。

  • 路径 /path/to/http.jks/path/to/http_truststore.jks 需要替换为实际的文件路径。

  • 密码 http_keystore_passwordhttp_truststore_password 需要替换为实际的密码。

4. 生成和管理 TLS/SSL 证书

为了启用 TLS/SSL 加密,你需要生成数字证书并配置到 Elasticsearch 中。Elasticsearch 提供了 elasticsearch-certutil 工具来简化证书生成和管理过程。

4.1 使用 elasticsearch-certutil 生成证书

elasticsearch-certutil 工具位于 Elasticsearch 的 bin 目录下。你可以使用它来生成 CA 证书、节点证书、客户端证书等。

1. 生成 CA 证书:

./elasticsearch-certutil ca --pem --out config/certs/ca

该命令会在 config/certs 目录下生成 ca.zip 文件,解压后包含 ca.crt (CA 证书) 和 ca.key (CA 私钥)。

2. 生成节点证书:

./elasticsearch-certutil cert --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key --pem --out config/certs/node --name node1,node2,node3

该命令会使用 CA 证书 (ca.crt) 和 CA 私钥 (ca.key) 为节点 node1, node2, node3 生成证书,并将结果保存到 config/certs/node.zip 文件中。解压后包含每个节点的证书和私钥文件。

3. 生成客户端证书 (可选,用于客户端身份验证):

./elasticsearch-certutil cert --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key --pem --out config/certs/client --name client1,client2

该命令会使用 CA 证书和 CA 私钥为客户端 client1, client2 生成证书,并将结果保存到 config/certs/client.zip 文件中。解压后包含每个客户端的证书和私钥文件。

4. 生成包含所有证书的 PKCS#12 Keystore 和 Truststore:

./elasticsearch-certutil keystore --certs config/certs/node/node1.crt,config/certs/node/node2.crt,config/certs/node/node3.crt --keys config/certs/node/node1.key,config/certs/node/node2.key,config/certs/node/node3.key --ca-cert config/certs/ca/ca.crt --p12 --out config/certs/elasticsearch.p12

该命令会将节点证书、私钥和 CA 证书打包到一个 PKCS#12 格式的 Keystore 文件 elasticsearch.p12 中。你可以使用 keytool 工具将 PKCS#12 转换为 JKS 格式,或者直接在 Elasticsearch 配置中使用 PKCS#12 格式。

5. 将证书转换为 JKS 格式 (可选):

keytool -importkeystore -srckeystore config/certs/elasticsearch.p12 -srcstoretype pkcs12 -destkeystore config/certs/elasticsearch.jks -deststoretype jks

注意:

  • --name 参数用于指定证书的通用名称 (Common Name, CN),通常设置为节点的 hostname 或 IP 地址。

  • --pem 参数表示生成 PEM 格式的证书和私钥文件。

  • --out 参数指定输出文件路径。

  • --ca-cert--ca-key 参数用于指定 CA 证书和私钥路径。

  • 你需要根据实际情况调整命令参数。

4.2 手动生成证书 (使用 openssl)

你也可以使用 openssl 等工具手动生成证书,但这过程相对复杂,容易出错,建议使用 elasticsearch-certutil。 这里仅简单介绍步骤:

  1. 生成 CA 私钥:

    openssl genrsa -out ca.key 2048
  2. 生成 CA 证书:

    openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt -subj "/C=CN/ST=Beijing/L=Beijing/O=Example Org/OU=Example OU/CN=Example CA"
  3. 生成节点私钥:

    openssl genrsa -out node.key 2048
  4. 生成证书签名请求 (CSR):

    openssl req -new -key node.key -out node.csr -subj "/C=CN/ST=Beijing/L=Beijing/O=Example Org/OU=Example OU/CN=node1"
  5. 使用 CA 证书和私钥签署节点证书:

    openssl x509 -req -in node.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out node.crt -days 365 -sha256
  6. 将证书和私钥转换为 JKS 格式 (使用 keytool)

注意:

  • 手动生成证书需要对 opensslkeytool 工具比较熟悉。

  • 证书的 Subject 信息需要根据实际情况进行设置。

  • 确保妥善保管 CA 私钥。

4.3 证书管理最佳实践

  • 使用 elasticsearch-certutil 工具: 尽可能使用 Elasticsearch 提供的 elasticsearch-certutil 工具来生成和管理证书,减少手动操作错误。

  • 保护私钥: 私钥是加密体系的核心,必须妥善保管,防止泄露。

  • 定期更新证书: 证书都有有效期,为了安全起见,需要定期更新证书,避免证书过期导致服务中断。

  • 使用强密码: 为 Keystore 和 Truststore 文件设置强密码,防止未经授权的访问。

  • 最小权限原则: 运行 Elasticsearch 进程的用户只需要读取 Keystore 和 Truststore 文件的权限,避免赋予过多的权限。

5. 配置客户端连接 TLS/SSL 加密

客户端 (例如 Elasticsearch Java Client, Python Client, Kibana, Logstash, Beats) 连接到 TLS/SSL 加密的 Elasticsearch 集群时,也需要进行相应的配置。

5.1 Java REST Client

使用 Java REST Client 连接 TLS/SSL 加密的 Elasticsearch 集群,需要配置 SSL 上下文,加载 Truststore 文件,并可选配置 Keystore 文件 (如果需要客户端身份验证)。

示例代码 (Java REST Client):

import org.apache.http.HttpHost; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.SSLContexts; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestClientBuilder; import javax.net.ssl.SSLContext; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; import java.security.KeyStore; public class ElasticsearchClientTLS { public static void main(String[] args) throws Exception { // 加载 Truststore KeyStore truststore = KeyStore.getInstance("JKS"); try (InputStream is = Files.newInputStream(Paths.get("/path/to/truststore.jks"))) { truststore.load(is, "truststore_password".toCharArray()); } // 构建 SSLContext SSLContextBuilder sslBuilder = SSLContexts.custom() .loadTrustMaterial(truststore, null); // 使用 Truststore 验证服务器证书 final SSLContext sslContext = sslBuilder.build(); // 构建 RestClient RestClientBuilder builder = RestClient.builder( new HttpHost("your_elasticsearch_host", 9200, "https")) // 使用 HTTPS 协议 .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder .setSSLContext(sslContext)); // 配置 SSLContext RestClient restClient = builder.build(); // 执行 Elasticsearch 操作 // ... restClient.close(); } }

注意:

  • /path/to/truststore.jks 需要替换为客户端 Truststore 文件的实际路径。

  • truststore_password 需要替换为 Truststore 文件的密码。

  • your_elasticsearch_host 需要替换为 Elasticsearch 集群节点的 hostname 或 IP 地址。

  • 端口 9200 为 Elasticsearch HTTP 默认端口。

5.2 Python Elasticsearch Client

Python Elasticsearch Client 同样需要配置 SSL 参数。

示例代码 (Python Elasticsearch Client):

from elasticsearch import Elasticsearch es = Elasticsearch( ['https://your_elasticsearch_host:9200'], # 使用 HTTPS 协议 ssl_assert_hostname=False, # 关闭主机名验证 (生产环境建议开启) ssl_show_warn=False, # 关闭 SSL 警告 ssl_verify=True, # 启用 SSL 证书验证 ca_certs="/path/to/truststore.crt" # 指定 Truststore 文件路径 ) # 执行 Elasticsearch 操作 # ... es.close()

注意:

  • https://your_elasticsearch_host:9200 需要替换为 Elasticsearch 集群节点的 HTTPS 地址。

  • /path/to/truststore.crt 需要替换为客户端 Truststore 证书文件的实际路径 (PEM 格式)。

  • ssl_assert_hostname=False 在生产环境中建议设置为 True 并配置正确的主机名,以防止中间人攻击。

5.3 Kibana

Kibana 连接 TLS/SSL 加密的 Elasticsearch 集群,需要在 kibana.yml 配置文件中进行配置。

示例 kibana.yml 配置:

elasticsearch.hosts: ["https://your_elasticsearch_host:9200"] # 使用 HTTPS 协议 elasticsearch.ssl.certificateAuthorities: ["/path/to/truststore.crt"] # 指定 Truststore 文件路径

5.4 Logstash 和 Beats

Logstash 和 Beats 也需要配置 SSL 参数才能连接 TLS/SSL 加密的 Elasticsearch 集群。 具体配置方式请参考 Logstash 和 Beats 的官方文档。

6. TLS/SSL 配置验证与故障排除

配置 TLS/SSL 加密后,需要进行验证,确保配置正确生效。

6.1 验证传输层 TLS/SSL

  • 查看 Elasticsearch 日志: 检查 Elasticsearch 启动日志,确认是否成功加载 Keystore 和 Truststore 文件,以及 TLS/SSL 是否成功启用。

  • 使用 curl 命令测试节点间连接: 在集群节点上使用 curl 命令连接其他节点,验证是否使用 TLS/SSL 加密。 例如:

    curl -v --cacert /path/to/truststore.crt https://your_elasticsearch_host:9300

    如果连接成功,并且在 curl 输出中看到 TLSv1.2TLSv1.3 等信息,则表示 TLS/SSL 加密已生效。

6.2 验证 HTTP 层 TLS/SSL

  • 使用浏览器或 curl 命令访问 Elasticsearch HTTP API: 使用浏览器或 curl 命令访问 Elasticsearch HTTP API 地址 (例如 https://your_elasticsearch_host:9200),验证是否使用 HTTPS 协议。

  • 检查浏览器地址栏: 浏览器地址栏中应该显示 https 协议,并且显示安全锁图标,表示连接已加密。

  • 使用 curl 命令测试 HTTP 连接:

    curl -v --cacert /path/to/truststore.crt https://your_elasticsearch_host:9200

    如果连接成功,并且在 curl 输出中看到 TLSv1.2TLSv1.3 等信息,则表示 HTTP 层 TLS/SSL 加密已生效。

6.3 常见故障排除

  • 证书路径错误: 检查 elasticsearch.yml 中配置的 Keystore 和 Truststore 文件路径是否正确。

  • 证书密码错误: 检查 Keystore 和 Truststore 密码是否正确。

  • 证书格式错误: 确保证书格式为 JKS 或 PKCS#12 (根据配置)。

  • Truststore 中缺少 CA 证书: 如果客户端无法连接到 Elasticsearch 集群,可能是客户端 Truststore 中缺少 Elasticsearch 集群使用的 CA 证书。

  • 协议版本或密码套件不匹配: 检查 Elasticsearch 和客户端配置的 TLS/SSL 协议版本和密码套件是否兼容。

7. 总结

TLS/SSL 加密是 Elasticsearch 安全体系中不可或缺的一部分。通过为传输层和 HTTP 层启用 TLS/SSL 加密,可以有效保护 Elasticsearch 集群的数据安全,防止数据泄露和篡改。

核心要点回顾:

  • 理解 TLS/SSL 加密的核心概念:对称加密、非对称加密、数字证书、CA、密钥对、握手协议。

  • 掌握 Elasticsearch 中传输层和 HTTP 层 TLS/SSL 加密的配置方法,包括 elasticsearch.yml 配置文件中的关键参数。

  • 学习使用 elasticsearch-certutil 工具生成和管理 TLS/SSL 证书。

  • 了解客户端 (Java REST Client, Python Client, Kibana) 连接 TLS/SSL 加密集群的配置方法。

  • 掌握 TLS/SSL 配置验证和故障排除方法。

希望本文能够帮助你深入理解 Elasticsearch TLS/SSL 加密,并在实际生产环境中安全可靠地部署 Elasticsearch 集群。 请务必根据你的具体安全需求和环境,仔细配置 TLS/SSL 加密,并定期进行安全审查和更新。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U