# Transport Layer Security (TLS) The Percona Operator for PostgreSQL uses Transport Layer Security (TLS) cryptographic protocol for the following types of communication: * Internal - communication between PostgreSQL instances in the cluster * External - communication between the client application and the cluster The internal certificate is also used as an authorization method for PostgreSQL Replica instances. TLS security can be configured in several ways: * the Operator can generate certificates automatically at cluster creation time, * you can also generate certificates manually. You can also use pre-generated certificates available in the `deploy/ssl-secrets.yaml` file for test purposes, but we strongly recommend **avoiding their usage on any production system**! The following subsections explain how to configure TLS security with the Operator yourself, as well as how to temporarily disable it if needed. ## Allow the Operator to generate certificates automatically The Operator is able to generate long-term certificates automatically and turn on encryption at cluster creation time, if there are no certificate secrets available. It generates certificates with the help of [cert-manager](https://cert-manager.io/docs/) - a Kubernetes certificate management controller widely used to automate the management and issuance of TLS certificates. Cert-manager is community-driven and open source. ### Installation of the *cert-manager* You can install *cert-manager* as follows: * Create a namespace, * Disable resource validations on the cert-manager namespace, * Install the cert-manager. The following commands perform all the needed actions: ``` {.bash data-prompt="$" } $ kubectl create namespace cert-manager $ kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true $ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v{{ certmanagerversion }}/cert-manager.yaml ``` After the installation, you can verify the *cert-manager* by running the following command: ``` {.bash data-prompt="$" } $ kubectl get pods -n cert-manager ``` The result should display the *cert-manager* and webhook active and running. ### Turning automatic generation of certificates on When you have already installed *cert-manager*, the operator is able to request a certificate from it. To make this happend, uncomment `sslCA`, `sslSecretName`, and `sslReplicationSecretName` options in the `deploy/cr.yaml` configuration file: ```yaml ... spec: # secretsName: cluster1-users sslCA: cluster1-ssl-ca sslSecretName: cluster1-ssl-keypair sslReplicationSecretName: cluster1-ssl-keypair ... ``` When done, deploy your cluster as usual, with the `kubectl apply -f deploy/cr.yaml` command. Certificates will be generated if there are no certificate secrets available. ## Generate certificates manually To generate certificates manually, follow these steps: 1. Provision a to generate TLS certificates, 2. Generate a key and certificate file with the server details, 3. Create the server TLS certificates using the keys, certs, and server details. The set of commands generates certificates with the following attributes: * `Server-pem` - Certificate * `Server-key.pem` - the private key * `ca.pem` - Certificate Authority You should generate one set of certificates for external communications, and another set for internal ones. Supposing that your cluster name is `cluster1`, you can use the following commands to generate certificates: ``` {.bash data-prompt="$" } $ CLUSTER_NAME=cluster1 $ NAMESPACE=default $ cat < ca-config.json { "signing": { "default": { "expiry": "87600h", "usages": ["digital signature", "key encipherment", "content commitment"] } } } EOF $ cat <` placeholder): ``` {.bash data-prompt="$" } $ cat <-ssl-ca items: - key: ca.crt path: ca.crt mode: 0777 EOF ``` Now get shell access to the newly created container, and launch the PostgreSQL interactive terminal to check connectivity over the encrypted channel (please use real cluster-name, PostgreSQL user login and password): ``` {.bash data-prompt="$" data-prompt-second="[postgres@pg-client /]$"} $ kubectl exec -it deployment/pg-client -- bash -il [postgres@pg-client /]$ PGSSLMODE=verify-ca PGSSLROOTCERT=/tmp/tls/ca.crt psql postgres://:@-pgbouncer..svc.cluster.local ``` Now you should see the prompt of PostgreSQL interactive terminal: ``` {.bash data-prompt="$" data-prompt-second="pgdb=>"} $ psql ({{ postgresrecommended }}) Type "help" for help. pgdb=> ``` ## Run Percona Distribution for PostgreSQL without TLS Omitting TLS is also possible, but we recommend that you run your cluster with the TLS protocol enabled. To disable TLS protocol (e.g. for demonstration purposes) set the `spec.tlsOnly` key to `false`, and make sure that there are no certificate secrets configured in the `deploy/cr.yaml` file.