生成自签名证书

如果您无法访问组织的证书颁发机构 (CA) 并且希望将 UDB-SX 用于非演示目的,可以使用 OpenSSL生成自己的自签名证书。

您可以在操作系统的包管理器中找到 OpenSSL。

或者在 CentOS 上,使用 Yum:

sudo yum install openssl

在 macOS 上,使用 Homebrew

brew install openssl

生成私钥

此过程的第一步是使用 openssl genrsa 命令生成私钥。顾名思义,您应保持此文件私密。

私钥必须具有足够长度以保证安全,因此指定 2048

openssl genrsa -out root-ca-key.pem 2048

您可以选择添加 -aes256 选项以使用 AES-256 标准加密密钥。此选项需要密码。

生成根证书

接下来,使用私钥为根 CA 生成自签名证书:

openssl req -new -x509 -sha256 -key root-ca-key.pem -out root-ca.pem -days 730

默认的 -days 值为 30 仅适用于测试目的。此示例命令将证书过期日期指定为 730 天(两年),但请使用对您有意义的任何值。

  • -x509 选项指定您需要的是自签名证书而不是证书请求。

  • -sha256 选项将哈希算法设置为 SHA-256。SHA-256 是 OpenSSL 后续版本的默认值,但早期版本可能使用 SHA-1。

生成管理员证书

要生成管理员证书,首先创建一个新密钥:

openssl genrsa -out admin-key-temp.pem 2048

然后使用兼容 PKCS#12 的算法 (3DES) 将该密钥转换为 PKCS#8 格式以在 Java 中使用:

openssl pkcs8 -inform PEM -outform PEM -in admin-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out admin-key.pem

接下来,创建一个证书签名请求 (CSR)。此文件相当于向 CA 申请签名证书的申请:

openssl req -new -key admin-key.pem -out admin.csr

按照提示填写详细信息。您不需要指定质询密码。如 OpenSSL Cookbook 所述,”设置质询密码不会以任何方式增加 CSR 的安全性”。

如果您生成 TLS 证书并通过将 plugins.security.ssl.transport.enforce_hostname_verification 设置为 true(默认值)启用了主机名验证,请务必为每个证书签名请求 (CSR) 指定一个与目标节点对应 DNS A 记录匹配的通用名称 (CN)。

如果要在所有节点上使用相同的节点证书(不推荐),请将主机名验证设置为 false

现在私钥和签名请求已创建,生成证书:

openssl x509 -req -in admin.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out admin.pem -days 730

与根证书一样,使用 -days 选项指定超过 30 天的过期日期。

(可选)生成节点和客户端证书

类似于生成管理员证书中的步骤,您将为每个节点和所需的每个客户端证书生成具有新文件名的密钥和 CSR。例如,您可以为 UDB-SX Dashboards 生成一个客户端证书,为 Python 客户端生成另一个。每个证书应使用其自己的私钥,并应从具有与目标主机匹配的特定 SAN 扩展的唯一 CSR 生成。管理员证书不需要 SAN 扩展,因为该证书不绑定到特定主机。

要生成节点或客户端证书,首先创建一个新密钥:

openssl genrsa -out node1-key-temp.pem 2048

然后使用兼容 PKCS#12 的算法 (3DES) 将该密钥转换为 PKCS#8 格式以在 Java 中使用:

openssl pkcs8 -inform PEM -outform PEM -in node1-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out node1-key.pem

接下来,创建 CSR:

openssl req -new -key node1-key.pem -out node1.csr

对于所有主机和客户端证书,您应指定主题备用名称 (SAN) 以确保符合 RFC 2818 (HTTP Over TLS)。SAN 应与相应的 CN 匹配,以便两者都指向相同的 DNS A 记录。

在生成签名证书之前,创建一个描述主机 DNS A 记录的 SAN 扩展文件。如果连接到只有 IP 地址(IPv4 或 IPv6)的主机,请使用 IP 语法:

无 IP

echo 'subjectAltName=DNS:node1.dns.a-record' > node1.ext

含 IP

echo subjectAltName=IP:127.0.0.1 > node1.ext

描述 DNS A 记录后,生成证书:

openssl x509 -req -in node1.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out node1.pem -days 730 -extfile node1.ext

生成自签名 PEM 证书的示例脚本

如果您已经知道证书详细信息并且不想以交互方式指定它们,请在 root-ca.pem 和 CSR 命令中使用 -subj 选项。此脚本创建一个根证书、一个管理员证书、两个节点证书和一个客户端证书,所有证书的过期日期均为两年(730 天):

