在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 双向认证加密。