Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DER and PEM support #1

Closed
wants to merge 3 commits into from
Closed

DER and PEM support #1

wants to merge 3 commits into from

Conversation

maelvls
Copy link
Owner

@maelvls maelvls commented Nov 22, 2021

At first, I wanted to "add features" (DER support); I quickly realized that I did not understand why this issue existed in the first place. I spent a few hours investigating why people have issues and need PKCS#12, JKS, PKCS#8 DER, combined PEM... I wrote the various "use-cases" that I found along the way. After this investigation, I found only two useful transformations:

  • Transform the tls.key into a PKCS#8-formated DER-encoded binary private key. To use this mode, annotate your Secret with the following annotations:

    kind: Secret
    metadata:
      annotations:
        secret-transform-in: tls.key
        secret-transform-out: tls.der # Any name with the extension `.der` or `.pk8`.
    data:
      tls.key: ...
      tls.crt: ...
      tls.der: <der-encoded tls.key>
  • Bundle together the tls.key and tls.crt into a PEM-encoded concatenation of the PKCS#8-formated PEM-encoded private key followed by the chain of PEM-encoded X.509 certificates.

    kind: Secret
    metadata:
    annotations:
      secret-transform-in: tls.key,tls.crt
      secret-transform-out: tls.pem # Any name with the extension `.pem`.
    data:
      tls.key: ...
      tls.crt: ...
      tls.pem: <content of tls.key followed by tls.crt>

The other use-cases aren't relevant since I did not find any pain point (that I could find on the cert-manager issues). Here are the use-cases I identified:

Use-case: MongoDB

cert-manager/cert-manager#843

In order to configure mTLS, the mongod and mongos require a combined PEM file using the key certificateKeyFile. The PEM file must contain the PKCS#8 PEM-encoded private key followed by the chain of PEM-encoded X.509 certificates. The configuration looks like this:

net:
  tls:
    mode: requireTLS
    certificateKeyFile: /etc/ssl/mongodb.pem

✔️ secret-tranform should be able to get around this.

Use-case: HAProxy Community Edition and HAProxy Enterprise Edition

  • HAProxy,
  • Hitch,
  • OpenDistro for Elasticsearch. The crt parameter requires a PEM bundle containing the PKCS#8 private key followed by the X.509 certificate chain. An example of configuration looks like this:
frontend www
   bind :443 ssl crt /etc/certs/ssl.pem

✔️ secret-tranform should be able to get around this.

Use-case: Hitch

Hitch, a reverse-proxy that aims at terminating TLS connections, requires the use of a combined PEM bundle using the configuration key pem-file. The bundle must be comprised of a PKCS#8-encode private key followed by the X.509 certificate leaf followed by intermediate certificates. An example of configuration looks like this:

pem-file = "/etc/tls/combined.pem"

or

pem-file = {
    cert = "/etc/tls/combined.pem"
}

✔️ secret-tranform should be able to get around this.

Use-case: Postgres JBDC driver (lower than 42.2.9)

If you are stuck with a version of the Postgres JDBC driver older than 42.2.9 (released before Dec 2019), sslkey refers to a file containing the PKCS#8-formated DER-encoded private key.

props.setProperty("sslkey","/etc/ssl/protgres/postgresql.key");

✔️ secret-tranform should be able to get around this.

Use-case: Ejabbed

Related issue in the cert-manager repository: Add ca.crt to TLS secret generated by ACME issuers.

Ejabbed, an open-source Erlang-based XMPP server, requires all file paths given with certfiles to be "valid" (i.e., not empty). The pain point is that Ejabbed fails when the ca.crt file is empty on disk. This makes it difficult to use Ejabberd with cert-manager, for example with the following Ejabbed configuration:

certfiles:
  - /etc/ssl/ejabbed/tls.crt
  - /etc/ssl/ejabbed/tls.key
  - /etc/ssl/ejabbed/ca.crt # May be empty with the ACME Issuer.

❌ secret-transform is not able to work around this issue yet.

