13 KiB
Self-signed certificates and custom Certificate Authority (CA)
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.
-
Create the Certificate Authority (CA) private key:
$ openssl genrsa -aes256 -out ca-private_key.pem 2048 Enter PEM pass phrase: Verifying - Enter PEM pass phrase: -
Create the public certficiate for the Certificate Authority (CA):
$ 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 []: -
Generate the Java keystore (JKS) file
truststore.jkswith the CA certficiate (requires the Java SDK):$ 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 -
Generate the private key and certificate request for the OpenDesk certificate (assuming a wildcard domain: '.opendesk-test.example.com'), use supply all required subdomains as SANs (Subject Alternative Name):
$ 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" ....+...+..+.+.....+....+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....+....+...............+.....+.......+..+......+....+......+.....+.........+.......+.....+....+......+........+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*......................+..+.+......+...+........+...+.+..............................+.....+...+...+....+......+...............+.....+...+......+...+.+..+.........+.............+.....+...+.......+......+......+.....+....+..+...+.......+..............+...............+.+..+.......+...+..+.........+.+........+.+....................+..........+..+....+.....+.+.....+.......+...+........+................+...+..+...+..........+......+......+...+..+.+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .........+.......+..+................+..+..........+...+..+...+.+...+..+....+............+.....+.........+.+..+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*................+..+...+.............+..+.......+............+...+...........+.......+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+.......+.....+..........+........+...+................+........+.+.....+......+.........+......+.+..+.......+.....+....+...........+....+......+...+......+...............+..+...+.+.....+.........+.+.........+..+...+....+..+..........+.....+....+............+..+...+............+.+......+...+........+....+.....+.+.........+.....+...+.+..+.........+................+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ----- -
Sign the
opendesk-cert-request.csrwith the CA certficiate:$ 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: -
Control the certificate (X509v3 Subject Alternative Name must be given for the wildcard DNS):
$ 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.
- Import the certificates into the Kubernetes cluster through kubernetes secrets:
$ 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
-
Disable cert-manager.io certificate resource creation:
certificates: enabled: false -
Enable mount of self-signed certificates:
certificate: selfSigned: true caCertificate: create: false -
Save the password for the generated JKS trust store (
truststore.jks):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.crtcertificate. You can use the file/etc/ssl/certs/ca-certificates.crtfrom Debian distro. The CA certificate (ca.crt) can contain multiple certificates but keep in mind, that thetruststore.jksmust 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.
-
Create self-signed cert-manager.io Cluster Issuer:
apiVersion: "cert-manager.io/v1" kind: "ClusterIssuer" metadata: name: "selfsigned-issuer" spec: selfSigned: {} -
Enable mount and creation of self-signed certificates:
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.
-
Create self-signed cert-manager.io Cluster Issuer root certificate the same way as in Option 2a.
-
Create the root certificate for the previously created CA, in the example it is placed into the namespace
cert-manager.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 -
Copy this certificates secret into all namespaces you want to make use of the certificate in.
-
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.