mirror of
https://gitlab.opencode.de/bmi/opendesk/deployment/opendesk.git
synced 2025-12-08 00:11:38 +01:00
291 lines
13 KiB
Markdown
291 lines
13 KiB
Markdown
<!--
|
||
SPDX-FileCopyrightText: 2024 Zentrum für Digitale Souveränität der Öffentlichen Verwaltung (ZenDiS) GmbH
|
||
SPDX-License-Identifier: Apache-2.0
|
||
-->
|
||
|
||
<h1>Self-signed certificates and custom Certificate Authority (CA)</h1>
|
||
|
||
<!-- TOC -->
|
||
* [Configuration](#configuration)
|
||
* [Option 1: Bring Your Own Certificate](#option-1-bring-your-own-certificate)
|
||
* [Option 2a: Use cert-manager.io with auto-generated namespace based root-certificate](#option-2a-use-cert-managerio-with-auto-generated-namespace-based-root-certificate)
|
||
* [Option 2b: Use cert-manager.io with a pre-defined or shared root-certificate](#option-2b-use-cert-managerio-with-a-pre-defined-or-shared-root-certificate)
|
||
<!-- TOC -->
|
||
|
||
This document covers:
|
||
* Deploying openDesk into an environment with custom public key infrastructure (PKI) that is usually not part of
|
||
public certificate authority chains
|
||
* deploying openDesk into a local cluster without ACME challenge
|
||
|
||
# Configuration
|
||
|
||
There are two options to address these use case:
|
||
|
||
## Option 1: Bring Your Own Certificate
|
||
|
||
This option is useful when you have your own PKI in your environment which is also trusted by all clients that should
|
||
access openDesk.
|
||
|
||
To help others with this section, we document the certificate creation, so
|
||
please ensure that `openssl` is installed on your system.
|
||
|
||
1. Create the Certificate Authority (CA) private key:
|
||
```/bin/bash
|
||
$ openssl genrsa -aes256 -out ca-private_key.pem 2048
|
||
Enter PEM pass phrase:
|
||
Verifying - Enter PEM pass phrase:
|
||
```
|
||
|
||
2. Create the public certficiate for the Certificate Authority (CA):
|
||
```/bin/bash
|
||
$ openssl req -x509 -new -nodes -extensions v3_ca -key ca-private_key.pem -days 1024 -out ca-cert.crt -sha512
|
||
Enter pass phrase for ca-private_key.pem:
|
||
You are about to be asked to enter information that will be incorporated
|
||
into your certificate request.
|
||
What you are about to enter is what is called a Distinguished Name or a DN.
|
||
There are quite a few fields but you can leave some blank
|
||
For some fields there will be a default value,
|
||
If you enter '.', the field will be left blank.
|
||
-----
|
||
Country Name (2 letter code) [AU]:DE
|
||
State or Province Name (full name) [Some-State]:
|
||
Locality Name (eg, city) []:
|
||
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
|
||
Organizational Unit Name (eg, section) []:
|
||
Common Name (e.g. server FQDN or YOUR name) []:
|
||
Email Address []:
|
||
```
|
||
|
||
3. Generate the Java keystore (JKS) file `truststore.jks` with the CA certficiate (requires the Java SDK):
|
||
```/bin/bash
|
||
$ export TRUSTSTORE_PASSWORD="passwordForTruststore.jks"
|
||
$ keytool -import -file ca-cert.crt -keystore truststore.jks -storepass "$TRUSTSTORE_PASSWORD"
|
||
Owner: O=Internet Widgits Pty Ltd, ST=Some-State, C=DE
|
||
Issuer: O=Internet Widgits Pty Ltd, ST=Some-State, C=DE
|
||
Serial number: ccb2fc7257ebb602de0b74394cb1c009806f706
|
||
Valid from: Wed Dec 03 16:31:39 UTC 2025 until: Fri Sep 22 16:31:39 UTC 2028
|
||
Certificate fingerprints:
|
||
SHA1: AE:6F:55:AA:45:B4:A2:E1:E2:96:18:CF:FC:C0:5D:4B:56:0E:C4:26
|
||
SHA256: 95:C0:0E:44:B7:92:86:B7:D9:74:F4:4C:64:81:BA:E2:BE:75:90:03:56:0F:5F:9D:B5:85:A1:4C:82:54:19:8E
|
||
Signature algorithm name: SHA512withRSA
|
||
Subject Public Key Algorithm: 2048-bit RSA key
|
||
Version: 3
|
||
|
||
Extensions:
|
||
|
||
#1: ObjectId: 2.5.29.35 Criticality=false
|
||
AuthorityKeyIdentifier [
|
||
KeyIdentifier [
|
||
0000: 6A 64 5A 67 5E 11 8D B2 55 7B 53 0A 20 5C 9D 4D jdZg^...U.S. \.M
|
||
0010: 9A E8 C0 DD ....
|
||
]
|
||
]
|
||
|
||
#2: ObjectId: 2.5.29.19 Criticality=true
|
||
BasicConstraints:[
|
||
CA:true
|
||
PathLen: no limit
|
||
]
|
||
|
||
#3: ObjectId: 2.5.29.14 Criticality=false
|
||
SubjectKeyIdentifier [
|
||
KeyIdentifier [
|
||
0000: 6A 64 5A 67 5E 11 8D B2 55 7B 53 0A 20 5C 9D 4D jdZg^...U.S. \.M
|
||
0010: 9A E8 C0 DD ....
|
||
]
|
||
]
|
||
|
||
Trust this certificate? [no]: yes
|
||
Certificate was added to keystore
|
||
```
|
||
|
||
4. Generate the private key and certificate request for the OpenDesk certificate (assuming a wildcard domain: '.opendesk-test.example.com'), use supply [all required subdomains](../../helmfile/environments/default/global.yaml.gotmpl)
|
||
as SANs (Subject Alternative Name):
|
||
```/bin/bash
|
||
$ openssl req -newkey rsa:2048 -nodes -keyout opendesk-cert-key.key -out opendesk-cert-request.csr -subj "/C=DE/O=OpenDesk Test/CN=opendesk-test.example.com" -addext "subjectAltName = DNS:opendesk-test.example.com,DNS:*.opendesk-test.example.com"
|
||
....+...+..+.+.....+....+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....+....+...............+.....+.......+..+......+....+......+.....+.........+.......+.....+....+......+........+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*......................+..+.+......+...+........+...+.+..............................+.....+...+...+....+......+...............+.....+...+......+...+.+..+.........+.............+.....+...+.......+......+......+.....+....+..+...+.......+..............+...............+.+..+.......+...+..+.........+.+........+.+....................+..........+..+....+.....+.+.....+.......+...+........+................+...+..+...+..........+......+......+...+..+.+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
.........+.......+..+................+..+..........+...+..+...+.+...+..+....+............+.....+.........+.+..+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*................+..+...+.............+..+.......+............+...+...........+.......+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+.......+.....+..........+........+...+................+........+.+.....+......+.........+......+.+..+.......+.....+....+...........+....+......+...+......+...............+..+...+.+.....+.........+.+.........+..+...+....+..+..........+.....+....+............+..+...+............+.+......+...+........+....+.....+.+.........+.....+...+.+..+.........+................+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
-----
|
||
```
|
||
|
||
5. Sign the `opendesk-cert-request.csr` with the CA certficiate:
|
||
```/bin/bash
|
||
$ openssl x509 -req -in opendesk-cert-request.csr -days 365 -CA ca-cert.crt -CAkey ca-private_key.pem -CAcreateserial -out opendesk-cert.crt -copy_extensions copy
|
||
Certificate request self-signature ok
|
||
subject=C = DE, O = OpenDesk Test, CN = opendesk-test.example.com
|
||
Enter pass phrase for ca-private_key.pem:
|
||
```
|
||
|
||
6. Control the certificate (X509v3 Subject Alternative Name must be given for the wildcard DNS):
|
||
```/bin/bash
|
||
$ openssl x509 -in opendesk-cert.crt -noout -text
|
||
Certificate:
|
||
Data:
|
||
Version: 3 (0x2)
|
||
Serial Number:
|
||
15:be:c5:3b:f9:87:e2:89:3c:17:da:78:5f:ae:0e:4e:dc:b9:86:47
|
||
Signature Algorithm: sha256WithRSAEncryption
|
||
Issuer: C = DE, ST = Some-State, O = Test Organization Name
|
||
Validity
|
||
Not Before: Dec 4 08:17:17 2025 GMT
|
||
Not After : Dec 4 08:17:17 2026 GMT
|
||
Subject: C = DE, O = OpenDesk Test, CN = opendesk-test.example.com
|
||
Subject Public Key Info:
|
||
Public Key Algorithm: rsaEncryption
|
||
Public-Key: (2048 bit)
|
||
Modulus:
|
||
00:86:68:e3:5b:d1:fd:3c:44:01:08:99:0c:82:0c:
|
||
53:50:0c:4a:b2:59:30:ae:a2:6b:b0:a4:33:1b:e1:
|
||
39:d1:8c:71:8a:a0:60:c4:26:2c:1a:74:66:6d:77:
|
||
4e:1d:4f:0a:c2:c7:83:ac:20:09:eb:f2:ee:b1:19:
|
||
85:71:6c:f6:dc:4a:ef:d9:87:10:db:ff:b6:0b:ce:
|
||
6a:3a:c9:aa:08:9b:a0:b1:6d:d5:db:41:e3:58:98:
|
||
87:78:51:ff:2c:6b:19:e6:f2:7d:a3:91:5a:e6:fd:
|
||
08:f9:e5:be:19:1d:74:2c:1c:ee:1e:3a:39:3c:6a:
|
||
31:40:f2:7b:e3:ad:a8:f5:1a:fd:92:8e:c4:f6:89:
|
||
1b:e2:d4:e3:dc:f5:bc:3e:85:6e:08:3a:20:73:61:
|
||
96:4a:85:70:93:e9:17:a5:8e:78:54:34:26:83:a9:
|
||
44:17:7f:5d:49:19:ee:e0:ce:73:b5:c6:0d:4c:19:
|
||
7b:33:78:41:8b:80:2f:4b:bf:1d:70:77:fc:21:90:
|
||
6f:bd:ec:1e:12:38:a2:56:42:b8:c0:c9:b3:0c:be:
|
||
b7:9a:fb:82:38:c8:0c:aa:6c:3e:84:f7:82:cf:1d:
|
||
c5:9f:79:01:75:50:58:3d:92:22:e1:0c:9e:b4:7a:
|
||
45:76:ec:98:69:2a:fe:ed:89:44:6e:b2:ba:6c:2b:
|
||
2a:b7
|
||
Exponent: 65537 (0x10001)
|
||
X509v3 extensions:
|
||
X509v3 Subject Alternative Name:
|
||
DNS:opendesk-test.example.com, DNS:*.opendesk-test.example.com
|
||
X509v3 Subject Key Identifier:
|
||
3B:8F:7B:9F:A8:4B:10:72:7E:AC:1D:0A:24:51:5E:42:E7:C1:BB:AA
|
||
X509v3 Authority Key Identifier:
|
||
32:C0:EB:DE:3F:05:1A:7F:88:0D:49:05:A7:E1:56:28:CF:90:E0:E2
|
||
Signature Algorithm: sha256WithRSAEncryption
|
||
Signature Value:
|
||
98:48:ec:04:0a:53:c5:25:66:ff:1c:bd:ab:09:a2:9f:c3:ba:
|
||
d8:d8:c9:d8:47:dd:d6:08:70:5d:6b:0c:e4:2b:cd:ef:2f:06:
|
||
6c:5c:09:58:c1:72:df:d1:13:e3:c4:6e:9a:6a:cf:b4:cc:4a:
|
||
58:35:26:28:cb:b6:1f:f8:fa:e9:07:1a:0d:ba:01:1f:08:ac:
|
||
65:08:e7:23:25:42:f6:66:6e:11:a0:ef:73:c3:8b:dd:69:2e:
|
||
47:bf:59:c8:c1:6c:05:31:be:82:81:9d:be:f2:b3:61:a4:af:
|
||
a1:79:24:6a:26:1f:54:81:a0:eb:b0:ee:e3:7b:a2:2f:e7:74:
|
||
6e:71:cd:76:5d:65:18:14:6b:da:79:5c:3a:11:ec:11:95:6e:
|
||
ec:62:1f:77:7c:e6:7b:cb:d7:dd:46:8b:40:30:7c:2d:20:55:
|
||
99:25:05:05:37:b9:ff:06:1b:23:b2:58:88:ac:e5:75:06:a0:
|
||
73:72:50:d0:4e:bd:52:ab:3c:56:c2:1a:3d:5e:b5:ac:1c:d1:
|
||
f3:fb:29:e3:f5:bd:74:05:72:fc:b0:74:54:3c:67:45:19:76:
|
||
29:3c:3c:5a:57:9f:bd:8c:58:ff:9c:f3:08:99:1d:86:0a:59:
|
||
be:77:5d:b2:a4:6a:6e:d8:6d:fa:7e:cc:d1:99:6e:d3:19:9a:
|
||
84:b8:24:98
|
||
```
|
||
|
||
You can now use the `truststore.jks`, `opendesk-cert.crt`, `opendesk-cert-key.key` and `ca-cert.crt` for the secrets.
|
||
|
||
7. Import the certificates into the Kubernetes cluster through kubernetes secrets:
|
||
|
||
```/bin/bash
|
||
$ export KUBERNETES_NAMESAPCE="dev"
|
||
$ kubectl config set-context --current --namespace="$KUBERNETES_NAMESAPCE"
|
||
Context "default" modified.
|
||
|
||
# Generate the TLS secret
|
||
$ kubectl create secret tls opendesk-certificates-tls --key opendesk-cert-key.key --cert opendesk-cert.crt
|
||
secret/opendesk-certificates-tls created
|
||
|
||
|
||
# Generate the CA secret
|
||
$ kubectl create secret generic opendesk-certificates-ca-tls --from-file=ca.crt=ca-cert.crt --from-file truststore.jks
|
||
secret/opendesk-certificates-ca-tls created
|
||
```
|
||
|
||
8. Disable cert-manager.io certificate resource creation:
|
||
|
||
```yaml
|
||
certificates:
|
||
enabled: false
|
||
```
|
||
|
||
9. Enable mount of self-signed certificates:
|
||
|
||
```yaml
|
||
certificate:
|
||
selfSigned: true
|
||
caCertificate:
|
||
create: false
|
||
```
|
||
|
||
10. Save the password for the generated JKS trust store (`truststore.jks`):
|
||
|
||
```yaml
|
||
secrets:
|
||
certificates:
|
||
# The password from $TRUSTSTORE_PASSWORD
|
||
password: "passwordForTruststore.jks"
|
||
```
|
||
|
||
> [!note]
|
||
> If your OpenDesk applications access services from the internet, you have to append the relevant CA certificates
|
||
> to the `ca.crt`certificate. You can use the file `/etc/ssl/certs/ca-certificates.crt` from Debian distro. The CA certificate
|
||
> (`ca.crt`) can contain multiple certificates but keep in mind, that the `truststore.jks` must be updated as well.
|
||
|
||
|
||
## Option 2a: Use cert-manager.io with auto-generated namespace based root-certificate
|
||
|
||
This option is useful when you do not have a trusted certificate available and can't fetch a certificate from
|
||
Let’s Encrypt. It will result in a cert-manager managed root certificate in the namespace you deploy openDesk into.
|
||
|
||
1. Create self-signed cert-manager.io Cluster Issuer:
|
||
```yaml
|
||
apiVersion: "cert-manager.io/v1"
|
||
kind: "ClusterIssuer"
|
||
metadata:
|
||
name: "selfsigned-issuer"
|
||
spec:
|
||
selfSigned: {}
|
||
```
|
||
|
||
2. Enable mount and creation of self-signed certificates:
|
||
```yaml
|
||
certificate:
|
||
issuerRef:
|
||
name: "selfsigned-issuer"
|
||
selfSigned: true
|
||
```
|
||
|
||
## Option 2b: Use cert-manager.io with a pre-defined or shared root-certificate
|
||
|
||
Use this approach if you like to use a pre-created CA root certificate that can be "shared" (as copy) between
|
||
multiple namespaces in a cluster.
|
||
|
||
1. Create self-signed cert-manager.io Cluster Issuer root certificate the same way as in *Option 2a*.
|
||
|
||
2. Create the root certificate for the previously created CA, in the example it is placed into the namespace `cert-manager`.
|
||
```yaml
|
||
apiVersion: cert-manager.io/v1
|
||
kind: Certificate
|
||
metadata:
|
||
name: opendesk-root
|
||
namespace: cert-manager
|
||
spec:
|
||
isCA: true
|
||
commonName: opendesk.eu
|
||
secretName: opendesk-root-cert-secret
|
||
subject:
|
||
organizations: [ "openDesk cluster root certificate organization" ]
|
||
privateKey:
|
||
algorithm: ECDSA
|
||
size: 256
|
||
issuerRef:
|
||
name: selfsigned-issuer
|
||
kind: ClusterIssuer
|
||
group: cert-manager.io
|
||
duration: 87600h # 10y
|
||
renewBefore: 87599h
|
||
```
|
||
|
||
3. Copy this certificates secret into all namespaces you want to make use of the certificate in.
|
||
|
||
4. Create an issuer resource in all namespaces you want to make use of the certificate in.
|
||
|
||
>The latter two steps are part of the `env-start:` section within [`.gitlab-ci.yml`](../../.gitlab-ci.yml).
|