Use-case: Elasticsearch (Elastic's and Open Distro's)

Related to the issue on the cloud-on-k8s project: fleet and elastic agent doesn't work without a ca.crt.

Elasticsearch cannot start when the ca.crt file is empty on disk, which may happen for ACME issued certificates. A "possible" workaround for these empty ca.crt could be to set pemtrustedcas_filepath to the existing system CA bundle. For example, on REHL, that could be /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem or /etc/ssl/cert.pem on Alpine Linux. But Elasticsearch expects this file to exist within its config path (i.e., /usr/share/elasticsearch/config).

❌ secret-transform is not able to work around this issue yet.

@SgtCoDFish
Copy link

SgtCoDFish commented Nov 23, 2021

Cool writeup 😁 Might be sort-of related to cert-manager/cert-manager#4598 ? I guess this is a more generally useful thing for k8s! 🤔

@SpectralHiss
Copy link

From what it seems like, adding a static caBundle field , with an append or replace mode to secret-transform could solve those 2 edge cases, but would that be a generally useful feature? or is it potentially unsafe ?

@maelvls
Copy link
Owner Author

maelvls commented Dec 3, 2021

I added the use-cases to the readme (3bbaaba) and also added a link to the PR cert-manager/cert-manager#4598 that implements DER key and combined PEM. I'll close this PR now since there is no point in trying to implement the DER key transformation since it is being implemented in cert-manager itself.

@maelvls maelvls closed this Dec 3, 2021
@antstacks
Copy link

antstacks commented Sep 18, 2023

Would this cover the use case that has been presented regarding Redis?

There are format differences between cert-manager generated secrets and what Redis expects. Details as follows:

Cert-manager generated:

apiVersion: v1
data:
  ca.crt: [ca.crt content]
  tls.crt: [certificate content]
  tls.key: [private key content]
kind: Secret
metadata:
  name: redis-cert1

Redis expects:

apiVersion: v1
data:
  certificate: [certificate content]
  key: [private key content]
  name: proxy
kind: Secret
metadata:
  name: redis-cert1

@maelvls
Copy link
Owner Author

maelvls commented Sep 19, 2023

Hi! Yes, you can use secret-transform to fit Redis' expectations.

The only difference with the rest of the examples in the README is that you will need to create the Secret beforehand so that name: proxy shows correctly. When a Secret already exists, cert-manager doesn't create a new one: it simply updates tls.crt, tls.key, and ca.crt.

The pre-created Secret I suggest is:

apiVersion: v1
kind: Secret
type: kubernetes.io/tls
metadata:
  name: redis-cert1
  annotations:
    cert-manager.io/secret-copy-tls.crt: certificate
    cert-manager.io/secret-copy-tls.key: key
data:
  name: proxy

After cert-manager has issued the certificate, it will have added the tls.crt, tls.key, and ca.crt keys:

apiVersion: v1
kind: Secret
type: kubernetes.io/tls
metadata:
  name: redis-cert1
  annotations:
    cert-manager.io/secret-copy-tls.crt: certificate
    cert-manager.io/secret-copy-tls.key: key
data:
  tls.crt: LS0tLCR...UdJ0tC7g==
  tls.key: CRUdJTo...Ci0tLS0t==
  ca.crt: Ci0tLS0t...CRUdJTo==
  name: proxy

Right after that, secret-transform copies tls.crt and tls.key to certificate and key. The resulting Secret looks like this:

apiVersion: v1
kind: Secret
type: kubernetes.io/tls
metadata:
  name: redis-cert1
  annotations:
    cert-manager.io/secret-copy-tls.crt: certificate
    cert-manager.io/secret-copy-tls.key: key
data:
  tls.crt: LS0tLCR...UdJ0tC7g==
  tls.key: CRUdJTo...Ci0tLS0t==
  ca.crt: ...
  certificate: LS0tLCR...UdJ0tC7g==
  key: CRUdJTo...Ci0tLS0t==
  name: proxy

Does it make sense?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants