# Set up CA for mTLS

We are using [mTLS](https://www.cloudflare.com/de-de/learning/access-management/what-is-mutual-tls/) to secure the connection between the main server and the rendering servers. You will have to set up your own Certificate Authority (CA) and create a certificate for each server. All servers with a certificate from the same CA will be able to communicate with each other. **Do not use a certificate from an CA you don't own!**

## Preparations

**1. Install openssl**

`apt install openssl` on ubuntu/debian based systems

`pacman -Syu openssl` on archlinux based systems

**2. Create a new directory for your CA and cd into it:**

`mkdir my-ca && cd my-ca`

**3. Create CA config**

Create a new file `ca.conf` with this content:

```
[ca]
default_ca = default

[default]
dir = .
certs = $dir
new_certs_dir = $dir/db.certs

database = $dir/db.index
serial = $dir/db.serial

certificate = $dir/root.crt
private_key = $dir/root.key

default_days = 365
default_crl_days = 30

default_md = sha256

preserve = no
policy = default_policy

[default_policy]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = supplied
organizationalUnitName = supplied
commonName = supplied
emailAddress = optional

[crl_ext]
authorityKeyIdentifier=keyid:always

[ usr_cert ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth
authorityKeyIdentifier = keyid,issuer
subjectKeyIdentifier = hash
subjectAltName = $ENV::SAN
```

**4. Initialize CA directories and files**

```bash
mkdir -p db.certs input output
touch db.index
echo "01" > db.serial
```

**5. Generate CA private key &amp; cert**

```bash
openssl ecparam -name prime256v1 -genkey -noout -out root.key
openssl req -new -x509 -key root.key -out root.crt -days 3650 -sha256
```

<p class="callout danger">**Important:** keep all private keys secure, especially the CA private key!   
If leaked, anyone can connect to your main / rendering server.</p>

**6. Generate certificate revocation list &amp; convert to correct format**

```bash
export SAN="DNS:<hostname>"
openssl ca -config ca.conf -gencrl -out crl.pem
openssl crl -in crl.pem -out crl.der -outform DER
```

## **Create &amp; Sign certificates**

You successfully set up your own CA, now you can create and sign certificates for each of your servers.

**On each server:** Generate the private key &amp; certificate signing request:

```bash
openssl ecparam -name prime256v1 -genkey -noout -out client.key
openssl req -new -key client.key -out client.csr -sha256
```

<p class="callout warning">Make sure to use a different common name for each certificate! Also make sure to supply an organizationalUnitName.</p>

Transfer the .csr file to the system with your CA certificate.

**On the CA host:**

Set the SAN &amp; sign with your CA. **Replace &lt;hostname&gt; with your server's hostname!** Adjust the file names if needed.

```bash
export SAN="DNS:<hostname>"
openssl ca -config ca.conf -in client.csr -out client.crt -days 3650 -extensions usr_cert
```

Transfer the created certificate (e.g. client.crt) back to the server.