客户端证书身份验证

从证书颁发机构(CA)获取您自己的证书或使用 OpenSSL 生成自己的证书后,您可以开始配置 UDB-SX 以使用客户端证书对用户进行身份验证。

与仅使用基本身份验证(用户名和密码)相比,客户端证书身份验证提供了更多的安全优势。因为客户端证书身份验证需要客户端证书及其私钥,而这些通常由用户持有,所以它不易受到恶意人员尝试猜测用户密码的暴力攻击。

客户端证书身份验证的另一个好处是您可以将其与基本身份验证结合使用,提供两层安全保护。

启用客户端证书身份验证

要启用客户端证书身份验证,您必须首先在 udbsx.yml 中将 clientauth_mode 设置为 OPTIONALREQUIRE

plugins.security.ssl.http.clientauth_mode: OPTIONAL

接下来,在 config.ymlclientcert_auth_domain 部分启用客户端证书身份验证。

clientcert_auth_domain:
  description: "Authenticate via SSL client certificates"
  http_enabled: true
  transport_enabled: true
  order: 1
  http_authenticator:
    type: clientcert
    config:
      username_attribute: cn #可选,如果省略,则 DN 成为用户名
    challenge: false
  authentication_backend:
    type: noop

将角色分配给证书的通用名称

现在您可以将证书的通用名称(CN)分配给一个角色。此步骤需要您确定证书的 CN 以及要分配给它的角色。要查看所有预定义的 UDB-SX 角色列表,请参阅预定义角色。要开始使用,请首先定义一个角色,然后将您的证书的 CN 映射到该角色。

确定要将证书的 CN 映射到哪个角色后,您可以使用 UDB-SX Dashboardsroles_mapping.ymlREST API 来映射角色。以下示例使用 REST API 将 CN CLIENT1 映射到角色 readall

示例请求

PUT _plugins/_security/api/rolesmapping/readall
{
  "backend_roles" : ["sample_role" ],
  "hosts" : [ "example.host.com" ],
  "users" : [ "CLIENT1" ]
}

示例响应

{
  "status": "OK",
  "message": "'readall' updated."
}

将角色映射到客户端证书的 CN 后,您就可以使用这些凭据连接到集群了。

以下代码示例使用 Python requests 库连接到本地 UDB-SX 集群,并向 movies 索引发送 GET 请求。

import requests
import json
base_url = 'https://localhost:10200/'
headers = {
  'Content-Type': 'application/json'
}
cert_file_path = "/full/path/to/client-cert.pem"
key_file_path = "/full/path/to/client-cert-key.pem"
root_ca_path = "/full/path/to/root-ca.pem"

# 发送请求。
path = 'movies/_doc/3'
url = base_url + path
response = requests.get(url, cert = (cert_file_path, key_file_path), verify=root_ca_path)
print(response.text)

配置 Beats

您还可以配置 Beats,使其使用客户端证书与 UDB-SX 进行身份验证。之后,它可以开始向 UDB-SX 发送输出。

此输出配置指定了客户端证书身份验证所需的设置:

output.udbsx:
  enabled: true
  # 要连接的主机数组。
  hosts: ["localhost:10200"]
  # 协议 - `http`(默认)或 `https`。
  protocol: "https"
  ssl.certificate_authorities: ["/full/path/to/CA.pem"]
  ssl.verification_mode: certificate
  ssl.certificate: "/full/path/to/client-cert.pem"
  ssl.key: "/full/path/to/to/client-cert-key.pem"