Skip to content

Commit

Permalink
mtls for operator (#2178)
Browse files Browse the repository at this point in the history
* mtls for operator

* Update 8.5.enable-ssl.md
  • Loading branch information
abby-cyber authored Jul 21, 2023
1 parent 2f7d9ac commit e1cfd7d
Showing 1 changed file with 109 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -1,45 +1,66 @@
# Enable SSL Encryption in Nebula Graph
# Enable mTLS in NebulaGraph

SSL encryption is a commonly used network security technology that ensures secure communication between the client and server. Its working principle is mainly to protect data transmitted over the network by using encryption algorithms to prevent data interception or tampering during transmission. During the SSL connection establishment process, the server sends a digital certificate containing a public key and some identity information to the client. This certificate is issued by a trusted third-party Certification Authority (CA). The client verifies this digital certificate to confirm the identity of the server. In the NebulaGraph environment running in Kubernetes, you can enable SSL encryption, and both the client and server need to verify their identities to ensure secure communication between the client and server, and also between servers. This article explains how to enable SSL encryption in NebulaGraph running in K8s.
Transport Layer Security (TLS) is an encryption protocol in wide use on the Internet. TLS, which was formerly called SSL, authenticates the server in a client-server connection and encrypts communications between client and server so that external parties cannot spy on the communications. Its working principle is mainly to protect data transmitted over the network by using encryption algorithms to prevent data interception or tampering during transmission. During the TLS connection establishment process, the server sends a digital certificate containing a public key and some identity information to the client. This certificate is issued by a trusted third-party Certification Authority (CA). The client verifies this digital certificate to confirm the identity of the server.

In the NebulaGraph environment running in Kubernetes, mutual TLS (mTLS) is used to encrypt the communication between the client and server by default, which means both the client and server need to verify their identities. This article explains how to enable mTLS encryption in NebulaGraph running in K8s.

## Prerequisites

- NebulaGraph Operator has been installed.
- A NebulaGraph cluster has been created. For details, see [ Create a NebulaGraph cluster with kubectl](../3.deploy-nebula-graph-cluster/3.1create-cluster-with-kubectl.md) or [ Create a NebulaGraph cluster with Helm](../3.deploy-nebula-graph-cluster/3.2create-cluster-with-helm.md).
- A NebulaGraph cluster has been created. For details, see [Create a NebulaGraph cluster with kubectl](../3.deploy-nebula-graph-cluster/3.1create-cluster-with-kubectl.md) or [Create a NebulaGraph cluster with Helm](../3.deploy-nebula-graph-cluster/3.2create-cluster-with-helm.md).
- Certificates and their corresponding private keys have been generated for the client and server, and the CA certificate has been generated. For details, see [Generate Certificates Manually](https://kubernetes.io/docs/tasks/administer-cluster/certificates/).

!!! note

## Configure certifications
In the cluster created using Operator, the client and server use the same CA root certificate by default.

## Create a TLS-type Secret

In a K8s cluster, you can create Secrets to store sensitive information, such as passwords, OAuth tokens, and TLS certificates. In NebulaGraph, you can create a Secret to store TLS certificates and private keys. When creating a Secret, the type `tls` should be specified. A `tls` Secret is used to store TLS certificates.

For example, to create a Secret for storing server certificates and private keys:

```bash
kubectl create secret tls <server-cert> --key=<path/to/tls.key> --cert=<path/to/tls.cert> --namespace=<namespace>
```

- `<server-cert>`: The name of the Secret storing the server certificate and private key.
- `<path/to/tls.key>`: The path to the server private key file.
- `<path/to/tls.cert>`: The path to the server certificate file.
- `<namespace>`: The namespace where the Secret is located. If `--namespace` is not specified, it defaults to the `default` namespace.

You can follow the above steps to create Secrets for the client certificate and private key, and the CA certificate.


To view the created Secrets:

Operator provides the `sslCerts` field to specify the encrypted certificates. The `sslCerts` field contains three subfields: `serverSecret`, `clientSecret`, and `caSecret`. These three fields are used to specify the Secret names of the NebulaGraph server certificate, client certificate, and CA certificate, respectively. When the user specifies these three fields, Operator reads the certificate content from the corresponding Secret and mounts it into the cluster's Pod.
```bash
kubectl get secret --namespace=<namespace>
```

## Configure certifications

In a K8s cluster, SSL type Secrets use `tls.crt `and `tls.key` as the default names for the server or client certificate file and private key file, and the default name for the CA certificate file is `ca.crt` (the CA certificate does not need to configure a private key). If you change the names of the certificate file and private key, you need to add corresponding subfields in the `sslCerts` field to specify the new certificate and private key names, and specify the new names when creating the Secret.
Operator provides the `sslCerts` field to specify the encrypted certificates. The `sslCerts` field contains three subfields: `serverSecret`, `clientSecret`, and `caSecret`. These three fields are used to specify the Secret names of the NebulaGraph server certificate, client certificate, and CA certificate, respectively. When you specify these three fields, Operator reads the certificate content from the corresponding Secret and mounts it into the cluster's Pod.

```yaml
sslCerts:
# Name of the Secret containing the server certificate.
serverSecret: "server-cert"
# Name of the server certificate file. Defaults to tls.crt. No configuration is needed when using the default name.
serverPublicKey: ""
# Name of the server private key file. Defaults to tls.key. No configuration is needed when using the default name.
serverPrivateKey: ""
# Name of the Secret containing the client certificate.
clientSecret: "client-cert"
# Name of the client certificate file. Defaults to tls.crt. No configuration is needed when using the default name.
clientPublicKey: ""
# Name of the client private key file. Defaults to tls.key. No configuration is needed when using the default name.
clientPrivateKey: ""
# Name of the Secret containing the CA certificate.
caSecret: "ca-cert"
# Name of the CA certificate file. Defaults to ca.crt. No configuration is needed when using the default name.
caPublicKey: ""
serverSecret: "server-cert" # The name of the server certificate Secret.
serverCert: "" # The key name of the certificate in the server certificate Secret, default is tls.crt.
serverKey: "" # The key name of the private key in the server certificate Secret, default is tls.key.
clientSecret: "client-cert" # The name of the client certificate Secret.
clientCert: "" # The key name of the certificate in the client certificate Secret, default is tls.crt.
clientKey: "" # The key name of the private key in the client certificate Secret, default is tls.key.
caSecret: "ca-cert" # The name of the CA certificate Secret.
caCert: "" # The key name of the certificate in the CA certificate Secret, default is ca.crt.
```
The `serverCert` and `serverKey`, `clientCert` and `clientKey`, and `caCert` are used to specify the key names of the certificate and private key of the server Secret, the key names of the certificate and private key of the client Secret, and the key name of the CA Secret certificate. If you do not customize these field values, Operator defaults `serverCert` and `clientCert` to `tls.crt`, `serverKey` and `clientKey` to `tls.key`, and `caCert` to `ca.crt`. However, in the K8s cluster, the TLS type Secret uses `tls.crt` and `tls.key` as the default key names for the certificate and private key. Therefore, after creating the NebulaGraph cluster, you need to manually change the `caCert` field from `ca.crt` to `tls.crt` in the cluster configuration, so that the Operator can correctly read the content of the CA certificate. Before you customize these field values, you need to specify the key names of the certificate and private key in the Secret when creating it. For how to create a Secret with the key name specified, run the `kubectl create secret generic -h` command for help.
You can use the `insecureSkipVerify` field to decide whether the client will verify the server's certificate chain and hostname. In production environments, it is recommended to set this to `false` to ensure the security of communication. If set to `true`, the client will not verify the server's certificate chain and hostname.

```yaml
sslCerts:
# Determines whether the client needs to verify the server's certificate when establishing an SSL connection.
# Determines whether the client needs to verify the server's certificate chain and hostname when establishing an SSL connection. It defaults to true.
insecureSkipVerify: false
```

Expand All @@ -49,7 +70,7 @@ When the certificates are approaching expiration, they can be automatically upda

NebulaGraph offers three encryption strategies that you can choose and configure according to your needs.

- Encryption of all inter-service communication
- Encryption of client-graph and all inter-service communications

If you want to encrypt all data transmission between the client, Graph service, Meta service, and Storage service, you need to add the `enable_ssl = true` field to each service.

Expand All @@ -63,9 +84,9 @@ NebulaGraph offers three encryption strategies that you can choose and configure
namespace: default
spec:
sslCerts:
serverSecret: "server-cert"
clientSecret: "client-cert"
caSecret: "ca-cert"
serverSecret: "server-cert" # The Secret name of the server certificate and private key.
clientSecret: "client-cert" # The Secret name of the client certificate and private key.
caSecret: "ca-cert" # The Secret name of the CA certificate.
graphd:
config:
enable_ssl: "true"
Expand Down Expand Up @@ -98,6 +119,10 @@ NebulaGraph offers three encryption strategies that you can choose and configure
enable_graph_ssl: "true"
```

!!! note

Because Operator doesn't need to call the Graph service through an interface, it's not necessary to set `clientSecret` in `sslCerts`.

- Encryption of only Meta service communication

If you need to transmit confidential information to the Meta service, you can choose to encrypt data transmission related to the Meta service. In this case, you need to add the `enable_meta_ssl = true` configuration to each component.
Expand Down Expand Up @@ -126,32 +151,23 @@ NebulaGraph offers three encryption strategies that you can choose and configure
enable_meta_ssl: "true"
```

After setting up the encryption policy, when an external [client](../../14.client/1.nebula-client.md) needs to connect to the Graph service with mutual TLS, you still need to set the relevant TLS parameters according to the different clients. See the Use NebulaGraph Console to connect to Graph service section below for examples.

## Steps

1. Use the pre-generated server and client certificates and private keys, and the CA certificate to create a Secret for each.

- Examples to create an SSL type Secret for the server or client:

```yaml
kubectl create secret tls <client/server-cert-secret> --key=<client/server.key> --cert=<client/server.crt>
```

- `tls`: Indicates that the type of secret being created is TLS, which is used to store SSL/TLS certificates.
- `<client/server-cert-secret>`: Specifies the name of the new secret being created, which can be customized.
- `--key=<client/server.key>`: Specifies the path to the private key file of the SSL/TLS certificate to be stored in the secret.
- `--cert=<client/server.crt>`: Specifies the path to the public key certificate file of the SSL/TLS certificate to be stored in the secret.

- Create an encrypted CA certificate secret without specifying the private key of the CA.

```yaml
kubectl create secret tls <ca-cert-secret> --key --cert=<ca.crt>
```
```yaml
kubectl create secret tls <client/server/ca-cert-secret> --key=<client/server/ca.key> --cert=<client/server/ca.crt>
```

- `<ca-cert-secret>`: The name of the Secret to be created.
- `<ca.crt>`: The path to the CA certificate file stored in the Secret.
- `tls`: Indicates that the type of secret being created is TLS, which is used to store TLS certificates.
- `<client/server/ca-cert-secret>`: Specifies the name of the new secret being created, which can be customized.
- `--key=<client/server/ca.key>`: Specifies the path to the private key file of the TLS certificate to be stored in the secret.
- `--cert=<client/server/ca.crt>`: Specifies the path to the public key certificate file of the TLS certificate to be stored in the secret.


2. Add server certificate, client certificate, CA certificate configuration, and encryption policy configuration in the corresponding cluster instance YAML file.
2. Add server certificate, client certificate, CA certificate configuration, and encryption policy configuration in the corresponding cluster instance YAML file. For details, see [Encryption strategies](#encryption_strategies).

For example, add encryption configuration for transmission data between client, Graph service, Meta service, and Storage service.

Expand All @@ -178,5 +194,51 @@ NebulaGraph offers three encryption strategies that you can choose and configure
```

3. Use `kubectl apply -f` to apply the file to the Kubernetes cluster.

4. Verify that the values of `serverCert`, `serverKey`, `clientCert`, `clientKey`, `caCert` under the `sslCerts` field in the cluster configuration match the key names of the certificates and private keys stored in the created Secret.

```bash
# Check the key names of the certificate and private key stored in the Secret. For example, check the key name of the CA certificate stored in the Secret.
kubectl get secret ca-cert -o yaml
```

```bash
# Check the cluster configuration file.
kubectl get nebulacluster nebula -o yaml
```

Example output:

```
...
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
...
```

If the key names of the certificates and private keys stored in the Secret are different from the values of `serverCert`, `serverKey`, `clientCert`, `clientKey`, `caCert` under the `sslCerts` field in the cluster configuration, you need to execute `kubectl edit nebulacluster <cluster_name>` to manually modify the cluster configuration file.

In the example output, the key name of the CA certificate in the TLS-type Secret is `tls.crt`, so you need to change the value of caCert from `ca.crt` to `tls.crt`.

5. Use NebulaGraph Console to connect to the Graph service and establish a secure TLS connection.

Example:

```
kubectl run -ti --image vesoft/nebula-console:v{{console.release}} --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`: Use mTLS when connecting to NebulaGraph.
- `-ssl_root_ca_path`: Specify the storage path of the CA root certificate.
- `-ssl_cert_path`: Specify the storage path of the TLS public key certificate.
- `-ssl_private_key_path`: Specify the storage path of the TLS private key.
- For details on using NebulaGraph Console to connect to the Graph service, see [Connect to NebulaGraph](../4.connect-to-nebula-graph-service.md).
This will enable SSL encryption in NebulaGraph and enhance the security of the data.
At this point, you can enable mTLS in NebulaGraph.

0 comments on commit e1cfd7d

Please sign in to comment.