Files
opendesk/docs/enhanced-configuration/self-signed-certificates.md
2025-12-04 14:52:29 +01:00

13 KiB
Raw Permalink Blame History

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.

  1. 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:
    
  2. 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 []:
    
  3. Generate the Java keystore (JKS) file truststore.jks with 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
    
  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 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"
    ....+...+..+.+.....+....+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....+....+...............+.....+.......+..+......+....+......+.....+.........+.......+.....+....+......+........+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*......................+..+.+......+...+........+...+.+..............................+.....+...+...+....+......+...............+.....+...+......+...+.+..+.........+.............+.....+...+.......+......+......+.....+....+..+...+.......+..............+...............+.+..+.......+...+..+.........+.+........+.+....................+..........+..+....+.....+.+.....+.......+...+........+................+...+..+...+..........+......+......+...+..+.+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    .........+.......+..+................+..+..........+...+..+...+.+...+..+....+............+.....+.........+.+..+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*................+..+...+.............+..+.......+............+...+...........+.......+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+.......+.....+..........+........+...+................+........+.+.....+......+.........+......+.+..+.......+.....+....+...........+....+......+...+......+...............+..+...+.+.....+.........+.+.........+..+...+....+..+..........+.....+....+............+..+...+............+.+......+...+........+....+.....+.+.........+.....+...+.+..+.........+................+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    -----
    
  5. Sign the opendesk-cert-request.csr with 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:
    
  6. 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.

  1. 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
  1. Disable cert-manager.io certificate resource creation:

    certificates:
      enabled: false
    
  2. Enable mount of self-signed certificates:

    certificate:
      selfSigned: true
      caCertificate:
        create: false
    
  3. 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.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 Lets 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:

    apiVersion: "cert-manager.io/v1"
    kind: "ClusterIssuer"
    metadata:
      name: "selfsigned-issuer"
    spec:
      selfSigned: {}
    
  2. 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.

  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.

    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.