证书配置

配置 TLS 证书 #

Easysearch 可以通过启用 TLS 传输加密来保护您数据的网络传输安全。 TLS 的相关设置在配置文件 easysearch.yml 中进行,主要包括两个部分:传输层和 HTTP 层。

  • 传输层(Transport):节点之间的通信。传输层 TLS 是必需的(默认启用)。
  • HTTP 层:客户端与节点之间的通信。HTTP 层 TLS 是可选的(默认关闭)。

默认的配置如下:

security.ssl.transport.cert_file: instance.crt
security.ssl.transport.key_file: instance.key
security.ssl.transport.ca_file: ca.crt
security.ssl.http.enabled: true
security.ssl.http.cert_file: instance.crt
security.ssl.http.key_file: instance.key
security.ssl.http.ca_file: ca.crt

一键生成证书 #

启用 TLS 需要设置证书才能工作,通过执行命令 ./bin/initialize.sh 可以一键生成 TLS 证书,如下:

➨  ./bin/initialize.sh
Generating RSA private key, 2048 bit long modulus
.......................+++
...............................+++
e is 65537 (0x10001)
Generating RSA private key, 2048 bit long modulus
.......................................................................................................................................................................................+++
......................................................+++
e is 65537 (0x10001)
Signature ok
subject=/C=IN/ST=FI/L=NI/O=ORG/OU=UNIT/CN=infini.cloud
Getting CA Private Key
                DNS:infini.cloud, DNS:*.infini.cloud
➨  ls config
ca.crt                 easysearch.yml         instance.key           log4j2.properties
ca.key                 easysearch.yml.example jvm.options            security
easysearch.keystore    instance.crt           jvm.options.d

TLS 启用开关 #

名称描述默认值
security.ssl.transport.enabled是否启用传输层 TLS。true
security.ssl.http.enabled是否启用 HTTP 层 TLS。false

X.509 PEM 证书和 PKCS#8 密钥 #

下面是 Easysearch 使用 PEM 格式证书和 PKCS#8 私钥的详细参数说明。所有证书和密钥文件必须位于 config 目录下,使用相对路径指定。

传输层 TLS(PEM) #

