Security
Kuma helps you secure your existing infrastructure with mTLS. The following sections cover details of how it works.
Certificates
Kuma uses a built-in CA (Certificate Authority) to issue certificates for dataplanes. The root CA certificate is unique for each mesh in the system. On Kubernetes, the root CA certificate is stored as a Kubernetes Secret. On Universal, we leverage the same storage (Postgres) that is used for storing policies. Certificates for dataplanes are ephemeral, re-created on dataplane restart and never persisted on disk.
Dataplane certificates generated by Kuma are X.509 certificates that are SPIFFE compliant. The SAN of certificate is set to spiffe://<mesh name>/<service name>
Kuma also supports external CA. By changing the ca
in the mesh resource to provided
, you can use a CA of your choice.
type: Mesh
name: default
mtls:
enabled: true # enable mTLS
ca:
provided: {} # use Provided CA (an existing Root CA certificate must be provided by a user)
To manage external CAs after you update the mesh resource, kumactl
now supports a new command: kumactl manage ca
. With this new command, you can do add and delete certificates.
For further details refer to Mutual TLS policy.
Dataplane Token
In order to obtain an mTLS certificate from the server (SDS built-in in the control plane), a dataplane must prove it’s identity.
Kubernetes
On Kubernetes, a dataplane proves its identity by leveraging ServiceAccountToken that is mounted in every pod.
Universal
On Universal, a dataplane must be explicitly configured with a unique security token (Dataplane Token) that will be used to prove its identity. Dataplane Token is a signed JWT token that the carries dataplane name and name of the mesh it’s allowed to join to. It is signed by an RSA key auto-generated by the control plane on first run. Tokens are not stored in the control plane, the only thing that is stored is a signing key that is used to verify if a token is valid.
You can generate token either by REST API
curl -XPOST http://localhost:5679/tokens --data '{"name:" "dp-echo-1", "mesh": "default"}'
or by using kumactl
kumactl generate dataplane-token --name=dp-echo-1 --mesh=default > /tmp/kuma-dp-echo1-token
The token should be stored in a file and then used when starting kuma-dp
$ kuma-dp run \
--name=dp-echo-1 \
--mesh=default \
--cp-address=http://127.0.0.1:5681 \
--dataplane-token-file=/tmp/kuma-dp-echo-1-token
Accessing Admin Server from a different machine
By default, the Admin Server that is serving Dataplane Tokens is exposed only on localhost. If you want to generate tokens from a different machine than control plane you have to secure the connection:
- Enable public server by setting
KUMA_ADMIN_SERVER_PUBLIC_ENABLED
totrue
. Make sure to specify hostname which can be used to access Kuma from other machine viaKUMA_GENERAL_ADVERTISED_HOSTNAME
. - Generate certificate for the HTTPS Admin Server and set via
KUMA_ADMIN_SERVER_PUBLIC_TLS_CERT_FILE
andKUMA_ADMIN_SERVER_PUBLIC_TLS_KEY_FILE
config environment variable. For generating self signed certificate you can usekumactl
$ kumactl generate tls-certificate --cert-file=/path/to/cert --key-file=/path/to/key --type=server --cp-hostname=<name from KUMA_GENERAL_ADVERTISED_HOSTNAME>
- Pick a public interface on which HTTPS server will be exposed and set it via
KUMA_ADMIN_SERVER_PUBLIC_INTERFACE
. Optionally pick the port viaKUMA_ADMIN_SERVER_PUBLIC_PORT
. By default, it will be the same as the port for the HTTP server exposed on localhost. - Generate one or more certificates for the clients of this server. Pass the path to the directory with client certificates (without keys) via
KUMA_ADMIN_SERVER_PUBLIC_CLIENT_CERTS_DIR
. For generating self signed client certificates you can usekumactl
$ kumactl generate tls-certificate --cert-file=/path/to/cert --key-file=/path/to/key --type=client
- Configure
kumactl
with client certificate.
$ kumactl config control-planes add \
--name <NAME> --address http://<KUMA_CP_DNS_NAME>:5681 \
--admin-client-cert <CERT.PEM> \
--admin-client-key <KEY.PEM>
mTLS
Once a dataplane has proved its identity, it will be allowed to fetch its own identity certificate and a root CA certificate of the mesh. When establishing a connection between two dataplanes each side validates each other dataplane certificate confirming the identity using the root CA of the mesh.
mTLS is not enabled by default. To enable it, apply proper settings in Mesh policy. Additionally, when running on Universal you have to ensure that every dataplane in the mesh has been configured with a Dataplane Token.
TrafficPermission
When mTLS is enabled, every connection between dataplanes is denied by default, so you have to explicitly allow it using TrafficPermission.
Postgres
Since on Universal, the secrets such as “provided” CA’s private key, are stored in Postgres, a connection between Postgres and Kuma CP should be secured with TLS. To secure the connection, first pick the security mode using KUMA_STORE_POSTGRES_TLS_MODE
. There are several modes:
disable
- is not secured with TLS (secrets will be transmitted over network in plain text).verifyNone
- the connection is secured but neither hostname, nor by which CA the certificate is signed is checked.verifyCa
- the connection is secured and the certificate presented by the server is verified using the provided CA.verifyFull
- the connection is secured, certificate presented by the server is verified using the provided CA and server hostname must match the one in the certificate.
The CA for verification server’s certificate can be set using KUMA_STORE_POSTGRES_TLS_CA_PATH
.
Once secured connections are configured in Kuma CP, you have to configure Postgres’ pg_hba.conf
file to restrict unsecured connections. Here is an example configuration that will allow only TLS connections and will require username and password:
# TYPE DATABASE USER ADDRESS METHOD
hostssl all all 0.0.0.0/0 password
You can also provide client key and certificate for mTLS using KUMA_STORE_POSTGRES_TLS_CERT_PATH
and KUMA_STORE_POSTGRES_TLS_KEY_PATH
. This pair can be used for auth-method cert
described here.