在NebulaGraph中启用 TLS 加密¶
TLS 加密是一种常用的网络安全技术,可确保客户端与服务端之间的通信安全。其工作原理主要是通过使用加密算法来保护在网络中传输的数据,防止数据在传输过程中被截获或者篡改。在 TLS 连接建立过程中,服务端会向客户端发送一个包含公钥和一些身份信息的数字证书,这个证书是由受信任的第三方认证机构(Certificate Authority, CA)签发的。客户端会验证这个数字证书,以确认服务端的身份。在 K8s 环境NebulaGraph中,用户如果需建立 TLS 加密,默认建立双向认证 TLS 加密,即客户端和服务端都需要验证其身份,以保证客户端与服务端之间的通信安全。本文介绍如何在 K8s 环境NebulaGraph中启用 TLS 加密。
前提条件¶
- 已安装 NebulaGraph Operator。
- 已创建NebulaGraph集群。具体步骤参见使用 Kubectl 部署NebulaGraph集群或者使用 Helm 部署NebulaGraph集群。
-
已为客户端、服务端生成证书和对应私钥,并生成 CA 证书。具体步骤参见 Generate Certificates Manually。
Note
在使用 Operator 创建的集群中,默认客户端和服务端使用相同的 CA 根证书。
创建 TLS 类型 Secret¶
在 K8s 集群中,用户可以通过创建 Secret 来存储敏感信息,例如密码、OAuth 令牌和 TLS 证书等。在NebulaGraph中,用户可以通过创建 Secret 来存储 TLS 证书和私钥。在创建 Secret 时,需要指定 Secret 的类型 tls,tls类型的 Secret 用于存储 TLS/TLS 证书。
例如,创建一个用于存储服务端证书和私钥的 Secret:
kubectl create secret tls <server-cert> --key=<path/to/server.key> --cert=<path/to/server.cert> --namespace=<namespace>
<server-cert>: 存储服务端证书和私钥的 Secret 的名称。<path/to/server.key>: 服务端私钥文件的路径。<path/to/server.cert>: 服务端证书文件的路径。<namespace>: Secret 所在的命名空间。如果不指定--namespace,则默认为default。
可按照上述步骤分别创建客户端证书和私钥的 Secret 和 CA 证书的 Secret。
查看创建的 Secret:
kubectl get secret --namespace=<namespace>
证书配置说明¶
Operator 提供sslCerts字段指定加密的证书。sslCerts字段包含三个子字段:serverSecret、clientSecret、caSecret。这三个字段分别用于指定NebulaGraph服务端证书、客户端证书和 CA 证书的 Secret 名称。当用户指定这三个字段时,Operator 会从对应的 Secret 中读取证书内容并挂载到集群的 Pod 中。
sslCerts:
serverSecret: "server-cert" # 服务端证书 Secret 的名称。
serverCert: "" # 服务端证书 Secret 中证书的键名称,默认为 tls.crt。
serverKey: "" # 服务端证书 Secret 中私钥的键名称,默认为 tls.key。
clientSecret: "client-cert" # 客户端证书 Secret 的名称。
clientCert: "" # 客户端证书 Secret 中证书的键名称,默认为 tls.crt。
clientKey: "" # 客户端证书 Secret 中私钥的键名称,默认为 tls.key。
caSecret: "ca-cert" # CA 证书 Secret 的名称。
caCert: "" # CA 证书 Secret 中证书的键名称,默认为 ca.crt。
serverCert和serverKey、clientCert和clientKey、caCert分别用于指定服务端 Secret 的证书和私钥的键名称,客户端 Secret 的证书和私钥的键名称,和 CA Secret 的证书键名称。如果没有自定义这些字段值,则 Operator 默认serverCert和clientCert的值为tls.crt,serverKey和clientKey的值为tls.key,caCert值为ca.crt。但在 K8s 集群中,TLS 类型的 Secret 默认使用tls.crt和tls.key作证书和私钥的键名称。因此,在创建NebulaGraph集群后,需要在集群配置中手动将caCert字段的ca.crt更改为tls.crt,这样 Operator 才能正确地读取 CA 证书的内容。如果用户自定义这些字段值,同时也需要在创建 Secret 的时候指定 Secret 的证书和私钥的键名称。可通过kubectl create secret generic -h查看创建指定键名的 Secret 的命令。
用户可通过insecureSkipVerify字段决定客户端是否会验证服务端的证书链和主机名。在生产环境中,建议将其设置为false以确保通信的安全性。如果设置为true,客户端将不会验证服务端的证书链和主机名。
sslCerts:
# 用于决定客户端在建立 TLS 连接时,是否验证服务器端的证书链和主机名。
insecureSkipVerify: false
当证书接近到期时,可以通过安装 cert-manager 自动更新 Secret。NebulaGraph会监听证书目录文件的变化,一旦检测到文件变动,便会将新的证书内容加载到内存中。
加密策略¶
NebulaGraph提供了三种加密策略,用户可以根据自己的需求来选择和配置。
-
全部服务间通信加密
如果想加密客户端、Graph 服务、Meta 服务和 Storage 服务之间的所有数据传输,需在每个服务中添加
enable_ssl = true字段。配置示例:
apiVersion: apps.nebula-graph.io/v1alpha1 kind: NebulaCluster metadata: name: nebula namespace: default spec: sslCerts: serverSecret: "server-cert" # 服务端证书和私钥的 Secret 名称。 clientSecret: "client-cert" # 客户端证书和私钥的 Secret 名称。 caSecret: "ca-cert" # CA 证书 Secret 名称。 graphd: config: enable_ssl: "true" metad: config: enable_ssl: "true" storaged: config: enable_ssl: "true"
-
仅客户端与 Graph 服务之间的通信加密
如果 K8s 集群部署在同一个机房内,且只有 Graph 服务的端口向外部开放,可以选择只加密客户端和 Graph 服务之间的数据传输。在这种情况下,其他服务可以在内部网络上无需加密的情况下进行通信。只需在 Graph 服务中添加
enable_graph_ssl = true字段即可。配置示例:
apiVersion: apps.nebula-graph.io/v1alpha1 kind: NebulaCluster metadata: name: nebula namespace: default spec: sslCerts: serverSecret: "server-cert" caSecret: "ca-cert" graphd: config: enable_graph_ssl: "true"Note
因为 Operator 没有通过接口调用 Graph 服务的需求,所以
sslCerts里不用设置clientSecret。
-
仅 Meta 服务通信加密
如果需要将保密信息传输到 Meta 服务,可以选择加密与 Meta 服务相关的数据传输。在这种情况下,需要在每个组件中添加
enable_meta_ssl = true配置。配置示例:
apiVersion: apps.nebula-graph.io/v1alpha1 kind: NebulaCluster metadata: name: nebula namespace: default spec: sslCerts: serverSecret: "server-cert" clientSecret: "client-cert" caSecret: "ca-cert" graphd: config: enable_meta_ssl: "true" metad: config: enable_meta_ssl: "true" storaged: config: enable_meta_ssl: "true"
加密策略设置好后,当外部客户端连接 Graph 服务需要双向认证时,用户还需要根据客户端的不同来设置相关的 TLS 参数。示例参见下文使用 NebulaGraph Console 连接 Graph 服务。
操作步骤¶
-
使用预先生成的服务端、客户端证书和私钥、和 CA 证书分别创建 Secret。
kubectl create secret tls <client/server/ca-cert-secret> --key=<client/server/ca.key> --cert=<client/server/ca.crt>tls:创建的 Secret 的类型是 TLS,这种类型的 Secret 用于存储 TLS 证书。<client/server/ca-cert-secret>:新创建的 Secret 的名称。--key=<client/server/ca.key>:该 Secret 中存储的私钥文件的路径。--cert=<client/server/ca.crt>:该 Secret 中存储的证书文件的路径。
-
在对应的集群实例配置文件中,增加服务端证书、客户端证书、CA 证书配置和加密策略配置。有关加密策略的配置,参见上文加密策略。
例如,对客户端、Graph 服务、Meta 服务和 Storage 服务之间的传输数据加密配置。
apiVersion: apps.nebula-graph.io/v1alpha1 kind: NebulaCluster metadata: name: nebula namespace: default spec: sslCerts: serverSecret: "server-cert" // 服务端证书 Secret 名称。 clientSecret: "client-cert" // 客户端证书 Secret 名称。 caSecret: "ca-cert" // CA 证书 Secret 名称。 graphd: config: enable_ssl: "true" metad: config: enable_ssl: "true" storaged: config: enable_ssl: "true" -
使用
kubectl apply -f <config-file>将配置文件应用到集群中。 -
确认集群配置中
sslCerts字段下serverCert、serverKey、clientCert、clientKey、caCert的值是否与创建的 Secret 中存储的证书和私钥的键名称一致。# 查看 Secret 中存储的证书文件和私钥文件的名称。例如,查看 Secret 中存储的 CA 证书文件的名称。 kubectl get secret ca-cert -o yaml# 查看集群的配置文件。 kubectl get nebulacluster nebula -o yaml示例输出:
... spec: sslCerts: serverSecret: server-cert serverCert: tls.crt serverKey: tls.key clientSecret: client-cert clientCert: tls.crt clientKey: tls.key caSecret: ca-cert caCert: ca.crt ...如果不一致,执行
kubectl edit nebulacluster <cluster_name>手动修改集群配置中sslCerts字段下serverCert、serverKey、clientCert、clientKey、caCert的值为 Secret 中存储的证书和私钥的键名称。上述示例中,需要将caCert的值ca.crt修改为tls.crt。 -
使用 NebulaGraph Console 连接 Graph 服务并建立安全的 TLS 连接。
示例命令如下:
kubectl run -ti --image vesoft/nebula-console:v3.5.0 --restart=Never -- nebula-console -addr 10.98.xxx.xx -port 9669 -u root -p nebula -enable_ssl -ssl_root_ca_path /path/to/cert/root.crt -ssl_cert_path /path/to/cert/client.crt -ssl_private_key_path /path/to/cert/client.key-enable_ssl:连接NebulaGraph时使用 TLS 双向认证加密。-ssl_root_ca_path:指定 CA 根证书的存储路径。-ssl_cert_path:指定 TLS 公钥证书的存储路径。-ssl_private_key_path:指定 TLS 密钥的存储路径。- 有关使用 NebulaGraph Console 连接 Graph 服务的详情,参见连接NebulaGraph。
至此,就可以在NebulaGraph中建立 TLS 双向认证加密。