# Postgres TLS

Bindplane supports TLS and mutual TLS when connecting to Postgres.

### Prerequisites

This guide assumes you already have Bindplane and Postgres deployed and configured. Before\
following this guide, make sure you have performed the steps in the previous [Postgres Store](https://docs.bindplane.com/how-to-guides/postgres/postgres-store) guide.

Lastly, the guide assumes you have already configured Postgres to use TLS or mutual TLS.

### SSL Mode

Before configuring TLS, familiarize yourself with the following Postgres SSL mode options. Bindplane\
supports four SSL mode options.

<table><thead><tr><th width="94.77734375">Mode</th><th>Description</th></tr></thead><tbody><tr><td>disable</td><td>TLS is not used.</td></tr><tr><td>require</td><td>TLS is used, but does not verify the server certificate.</td></tr><tr><td>verify-ca</td><td>TLS is used and verifies the server certificate.</td></tr><tr><td>verify-full</td><td>Same as <code>verify-ca</code>, but with mutual TLS and a client TLS key pair is configured.</td></tr></tbody></table>

You can review the official descriptions [here](https://www.postgresql.org/docs/current/libpq-ssl.html). Keep in mind that Bindplane supports a subset of the options found in the official Postgres documentation.

### Linux

When operating Bindplane on Linux, you can enable TLS by editing the configuration file at `/etc/bindplane/config.yaml`.

Find the `store` section and modify the `store.postgres` sub section.

```yaml
store:
  type: postgres
  maxEvents: 100
  postgres:
    host: bindplane-postgres
    port: "5432"
    connectTimeout: 30s
    database: bindplane
    username: bindplane
    password: your_password
    maxConnections: 100
    sslmode: disable
```

Modify `store.postgres.sslmode` to `require` or `verify-ca`. If using `verify-ca`, configure a certificate authority by setting `store.postgres.sslRootCert` to the path of a CA certificate file that can be used to verify the Postgres server's authenticity.

The resulting configuration file should look similar to this:

```yaml
store:
  type: postgres
  maxEvents: 100
  postgres:
    host: bindplane-postgres
    port: "5432"
    connectTimeout: 30s
    database: bindplane
    username: bindplane
    password: your_password
    maxConnections: 100
+   sslmode: verify-ca
+   sslRootCert: /etc/bindplane/tls/postgres-ca.crt
```

{% hint style="info" %}
**NOTE**

`sslRootCert` is not required when using `verify-ca` if the operating system's trust store\
includes your CA certificate.
{% endhint %}

Mutual TLS can be configured by setting `sslmode` to `verify-full` and including the `sslCert` and `sslKey` options.

```yaml
store:
  type: postgres
  maxEvents: 100
  postgres:
    host: bindplane-postgres
    port: "5432"
    connectTimeout: 30s
    database: bindplane
    username: bindplane
    password: your_password
    maxConnections: 100
+   sslmode: verify-full
+   sslRootCert: /etc/bindplane/tls/postgres-ca.crt
+   sslCert: /etc/bindplane/tls/client.crt
+   sslKey: /etc/bindplane/tls/client.key
```

When copying certificates to the Bindplane server, set the filesystem ownership and permissions.

```bash
sudo chown -R bindplane:bindplane /etc/bindplane/tls
sudo chmod 0400 /etc/bindplane/tls/*
```

After you have re-configured Bindplane and deployed the TLS files, restart the service.

```bash
sudo systemctl restart bindplane
```

Watch the Bindplane log file for issues.

```bash
sudo tail -F /var/log/bindplane/bindplane.log
```

If the service appears stopped, and the log file is not useful, check the journal output of the service.

```bash
sudo journalctl -f --unit bindplane
```

If no errors are encountered, Bindplane is correctly configured to use TLS when connecting to Postgres.

### Kubernetes

The [Bindplane Helm Chart](https://github.com/observIQ/bindplane-op-helm/tree/main) supports configuring Bindplane to use TLS by leveraging Kubernetes secrets.

Assuming you have the following files:

* `ca.crt`: The CA certificate
* `client.crt`: The mutual TLS client certificate (optional)
* `client.key`: The mutual TLS client private key (optional)

Create a Kubernetes secret. Omit the client keypair if you do not intend to use mutual TLS.

```bash
kubectl create secret generic postgres-tls \
  --from-file ca.crt \
  --from-file client.crt \
  --from-file client.key
```

Update your values configuration to include the `sslmode` and `sslsecret` options. Use sslmode `verify-ca` and omit the client keypair if you are not using mutual tls.

```yaml
backend:
  type: postgres
  postgres:
    host: postgres.postgres.svc.cluster.local
    database: bindplane
    username: postgres
    password: password
    maxConnections: 20
+   sslmode: verify-full # Use verify-ca if not using mutual TLS
+   sslsecret:
+     name: postgres-tls
+     sslrootcertSubPath: ca.crt
+     sslcertSubPath: client.crt # Optional, for mutual TLS
+     sslkeySubPath: client.key # Optional, for mutual TLS
```

Upgrade your Helm deployment to apply the changes. The Bindplane pods should restart without startup errors. If the new Bindplane pod(s) enter a crashloop, check their logs to investigate the error. If the pods come up successfully, TLS is configured and working.
