Security Config

Keep your TiKV secure

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:

#! /bin/bash
set +e

mkdir -p easyrsa
cd easyrsa
curl -L https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.6/EasyRSA-unix-v3.0.6.tgz \
    | tar xzv --strip-components=1

./easyrsa init-pki \
    && ./easyrsa build-ca nopass

NUM_PD_NODES=3
for i in $(seq 1 $NUM_PD_NODES); do
    ./easyrsa gen-req pd$i nopass
    ./easyrsa sign-req server pd$i
done

NUM_TIKV_NODES=3
for i in $(seq 1 $NUM_TIKV_NODES); do
    ./easyrsa gen-req tikv$i nopass
    ./easyrsa sign-req server tikv$i
done

./easyrsa gen-req client nopass
./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:

$ ls easyrsa/pki/{ca.crt,issued,private}
easyrsa/pki/ca.crt

easyrsa/pki/issued:
client.crt  pd1.crt  pd2.crt  pd3.crt  tikv1.crt  tikv2.crt  tikv3.crt

easyrsa/pki/private:
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:

# Using empty strings here means disabling secure connections.
[security]
# The path to the file that contains the PEM encoding of the server’s CA certificates.
ca-path = "/path/to/ca.pem"
# The path to the file that contains the PEM encoding of the server’s certificate chain.
cert-path = "/path/to/tikv-server-cert.pem"
# The path to the file that contains the PEM encoding of the server’s private key.
key-path = "/path/to/tikv-server-key.pem"
# The name list used to verify the common name in client’s certificates. Verification is
# not enabled if this field is empty.
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:

[security]
# The path to the file that contains the PEM encoding of the server’s CA certificates.
cacert-path = "/path/to/ca.pem"
# The path to the file that contains the PEM encoding of the server’s certificate chain.
cert-path = "/path/to/pd-server-cert.pem"
# The path to the file that contains the PEM encoding of the server’s private key.
key-path = "/path/to/pd-server-key.pem"
# The name list used to verify the common name in client’s certificates. Verification is
# not enabled if this field is empty.
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

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

Java Client

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

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

Go Client

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

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:

pd-ctl                                    \
    --pd     "https://127.0.0.1:2379"     \
    # The path to the file that contains the PEM encoding of the server’s CA certificates.
    --cacert "/path/to/ca.pem"            \
    # The path to the file that contains the PEM encoding of the server’s certificate chain.
    --cert   "/path/to/client.pem"        \
    # The path to the file that contains the PEM encoding of the server’s private key.
    --key    "/path/to/client-key.pem"

tikv-ctl                                  \
    --host      "127.0.0.1:20160"         \
    # The path to the file that contains the PEM encoding of the server’s CA certificates.
    --ca-path   "/path/to/ca.pem"         \
    # The path to the file that contains the PEM encoding of the server’s certificate chain.
    --cert-path "/path/to/client.pem"     \
    # The path to the file that contains the PEM encoding of the server’s private key.
    --key-path  "/path/to/client-key.pem"