名称描述
security.ssl.transport.key_file节点私钥文件(PKCS#8,PEM 格式)的路径。必填。
security.ssl.transport.key_secret私钥文件的密码。如果密钥没有密码保护,可忽略。选填。
security.ssl.transport.cert_file节点证书文件(PEM 格式)的路径。必填。
security.ssl.transport.ca_file根证书(CA)文件(PEM 格式)的路径。必填。

HTTP 层 TLS(PEM) #

名称描述
security.ssl.http.key_file节点私钥文件(PKCS#8,PEM 格式)的路径。必填。
security.ssl.http.key_secret私钥文件的密码。如果密钥没有密码保护,可忽略。选填。
security.ssl.http.cert_file节点证书文件(PEM 格式)的路径。必填。
security.ssl.http.ca_file根证书(CA)文件(PEM 格式)的路径。必填。

JKS/PKCS12 Keystore 和 Truststore #

除了 PEM 格式,Easysearch 还支持使用 JKS 或 PKCS12 格式的 Keystore 和 Truststore 来存储证书和密钥。所有 Keystore/Truststore 文件必须位于 config 目录下,使用相对路径指定。

注意: PEM 格式和 Keystore 格式是互斥的,每一层只能选择其中一种方式配置证书。

传输层 TLS(Keystore) #

名称描述默认值
security.ssl.transport.keystore_filepathKeystore 文件的路径。必填(若使用 Keystore 方式)。-
security.ssl.transport.keystore_passwordKeystore 的密码。changeit
security.ssl.transport.keystore_keypasswordKeystore 中私钥的密码(如果与 Keystore 密码不同)。keystore_password 相同
security.ssl.transport.keystore_aliasKeystore 中要使用的证书别名。如果 Keystore 包含多个证书条目,可指定别名。使用第一个条目
security.ssl.transport.keystore_typeKeystore 的类型。JKS
security.ssl.transport.truststore_filepathTruststore 文件的路径。必填(若使用 Keystore 方式)。-
security.ssl.transport.truststore_passwordTruststore 的密码。changeit
security.ssl.transport.truststore_aliasTruststore 中要使用的 CA 证书别名。使用第一个条目
security.ssl.transport.truststore_typeTruststore 的类型。JKS

HTTP 层 TLS(Keystore) #

名称描述默认值
security.ssl.http.keystore_filepathKeystore 文件的路径。必填(若使用 Keystore 方式)。-
security.ssl.http.keystore_passwordKeystore 的密码。changeit
security.ssl.http.keystore_keypasswordKeystore 中私钥的密码(如果与 Keystore 密码不同)。keystore_password 相同
security.ssl.http.keystore_aliasKeystore 中要使用的证书别名。使用第一个条目
security.ssl.http.keystore_typeKeystore 的类型。JKS
security.ssl.http.truststore_filepathTruststore 文件的路径。当 clientauth_modeREQUIRE 时必填。-
security.ssl.http.truststore_passwordTruststore 的密码。changeit
security.ssl.http.truststore_aliasTruststore 中要使用的 CA 证书别名。使用第一个条目
security.ssl.http.truststore_typeTruststore 的类型。JKS

Keystore 配置示例 #

# 传输层使用 JKS Keystore
security.ssl.transport.keystore_filepath: node-keystore.jks
security.ssl.transport.keystore_password: mypassword
security.ssl.transport.truststore_filepath: node-truststore.jks
security.ssl.transport.truststore_password: mypassword

# HTTP 层使用 PKCS12 Keystore
security.ssl.http.enabled: true
security.ssl.http.keystore_filepath: node-keystore.p12
security.ssl.http.keystore_password: mypassword
security.ssl.http.keystore_type: PKCS12
security.ssl.http.truststore_filepath: node-truststore.p12
security.ssl.http.truststore_password: mypassword
security.ssl.http.truststore_type: PKCS12

扩展密钥用途(Extended Key Usage) #

当启用扩展密钥用途时,传输层可以为服务端和客户端使用不同的证书。这在需要严格区分节点间入站和出站连接身份的场景中非常有用。

名称描述默认值
security.ssl.transport.extended_key_usage_enabled是否启用扩展密钥用途,启用后传输层将分别使用独立的服务端和客户端证书。false

服务端/客户端独立 PEM 证书 #

当启用扩展密钥用途时,可以为传输层的服务端和客户端分别指定 PEM 证书文件:

名称描述
security.ssl.transport.server.key_file传输层服务端私钥文件路径。
security.ssl.transport.server.key_secret服务端私钥密码。选填。
security.ssl.transport.server.cert_file传输层服务端证书文件路径。
security.ssl.transport.server.ca_file服务端 CA 证书文件路径。
security.ssl.transport.client.key_file传输层客户端私钥文件路径。
security.ssl.transport.client.key_secret客户端私钥密码。选填。
security.ssl.transport.client.cert_file传输层客户端证书文件路径。
security.ssl.transport.client.ca_file客户端 CA 证书文件路径。

服务端/客户端独立 Keystore 别名 #

当启用扩展密钥用途时,也可以通过 Keystore 别名来区分服务端和客户端证书。此时需要同时指定所有四个别名:

名称描述
security.ssl.transport.server.keystore_aliasKeystore 中服务端证书的别名。必填。
security.ssl.transport.server.keystore_keypassword服务端私钥的密码。默认使用 keystore_password
security.ssl.transport.client.keystore_aliasKeystore 中客户端证书的别名。必填。
security.ssl.transport.client.keystore_keypassword客户端私钥的密码。默认使用 keystore_password
security.ssl.transport.server.truststore_aliasTruststore 中服务端 CA 证书的别名。必填。
security.ssl.transport.client.truststore_aliasTruststore 中客户端 CA 证书的别名。必填。

扩展密钥用途配置示例 #

# 使用 PEM 格式的独立服务端/客户端证书
security.ssl.transport.extended_key_usage_enabled: true
security.ssl.transport.server.key_file: transport-server.key
security.ssl.transport.server.cert_file: transport-server.crt
security.ssl.transport.server.ca_file: ca.crt
security.ssl.transport.client.key_file: transport-client.key
security.ssl.transport.client.cert_file: transport-client.crt
security.ssl.transport.client.ca_file: ca.crt

配置节点证书 #

安全模块需要识别集群节点间的请求(即节点之间的通信)。配置节点证书的最简单方法是在 easysearch.yml 中列出这些证书的可分辨名称(DN)。所有 DN 都必须包含在所有节点上的 easysearch.yml 中。安全模块支持通配符和正则表达式:

security.nodes_dn:
  - "CN=node.other.com,OU=SSL,O=Test,L=Test,C=DE"
  - "CN=*.example.com,OU=SSL,O=Test,L=Test,C=DE"
  - "CN=elk-devcluster*"
  - "/CN=.*regex/"

如果您的节点证书在 SAN 部分中具有 OID 标识符,则可以省略此配置。

相关设置:

名称描述默认值
security.nodes_dn_dynamic_config_enabled是否允许通过 REST API 动态更新 nodes_dn 配置。false
security.cert.oid自定义 OID 用于在节点证书中标识节点身份。如果节点证书的 SAN 中包含此 OID 的值,则无需配置 security.nodes_dn1.2.3.4.5.5

配置管理证书 #

管理员证书是具有执行管理任务的提升权限的常规客户端证书。您需要管理员证书才能使用 HTTP API 更改安全配置。管理员证书在 easysearch.yml 中通过声明其 DN 进行配置:

security.authcz.admin_dn:
  - CN=admin,OU=SSL,O=Test,L=Test,C=DE

出于安全原因,您不能在此处使用通配符或正则表达式。

证书身份模拟(Impersonation) #

安全模块支持基于证书 DN 的身份模拟功能,允许经过认证的用户或传输请求以另一个用户的身份执行操作。

名称描述
security.authcz.impersonation_dn映射传输层证书 DN 到允许模拟的用户列表。
security.authcz.rest_impersonation_user映射 REST 层用户到允许模拟的用户列表。

模拟配置示例 #

security.authcz.impersonation_dn:
  "CN=spock,OU=client,O=client,L=Test,C=DE":
    - "worf"
    - "naomi"

security.authcz.rest_impersonation_user:
  "admin":
    - "monitor_user"
    - "report_user"

主机名验证和 DNS 查找 #

除了根据根 CA 和/或中间 CA 验证 TLS 证书外,安全插件还可以对传输层应用其他检查。

禁用 skip_domain_verify 后,安全模块将验证通信伙伴的主机名是否与证书中的主机名匹配。

主机名取自证书的 subjectSAN 条目。例如,如果节点的主机名为 node-0.example.com,则 TLS 证书中的主机名也必须设置为 node-0.example.com。否则,将引发错误:

[ERROR][c.a.o.s.s.t.SecuritySSLNettyTransport] [WX6omJY] SSL Problem No name matching <hostname> found
[ERROR][c.a.o.s.s.t.SecuritySSLNettyTransport] [WX6omJY] SSL Problem Received fatal alert: certificate_unknown

此外,启用 resolve_hostname 后,安全模块会根据您的 DNS 解析(经过验证的)主机名。如果主机名未解析,则会引发错误。

名称描述默认值
security.ssl.transport.skip_domain_verify是否跳过验证传输层上的主机名。true
security.ssl.transport.resolve_hostname是否在传输层上根据 DNS 解析主机名。仅在同时启用主机名验证时(skip_domain_verifyfalse)才有效。true

客户端认证 #

启用 TLS 客户端身份验证后,HTTP 客户端可以将 TLS 证书与 HTTP 请求一起发送,以向安全模块提供身份信息。TLS 客户端认证主要有以下使用场景:

  • 在使用 HTTP 管理 API 时提供管理员证书。
  • 根据客户端证书配置角色和权限。
  • 为 INFINI Console、Logstash 或 Beats 等工具提供身份信息。

TLS 客户端认证有三种模式:

模式描述
NONE安全模块不接受 TLS 客户端证书。如果发送了一个,则将其丢弃。
OPTIONAL安全模块接受 TLS 客户端证书(如果已发送),但不强制要求。默认值。
REQUIRE安全模块仅在发送有效的客户端 TLS 证书时接受 HTTP 请求。

对于 HTTP 管理 API,客户端身份验证模式至少必须是 OPTIONAL

名称描述默认值
security.ssl.http.clientauth_mode要使用的 TLS 客户端身份验证模式。可选值:NONEOPTIONALREQUIREOPTIONAL

样例 #

curl -k --cert config/instance.crt --key config/instance.key \\
  -XDELETE 'https://localhost:9200/.infini-*/' -u admin:xxxxxxxxxxxx

证书吊销列表(CRL) #

Easysearch 支持通过 CRL(证书吊销列表)和 OCSP(在线证书状态协议)来验证 HTTP 层客户端证书的有效性。

名称描述默认值
security.ssl.http.crl.file_pathCRL 文件的路径(PEM 格式),文件必须位于 config 目录下。-
security.ssl.http.crl.validate是否启用 CRL 验证。false
security.ssl.http.crl.prefer_crlfile_over_ocsp优先使用本地 CRL 文件而非 OCSP 进行证书吊销检查。false
security.ssl.http.crl.check_only_end_entities仅验证终端实体证书,不验证 CA 证书链中的中间证书。true
security.ssl.http.crl.disable_ocsp禁用 OCSP 检查。false
security.ssl.http.crl.disable_crldp禁用证书中 CRL 分发点(CRLDP)的自动下载。false
security.ssl.http.crl.validation_date用于验证的日期(主要用于测试目的)。格式为 ISO 8601 日期字符串。当前日期

加密算法和协议 #

您可以限制 HTTP 层和传输层允许的加密算法和 TLS 协议。例如,您可以只允许强密码算法,并将 TLS 版本限制为最新版本。

如果未配置此设置,密码和 TLS 版本将在通信双方之间自动协商,这在某些情况下可能会导致使用较弱的密码套件。

名称描述
security.ssl.http.enabled_ciphers数组,HTTP 层启用的 TLS 密码套件。仅支持 Java 格式。
security.ssl.http.enabled_protocols数组,HTTP 层启用的 TLS 协议。仅支持 Java 格式。
security.ssl.transport.enabled_ciphers数组,传输层启用的 TLS 密码套件。仅支持 Java 格式。
security.ssl.transport.enabled_protocols数组,传输层启用的 TLS 协议。仅支持 Java 格式。

默认启用的协议为 TLSv1.3TLSv1.2TLSv1.1。不安全的 TLSv1 协议默认禁用。

样例 #

security.ssl.http.enabled_ciphers:
  - "TLS_AES_128_GCM_SHA256"
  - "TLS_AES_256_GCM_SHA384"
  - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
  - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
  - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
  - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
  - "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"
  - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
security.ssl.http.enabled_protocols:
  - "TLSv1.2"
  - "TLSv1.3"

如果您需要使用 TLSv1 并接受潜在的安全风险,您仍然可以手动启用它:

security.ssl.http.enabled_protocols:
  - "TLSv1"
  - "TLSv1.1"
  - "TLSv1.2"

高级设置 #

OpenSSL 支持 #

Easysearch 支持使用 OpenSSL 作为 TLS 引擎来替代默认的 JDK SSL 实现。OpenSSL 通常可以提供更好的性能。

注意: OpenSSL 支持需要 Java 11 或更低版本,且必须设置系统属性 es.unsafe.use_netty_default_allocator=true。Java 12 及以上版本不支持 OpenSSL,将自动使用 JDK SSL。

名称描述默认值
security.ssl.http.enable_openssl_if_available如果 OpenSSL 可用,HTTP 层是否使用 OpenSSL。true
security.ssl.transport.enable_openssl_if_available如果 OpenSSL 可用,传输层是否使用 OpenSSL。true

证书热加载 #

名称描述默认值
security.ssl.cert_reload.enabled是否启用 TLS 证书的热加载。启用后,当证书文件发生变化时,节点将自动加载新证书而无需重启。false

TLS 客户端重协商 #

名称描述默认值
security.ssl.allow_client_initiated_renegotiation是否允许客户端发起的 TLS 重协商。允许此设置可能会导致 DoS 攻击风险,建议保持默认禁用。false

传输层主体提取器 #

名称描述默认值
security.ssl.transport.principal_extractor_class自定义主体提取器类的完全限定类名。用于自定义如何从传输层 TLS 证书中提取用户身份信息。-

SSL-Only 模式 #

名称描述默认值
security.ssl_only仅启用 SSL/TLS 加密,不加载安全插件的其余功能(认证、授权等)。适用于仅需要传输加密而不需要安全控制的场景。false

双模式(Dual Mode) #

名称描述默认值
security.ssl.dual_mode.enabled启用 SSL 双模式。当启用时,节点同时接受 SSL 和非 SSL 的传输层连接,便于集群从非加密向加密状态的平滑迁移。false

完整配置示例 #

以下是一个使用 PEM 格式证书的完整配置示例:

# ===== 传输层 TLS =====
security.ssl.transport.enabled: true
security.ssl.transport.key_file: instance.key
security.ssl.transport.cert_file: instance.crt
security.ssl.transport.ca_file: ca.crt
security.ssl.transport.skip_domain_verify: true

# ===== HTTP 层 TLS =====
security.ssl.http.enabled: true
security.ssl.http.key_file: instance.key
security.ssl.http.cert_file: instance.crt
security.ssl.http.ca_file: ca.crt
security.ssl.http.clientauth_mode: OPTIONAL

# ===== 节点和管理员 DN =====
security.nodes_dn:
  - "CN=*.example.com,OU=SSL,O=Test,L=Test,C=DE"
security.authcz.admin_dn:
  - "CN=admin,OU=SSL,O=Test,L=Test,C=DE"

# ===== 加密算法限制 =====
security.ssl.http.enabled_protocols:
  - "TLSv1.2"
  - "TLSv1.3"
security.ssl.transport.enabled_protocols:
  - "TLSv1.2"
  - "TLSv1.3"

# ===== 证书热加载 =====
security.ssl.cert_reload.enabled: true