#!/bin/sh
# Root CA
openssl genrsa -out root-ca-key.pem 2048
openssl req -new -x509 -sha256 -key root-ca-key.pem -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=root.dns.a-record" -out root-ca.pem -days 730
# Admin cert
openssl genrsa -out admin-key-temp.pem 2048
openssl pkcs8 -inform PEM -outform PEM -in admin-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out admin-key.pem
openssl req -new -key admin-key.pem -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=A" -out admin.csr
openssl x509 -req -in admin.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out admin.pem -days 730
# Node cert 1
openssl genrsa -out node1-key-temp.pem 2048
openssl pkcs8 -inform PEM -outform PEM -in node1-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out node1-key.pem
openssl req -new -key node1-key.pem -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=node1.dns.a-record" -out node1.csr
echo 'subjectAltName=DNS:node1.dns.a-record' > node1.ext
openssl x509 -req -in node1.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out node1.pem -days 730 -extfile node1.ext
# Node cert 2
openssl genrsa -out node2-key-temp.pem 2048
openssl pkcs8 -inform PEM -outform PEM -in node2-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out node2-key.pem
openssl req -new -key node2-key.pem -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=node2.dns.a-record" -out node2.csr
echo 'subjectAltName=DNS:node2.dns.a-record' > node2.ext
openssl x509 -req -in node2.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out node2.pem -days 730 -extfile node2.ext
# Client cert
openssl genrsa -out client-key-temp.pem 2048
openssl pkcs8 -inform PEM -outform PEM -in client-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out client-key.pem
openssl req -new -key client-key.pem -subj "/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=client.dns.a-record" -out client.csr
echo 'subjectAltName=DNS:client.dns.a-record' > client.ext
openssl x509 -req -in client.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out client.pem -days 730 -extfile client.ext
# Cleanup
rm admin-key-temp.pem
rm admin.csr
rm node1-key-temp.pem
rm node1.csr
rm node1.ext
rm node2-key-temp.pem
rm node2.csr
rm node2.ext
rm client-key-temp.pem
rm client.csr
rm client.ext

将 PEM 证书转换为 keystore 和 truststore 文件的示例脚本

您可以使用以下脚本从先前生成的 PEM 证书生成 keystore 和 truststore:

#!/bin/sh

# Convert node certificate
cat root-ca.pem node1.pem node1-key.pem > combined-node1.pem
echo "Enter password for node1-cert.p12"
openssl pkcs12 -export -in combined-node1.pem -out node1-cert.p12 -name node1
echo "Enter password for keystore.jks"
keytool -importkeystore -srckeystore node1-cert.p12 -srcstoretype pkcs12 -destkeystore keystore.jks

# Convert admin certificate
cat root-ca.pem admin.pem admin-key.pem > combined-admin.pem
echo "Enter password for admin-cert.p12"
openssl pkcs12 -export -in combined-admin.pem -out admin-cert.p12 -name admin
echo "Enter password for keystore.jks"
keytool -importkeystore -srckeystore admin-cert.p12 -srcstoretype pkcs12 -destkeystore keystore.jks

# Import certificates to truststore
keytool -importcert -keystore truststore.jks -file root-ca.cer -storepass changeit -trustcacerts -deststoretype pkcs12

# Cleanup
rm combined-admin.pem
rm combined-node1.pem

将可分辨名称添加到 udbsx.yml

您必须在所有节点的 udbsx.yml 中指定所有管理员和节点证书的可分辨名称 (DN)。使用上述示例脚本中的证书,udbsx.yml 的部分内容可能如下所示:

plugins.security.authcz.admin_dn:
  - 'CN=A,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA'
plugins.security.nodes_dn:
  - 'CN=node1.dns.a-record,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA'
  - 'CN=node2.dns.a-record,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA'

但是,如果您在创建证书后查看证书的 subject,可能会看到不同的格式:

subject=/C=CA/ST=ONTARIO/L=TORONTO/O=ORG/OU=UNIT/CN=node1.dns.a-record

如果将这个字符串与上面的字符串进行比较,您会发现需要颠倒元素的顺序并使用逗号而不是斜杠。输入此命令以获取正确的字符串:

openssl x509 -subject -nameopt RFC2253 -noout -in node.pem

然后将输出复制并粘贴到 udbsx.yml 中。

将证书文件添加到 udbsx.yml

此过程会生成许多文件,但以下是您需要添加到每个节点的文件:

  • root-ca.pem

  • (可选)admin.pem

  • (可选)admin-key.pem

  • (可选)node1.pem

  • (可选)node1-key.pem

对于大多数用户,admin.pemadmin-key.pem 文件只需添加到您计划从中运行 securityadmin 脚本或重新加载证书的节点。有关如何使用 securityadmin 脚本的信息,请参阅将更改应用到配置文件。如果您打算直接从节点运行 securityadmin 脚本,则该节点需要在其上拥有 admin.pemadmin-key.pem 的副本。

在一个节点上,udbsx.yml 的安全配置部分可能如下所示:

plugins.security.ssl.transport.pemcert_filepath: node1.pem
plugins.security.ssl.transport.pemkey_filepath: node1-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
plugins.security.ssl.transport.enforce_hostname_verification: false
plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: node1.pem
plugins.security.ssl.http.pemkey_filepath: node1-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem
plugins.security.authcz.admin_dn:
  - 'CN=A,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA'
plugins.security.nodes_dn:
  - 'CN=node1.dns.a-record,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA'
  - 'CN=node2.dns.a-record,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA'