This document describes how to use Transport Layer Security (TLS) to encrypt the connections between TiKV nodes.

Transport Layer Security

Transport Layer Security is a standard protocol designed to protect network communications from network tampering or inspection. TiKV uses OpenSSL, an industry-standard toolkit for TLS, to implement its TLS encryption.

It is necessary to use TLS when TiKV is being deployed or accessed from outside of a secure Virtual Local Area Network (VLAN), such as the network across a Wide Area Network (WAN, also refers to a public internet), the network that is a part of an untrusted data center network, and the network where other untrustworthy users or services are active.

Preparation

Before getting started, you need to check your infrastructure. Your organization might already use tools like the Kubernetes certificates API to issue certificates. To successfully encrypt the connections between TiKV nodes, prepare the following certificates and keys:

  • A Certificate Authority (CA) certificate
  • Individual unique certificates and keys for each TiKV service and PD service
  • One or many certificates and keys for TiKV clients depending on your needs.

If you already have them, you can skip the optional section below.

If your organization does not yet have a public key infrastructure (PKI), you can create a simple CA to issue certificates for the services in your deployment by following the below instructions:

Optional: Generate a test certificate chain

You need to prepare certificates for each TiKV and Placement Driver (PD) node to be involved with the cluster. It is recommended to prepare a separate server certificate for TiKV and PD and ensure that they can authenticate each other. The clients of TiKV and PD can share one client certificate.

You can use multiple tools to generate self-signed certificates, such as openssl, easy-rsa, and cfssl.

Here is an example of generating self-signed certificates using easyrsa:

  1. #! /bin/bash
  2. set +e
  3. mkdir -p easyrsa
  4. cd easyrsa
  5. curl -L https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.6/EasyRSA-unix-v3.0.6.tgz \
  6. | tar xzv --strip-components=1
  7. ./easyrsa init-pki \
  8. && ./easyrsa build-ca nopass
  9. NUM_PD_NODES=3
  10. for i in $(seq 1 $NUM_PD_NODES); do
  11. ./easyrsa gen-req pd$i nopass
  12. ./easyrsa sign-req server pd$i
  13. done
  14. NUM_TIKV_NODES=3
  15. for i in $(seq 1 $NUM_TIKV_NODES); do
  16. ./easyrsa gen-req tikv$i nopass
  17. ./easyrsa sign-req server tikv$i
  18. done
  19. ./easyrsa gen-req client nopass
  20. ./easyrsa sign-req server client

When running this script, you need to answer some questions and make some confirmations interactively. For the CA common name, you can use any desired name. While for the PD and TiKV nodes, you need to use the hostnames.

If you see the following output, it means that the script runs successfully:

  1. $ ls easyrsa/pki/{ca.crt,issued,private}
  2. easyrsa/pki/ca.crt
  3. easyrsa/pki/issued:
  4. client.crt pd1.crt pd2.crt pd3.crt tikv1.crt tikv2.crt tikv3.crt
  5. easyrsa/pki/private:
  6. ca.key client.key pd1.key pd2.key pd3.key tikv1.key tikv2.key tikv3.key

Step 1. Configure the TiKV server certificates

You need to set the certificates in the TiKV configuration file:

  1. # Using empty strings here means disabling secure connections.
  2. [security]
  3. # The path to the file that contains the PEM encoding of the server’s CA certificates.
  4. ca-path = "/path/to/ca.pem"
  5. # The path to the file that contains the PEM encoding of the server’s certificate chain.
  6. cert-path = "/path/to/tikv-server-cert.pem"
  7. # The path to the file that contains the PEM encoding of the server’s private key.
  8. key-path = "/path/to/tikv-server-key.pem"
  9. # The name list used to verify the common name in client’s certificates. Verification is
  10. # not enabled if this field is empty.
  11. cert-allowed-cn = ["tikv-server", "pd-server"]

Besides, the connection URL should be changed to https:// instead of a plain ip:port.

For the information about all TLS configuration parameters of TiKV, see TiKV security-related parameters.

Step 2. Configure the PD certificates

You need to set the certificates in the PD configuration file:

  1. [security]
  2. # The path to the file that contains the PEM encoding of the server’s CA certificates.
  3. cacert-path = "/path/to/ca.pem"
  4. # The path to the file that contains the PEM encoding of the server’s certificate chain.
  5. cert-path = "/path/to/pd-server-cert.pem"
  6. # The path to the file that contains the PEM encoding of the server’s private key.
  7. key-path = "/path/to/pd-server-key.pem"
  8. # The name list used to verify the common name in client’s certificates. Verification is
  9. # not enabled if this field is empty.
  10. cert-allowed-cn = ["tikv-server", "pd-server"]

Besides, the connection URL should be changed to https:// instead of a plain ip:port.

For the information about all TLS configuration parameters of PD, see PD security-related parameters.

Step 3. Configure the TiKV client

You need to set TLS options for the TiKV client to connect to TiKV.

Rust Client

  1. let config = Config::new(/* ... */).with_security(
  2. // The path to the file that contains the PEM encoding of the server’s CA certificates.
  3. "/path/to/ca.pem",
  4. // The path to the file that contains the PEM encoding of the server’s certificate chain.
  5. "/path/to/client-cert.pem",
  6. // The path to the file that contains the PEM encoding of the server’s private key.
  7. "/path/to/client-key.pem"
  8. );

Java Client

  1. TiConfiguration conf = TiConfiguration.createRawDefault("127.0.0.1:2379");
  2. conf.setTlsEnable(true);
  3. conf.setTrustCertCollectionFile("/path/to/ca.pem");
  4. conf.setKeyCertChainFile("/path/to/cert.pem");
  5. conf.setKeyFile("/path/to/key.pem");

For more information about the TLS config of Java client, check the Java client documentation

Go Client

  1. cli, err := rawkv.NewClient(context.TODO(), []string{"127.0.0.1:2379"}, config.Security{
  2. ClusterSSLCA: "/path/to/ca.pem",
  3. ClusterSSLCert: "/path/to/cert.pem",
  4. ClusterSSLKey: "/path/to/key.pem",
  5. })
  6. if err != nil {
  7. panic(err)
  8. }

For more information about the TLS config of Go client, check the Go client documentation

Step 4. Connect TiKV using tikv-ctl and pd-ctl

To use pd-ctl and tikv-ctl, set the relevant options as follows:

  1. pd-ctl \
  2. --pd "https://127.0.0.1:2379" \
  3. # The path to the file that contains the PEM encoding of the server’s CA certificates.
  4. --cacert "/path/to/ca.pem" \
  5. # The path to the file that contains the PEM encoding of the server’s certificate chain.
  6. --cert "/path/to/client.pem" \
  7. # The path to the file that contains the PEM encoding of the server’s private key.
  8. --key "/path/to/client-key.pem"
  9. tikv-ctl \
  10. --host "127.0.0.1:20160" \
  11. # The path to the file that contains the PEM encoding of the server’s CA certificates.
  12. --ca-path "/path/to/ca.pem" \
  13. # The path to the file that contains the PEM encoding of the server’s certificate chain.
  14. --cert-path "/path/to/client.pem" \
  15. # The path to the file that contains the PEM encoding of the server’s private key.
  16. --key-path "/path/to/client-key.pem"