|
| 1 | +# Mutual TLS with client certificates |
| 2 | + |
| 3 | +Nginx Dogu supports client authentication using certificates (Mutual TLS). When this feature is enabled, |
| 4 | +Nginx requests a certificate from the client during the TLS handshake and validates it against a stored |
| 5 | +Certificate Authority (CA). |
| 6 | + |
| 7 | +## Configuration |
| 8 | + |
| 9 | +The configuration is done via the Dogu configuration `mutual_tls/enabled`. |
| 10 | + |
| 11 | +> [!IMPORTANT] |
| 12 | +> Split DNS must be configured for authentication with client certificates to work. |
| 13 | +> See [Split DNS](#split-dns) |
| 14 | +
|
| 15 | +### 1. Store CA certificate |
| 16 | + |
| 17 | +In order for Nginx to validate the client certificates, the public certificate of the CA must be known globally in the CES. |
| 18 | +The CA certificate must be stored in PEM format in the global configuration: |
| 19 | + |
| 20 | +```bash |
| 21 | +cat client-ca.crt | etcdctl set /config/_global/certificate/client-ca.crt |
| 22 | +``` |
| 23 | + |
| 24 | +> Note: A CA certificate can be generated as follows, for example: |
| 25 | +> 1. Generate key: `openssl genrsa -out client-ca.key 4096` |
| 26 | +> 2. Create certificate: ` openssl req -x509 -new -nodes -key client-ca.key -sha256 -days 3650 -out client-ca.crt -subj "/C=DE/O=MyOrg/CN=MyOrg Client Root CA` |
| 27 | +
|
| 28 | + |
| 29 | +### 2. Enable authentication |
| 30 | + |
| 31 | +Client authentication is disabled by default. It can be enabled via the Dogu config of nginx: |
| 32 | + |
| 33 | +```bash |
| 34 | +etcdctl set /config/nginx/mutual_tls/enabled true |
| 35 | +``` |
| 36 | + |
| 37 | +After making this change, the Nginx Dogu must be restarted so that the CA certificate is loaded from the registry and the |
| 38 | +configuration is regenerated. |
| 39 | + |
| 40 | +## How it works |
| 41 | + |
| 42 | +Once `mutual_tls/enabled` is set to `true`: |
| 43 | + |
| 44 | +1. The `startup.sh` script extracts the CA certificate from the global registry to `/etc/ssl/client-ca.crt`. |
| 45 | +2. The `ssl.conf` activates the Nginx directives `ssl_client_certificate` and `ssl_verify_client on`. |
| 46 | + |
| 47 | +### Exception for internal Dogu requests |
| 48 | +To enable Dogus to send requests to other Dogus without a client certificate (e.g., to validate the CAS session), |
| 49 | +an exception is created in `nginx.conf` for all requests originating from the internal Docker network (`172.18.0.1/32`). |
| 50 | + |
| 51 | +#### Split DNS |
| 52 | +For this to work, split DNS must be configured accordingly. |
| 53 | +When installing the CES, this can be configured in setup.json under `useInternalIp` or `internalIp`. See: https://docs.cloudogu.com/de/docs/system-components/ces-setup/operations/setup-json/#useinternalip |
| 54 | + |
| 55 | +This creates a corresponding entry in the `/etc/hosts` of the CES instance. |
| 56 | +To configure a CES instance for split DNS after installation, a corresponding entry must be stored in `/etc/hosts` for the internal IP. |
| 57 | +For example: |
| 58 | +``` |
| 59 | +<internal IP> <DNS name> |
| 60 | +172.18.0.1 ces.example.com |
| 61 | +``` |
| 62 | + |
| 63 | +After that, all Dogus must be restarted once. |
| 64 | + |
| 65 | +## Generate a client certificate |
| 66 | +The following steps are necessary to generate a client certificate: |
| 67 | + |
| 68 | +1. Generate user key: `openssl genrsa -out client1.key 4096` |
| 69 | +2. Generate a certificate signing request (CSR): `openssl req -new -key client1.key -out client1.csr -subj “/C=DE/O=MyOrg/OU=Clients/CN=client1”` |
| 70 | +3. Generate client extension file: |
| 71 | +```bash |
| 72 | + cat > client.ext <<‘EOF’ |
| 73 | + basicConstraints = CA:FALSE |
| 74 | + keyUsage = digitalSignature, keyEncipherment |
| 75 | + extendedKeyUsage = clientAuth |
| 76 | + subjectKeyIdentifier = hash |
| 77 | + EOF |
| 78 | + ``` |
| 79 | +4. Sign CSR: `openssl x509 -req -in client1.csr -CA client-ca.crt -CAkey client-ca.key -CAcreateserial -out client1.crt -days 365 -sha256 -extfile client.ext` |
| 80 | +5. Export client certificate: `openssl pkcs12 -export -inkey client1.key -in client1.crt -certfile client-ca.crt -name “client1” -out client1.p12` |
| 81 | + > Note: A password must be entered when exporting. |
| 82 | +
|
| 83 | +The exported certificate can now be imported into the browser. |
0 commit comments