跳转至

在NebulaGraph中启用 TLS 加密

TLS 加密是一种常用的网络安全技术,可确保客户端与服务端之间的通信安全。其工作原理主要是通过使用加密算法来保护在网络中传输的数据,防止数据在传输过程中被截获或者篡改。在 TLS 连接建立过程中,服务端会向客户端发送一个包含公钥和一些身份信息的数字证书,这个证书是由受信任的第三方认证机构(Certificate Authority, CA)签发的。客户端会验证这个数字证书,以确认服务端的身份。在 K8s 环境NebulaGraph中,用户如果需建立 TLS 加密,默认建立双向认证 TLS 加密,即客户端和服务端都需要验证其身份,以保证客户端与服务端之间的通信安全。本文介绍如何在 K8s 环境NebulaGraph中启用 TLS 加密。

前提条件

创建 TLS 类型 Secret

在 K8s 集群中,用户可以通过创建 Secret 来存储敏感信息,例如密码、OAuth 令牌和 TLS 证书等。在NebulaGraph中,用户可以通过创建 Secret 来存储 TLS 证书和私钥。在创建 Secret 时,需要指定 Secret 的类型 tlstls类型的 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字段包含三个子字段:serverSecretclientSecretcaSecret。这三个字段分别用于指定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。

serverCertserverKeyclientCertclientKeycaCert分别用于指定服务端 Secret 的证书和私钥的键名称,客户端 Secret 的证书和私钥的键名称,和 CA Secret 的证书键名称。如果没有自定义这些字段值,则 Operator 默认serverCertclientCert的值为tls.crtserverKeyclientKey的值为tls.keycaCert值为ca.crt。但在 K8s 集群中,TLS 类型的 Secret 默认使用tls.crttls.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 服务

操作步骤

  1. 使用预先生成的服务端、客户端证书和私钥、和 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 中存储的证书文件的路径。
  2. 在对应的集群实例配置文件中,增加服务端证书、客户端证书、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"
    
  3. 使用kubectl apply -f <config-file>将配置文件应用到集群中。

  4. 确认集群配置中sslCerts字段下serverCertserverKeyclientCertclientKeycaCert的值是否与创建的 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字段下serverCertserverKeyclientCertclientKeycaCert的值为 Secret 中存储的证书和私钥的键名称。上述示例中,需要将caCert的值ca.crt修改为tls.crt

  5. 使用 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 双向认证加密。


最后更新: October 12, 2023