Skip to content

Support custom CA certificates in Helm #2984

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

Closed
wants to merge 2 commits into from

Conversation

jgallucci32
Copy link
Contributor

Adds support to Helm charts for custom CA certificates. Approach derived from from https://github.com/goharbor/harbor-helm project for variable names and formatting.

Fixes #2615

Signed-off-by: jgallucci32 [email protected]

@jgallucci32
Copy link
Contributor Author

@corneliusludmann @geropl @stefanstoeckigt Please review this PR for custom CA certs.

@corneliusludmann
Copy link
Contributor

@jgallucci32 Thanks a lot for your contribution. I really appreciate this! I'm currently organizing a review. Thanks for your patience and sorry for the delay.

@meysholdt
Copy link
Member

hi @jgallucci32, thank you for your contribution!

IIRC /etc/ssl/certs/ca-certificates.crt is a generated file and the mount you're introducing overrides it, thus not only adding new certs but also removing pre-existing certs. Can this cause trouble?

We haven't documented it yet, but we'll need a CLA before we can merge this, I'll reach out to you about it via email.

@jgallucci32
Copy link
Contributor Author

jgallucci32 commented Jan 22, 2021

@meysholdt Yes you are correct. It is expected to be a full bundle inclusive of your custom certs. This is typically done by adding your custom certs to a local Linux OS (i.e. /usr/local/share/ca-certificates) and running update-ca-certificates to generate a full bundle to be used by Gitpod.

@stefanstoeckigt
Copy link

stefanstoeckigt commented Jan 26, 2021

@jgallucci32, the ca volume and NODE_EXTRA_CA_CERTS should also be added to the workspace-template.yaml. This will allow the workspace pod to have access to the ca. Without the NODE_EXTRA_CA_CERTS in the workspace pod you wont be able to download any vs-code extensions when the workspace is running.

@jgallucci32
Copy link
Contributor Author

@stefanstoeckigt Interesting I hadn't thought about adding it there. We just repackaged the public workspace-full image with the ENV added to Dockerfile and certs moved over with COPY as this is typical for most environments where custom CA certs are used. In addition to NODE_EXTRA_CA_CERTS we also found that REQUESTS_CA_BUNDLE was required as well for python pip to work. I'm sure we will discover more as we have only just scratched the surface of all the software packages contained in the full image.

Do you have a recommendation as to where to add it in workspace-template.yaml? I think I would start down the tree of spec: on Line 20, but there is very little there I don't want to risk breaking anything.

@stefanstoeckigt
Copy link

@jgallucci32, i think adding it under the coreWorkspaceConfig section, like below maybe.

{{- define "coreWorkspaceConfig" }}
{{- $comp := .comp -}}
spec:
 {{- if $comp.pullSecret }}
  imagePullSecrets:
  - name: {{ toYaml $comp.pullSecret.secretName }}
  {{- end }}
{{- if .Values.caBundleSecretName }}
   containers:
     - name: workspace
        volumeMounts:
{{ include "gitpod.caBundleVolumeMount" . | indent 8 }}
        env:
        - name: NODE_EXTRA_CA_CERTS
           value: /etc/ssl/certs/ca-certificates.crt
   volumes:
{{ include "gitpod.caBundleVolumeMount" . | indent 8 }}
{{- end }}

@jgallucci32
Copy link
Contributor Author

jgallucci32 commented Feb 4, 2021

@meysholdt @corneliusludmann what are your thoughts about also including the proposed changes for workspace-template.yaml?

@iamulya
Copy link

iamulya commented Feb 22, 2021

In image-builder-deployment.yaml, {{- if .Values.caBundleSecretName }} should be replaced with {{- if $.Values.caBundleSecretName }} - to reference the global scope.

Base automatically changed from master to main February 23, 2021 18:09
Copy link
Contributor

@corneliusludmann corneliusludmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jgallucci32,

First, an apology that we've been so slow with your great PR. Internally, we are not yet so well attuned to the processing of community PRs. But we will get better. I promise! 😃

I left a couple of comments. Please have a look.

For the workspace-template.yaml file, I think it makes sense to add the custom CA as well. This diff works for me:

diff --git a/chart/templates/workspace-template.yaml b/chart/templates/workspace-template.yaml
index 80beebb3..a012a84b 100644
--- a/chart/templates/workspace-template.yaml
+++ b/chart/templates/workspace-template.yaml
@@ -10,6 +10,19 @@ spec:
   imagePullSecrets:
   - name: {{ toYaml $comp.pullSecret.secretName }}
   {{- end }}
+  {{- if .gp.caBundleSecretName }}
+  containers:
+  - name: workspace
+    volumeMounts:
+{{ include "gitpod.caBundleVolumeMount" . | indent 4 }}
+    env:
+    - name: NODE_EXTRA_CA_CERTS
+      value: /etc/ssl/certs/ca-cert-gitpod.crt
+    - name: REQUESTS_CA_BUNDLE
+      value: /etc/ssl/certs/ca-cert-gitpod.crt
+  volumes:
+{{ include "gitpod.caBundleVolume" .root | indent 2 }}
+  {{- end }}
 {{- end }}
 {{- define "coreWorkspaceAffinity" -}}
 {{- $comp := .comp -}}

I also suggest, that we add an empty caBundleSecretName: property to the chart/values.yaml file (probably below certificatesSecret: …). Thus, we have some kind of documentation that the configuration value exist.

If you don't have time for this PR right now, please let me know. Then I will gladly take over.


{{- define "gitpod.caBundleVolumeMount" -}}
- name: ca-bundle-certs
mountPath: /etc/ssl/certs/ca-certificates.crt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about mounting just the root CA with a unique name (e.g. ca-cert-gitpod.crt) in the folder /etc/ssl/certs/ instead of the full ca-certificates.crt (addresses the comments #2984 (comment) and #2984 (comment))?

Suggested change
mountPath: /etc/ssl/certs/ca-certificates.crt
mountPath: /etc/ssl/certs/ca-cert-gitpod.crt

Then, you don't need to run update-ca-certificates on a local Linux and can add your root CA directly. In my tests, that works pretty fine.

@@ -64,6 +64,9 @@ spec:
secret:
secretName: {{ $sec.secret }}
{{- end }}
{{- if .Values.caBundleSecretName }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in #2984 (comment) by another user, this does not work for me too but need to be this:

Suggested change
{{- if .Values.caBundleSecretName }}
{{- if $.Values.caBundleSecretName }}

@@ -78,6 +81,9 @@ spec:
{{- range $idx, $sec := $comp.registryCerts }}
- mountPath: /etc/docker/certs.d/{{- if eq $sec.name "builtin" -}}{{ template "gitpod.builtinRegistry.name" $this.root }}{{ else }}{{ $sec.name }}{{ end }}
name: docker-tls-certs-{{ $idx }}
{{- if .Values.caBundleSecretName }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here (#2984 (comment))

Suggested change
{{- if .Values.caBundleSecretName }}
{{- if $.Values.caBundleSecretName }}

{{- end }}
{{- if .Values.caBundleSecretName }}
- name: NODE_EXTRA_CA_CERTS
value: /etc/ssl/certs/ca-certificates.crt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we change the cert name in the _helper.tpl file (see above) we need to change it here as well, right?

Suggested change
value: /etc/ssl/certs/ca-certificates.crt
value: /etc/ssl/certs/ca-cert-gitpod.crt

@jgallucci32
Copy link
Contributor Author

@corneliusludmann Thanks for getting back, I'll try to make some time to put in the suggested changes. I'll run through our setup to verify the alternate location for the CA Bundle works without changes (other than the node.js env var). I've always thought you had to use the specific ca-certificates.crt bundle but I will verify this as soon as I can.

@jgallucci32
Copy link
Contributor Author

@corneliusludmann I have good news and bad news. I did some preliminary testing on using a different file for the custom CA certs and validated all but the ws-daemon using the new configuration. The blobserve, image-builder, and registry-facade are what I assume to be using a Go library which honors any certs located in /etc/ssl/certs and as a result can work the way suggested. The server pod works because node.js allows for additional certs using the added environment variable (so in theory this could be anything in any directory).

The ws-daemon is a different story. Behind the scenes it is making Git client commands and git is a bit trickier to work with. I was able to find the variable GIT_SSL_CAINFO which when set to /etc/ssl/certs/ca-cert-gitpod.crt allows you to execute a shell into the container and run some git commands. It appears the Go code which is calling git does not honor this environment variable and throws the same error (to an unpatched system). It's possible there are other combos of env vars to set and I will experiment with those.

Long term, this is something the folks at Gitpod need to take into consideration. Option A (current PR) overwrites the bundled CA Certs making it more straightforward to fix certs, but requires all certs to be in the bundle. Option B (suggested change) uses a different CA bundle, but requires use of special environment variables for each client library needing to connect to an endpoint with a custom SSL cert. This method is more explicit, but does not guarantee the bundle can only contain additive certs as some client libraries when using an env var will completely ignore the local ca bundle, defeating the purpose of keeping the bundle to only what you need (node.js does it right with the "EXTRA" approach, but not all clients do this).

Here is the exact error I see in ws-deamon should we continue down the path of Option B.

{"@type":"type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent","error":"cannot initialize workspace:
    github.com/gitpod-io/gitpod/content-service/pkg/initializer.InitializeWorkspace
        /tmp/build/components-ws-daemon--content-initializer.3b990f245ba910a11725fbc05699fcfcffc53d71/_deps/components-content-service--lib/pkg/initializer/initializer.go:345
  - git initializer:
    github.com/gitpod-io/gitpod/content-service/pkg/initializer.(*GitInitializer).Run
        /tmp/build/components-ws-daemon--content-initializer.3b990f245ba910a11725fbc05699fcfcffc53d71/_deps/components-content-service--lib/pkg/initializer/git.go:68
  - git clone https://gitlab.domain.local/gitpod/workspace-validation.git . failed (exit status 128): Cloning into '.'...
fatal: unable to access 'https://gitlab.domain.local/gitpod/workspace-validation.git/': SSL certificate problem: unable to get local issuer certificate
","level":"error","message":"content init failed","serviceContext":{"service":"content-initializer","version":""},"severity":"ERROR","time":"2021-03-07T21:29:10Z"}

@aledbf
Copy link
Member

aledbf commented Mar 7, 2021

@jgallucci32 @corneliusludmann can we align with Kubernetes and use a TLS secret?
Using the change proposed in #3199

If the secret contains a custom CA, it must be concatenated in the tls.crt field

@jgallucci32
Copy link
Contributor Author

@jgallucci32 @corneliusludmann can we align with Kubernetes and use a TLS secret?
Using the change proposed in #3199

If the secret contains a custom CA, it must be concatenated in the tls.crt field

@aledbf Kubernetes TLS secrets are primarily used with TLS termination of Ingress resources and requires both a public certificate and private key during creation. Since a custom CA bundle only includes public certificates, it would not make sense to create a TLS secret where you would have to fake the private key in order to create the secret (which may cause issues)

Here is what happens when attempting to create a TLS secret for a CA bundle

$ kubectl create secret tls my-tls-secret --cert=/etc/ssl/certs/ca-certificates.crt
error: flag key is required
See 'kubectl create secret tls -h' for help and examples

@csweichel
Copy link
Contributor

The ws-daemon is a different story. Behind the scenes it is making Git client commands and git is a bit trickier to work with. I was able to find the variable GIT_SSL_CAINFO

Git also supports GIT_SSL_CAPATH which can point to a directory of ca certs. We could make that env var point to the CA certs available to ws-daemon. For example, adding the code below to

// We need to tell Git where to find CA certs in case someone added custom CA certs
// to ws-daemon. We're re-using ws-daemon's /etc above.
spec.Process.Env = append(spec.Process.Env, "GIT_SSL_CAPATH=/etc/ssl/certs")

should do the trick.

@corneliusludmann
Copy link
Contributor

corneliusludmann commented Mar 11, 2021

We could make that env var point to the CA certs available to ws-daemon. For example, adding the code below to

@csweichel: Thanks for the hint. I tried this, but this doesn't work. At first, I think we need to add this here instead:

like:

env = append(env, "GIT...=....")

However, I don't get GIT_SSL_CAPATH resp. http.sslCAPath running. I tried it also directly in an Alpine Docker image but the config seems to be ignored. Don't know why. What works is GIT_SSL_CAINFO like this:

	if stat, err := os.Stat("/etc/ssl/certs/ca-cert-gitpod.crt"); err == nil && stat.Size() > 0 {
		// We need to tell Git where to find CA certs in case someone added custom CA certs.
		env = append(env, "GIT_SSL_CAINFO=/etc/ssl/certs/ca-cert-gitpod.crt")
	}

but that breaks cloning from github.com (because it uses the ca-cert-gitpod.crt CA only).

EDIT: Ah, that's the reason why GIT_SSL_CAPATH does not work: https://stackoverflow.com/a/9880236/1364435

@zazizou
Copy link

zazizou commented May 21, 2021

Hi guys,

Will this feature eventually integrated in the main branch one day ? Is there a plan for that ?

Thanks

Regards

@jgallucci32
Copy link
Contributor Author

@zazizou This is still on my to-do list. This PR was written against version 0.6.0 so in addition to a rebase I am going to need to deploy the latest version in a test cluster to validate it still works as intended. I'm trying to get some time to do this as soon as I can.

@stale
Copy link

stale bot commented Aug 19, 2021

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the meta: stale This issue/PR is stale and will be closed soon label Aug 19, 2021
@bmnave
Copy link

bmnave commented Aug 19, 2021

This is still needed.

@stale stale bot removed the meta: stale This issue/PR is stale and will be closed soon label Aug 19, 2021
@SirLemyDanger
Copy link

what about accepting the working solution with the complete bundle first, and only afterwards go for the sophiticated solution? This is a major blocker to use gitpod in internal networks.

@jgallucci32
Copy link
Contributor Author

jgallucci32 commented Sep 17, 2021 via email

@SirLemyDanger
Copy link

@jgallucci32 First, thanks a lot for your effort on this MR.

And yes, I would be interested in your workarounds.

@stale
Copy link

stale bot commented Sep 29, 2021

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the meta: stale This issue/PR is stale and will be closed soon label Sep 29, 2021
@SirLemyDanger
Copy link

@corneliusludmann Is #4322 addressing/solving this issue?

@stale stale bot removed the meta: stale This issue/PR is stale and will be closed soon label Oct 3, 2021
@jgallucci32
Copy link
Contributor Author

@corneliusludmann Is #4322 addressing/solving this issue?

Looking at the PR it is solving a different problem. It looks like cert-manager is being implemented using its default setup of generating certificates from known sources (i.e. Letsencrypt). If it is being used to sign a self-signed or custom CA, then the certificate stores need to be updated using the methods outlined in this PR.

FYI, I am ready to work this PR but am stuck. 0.10.0 is the latest release but the master contains the changes for image-builder-mk3 which is something I cannot test. How do I deploy the latest helm chart for master? I only know how to deploy what is helm which is 0.10.0 currently.

@mrsimonemms
Copy link
Contributor

Hi @jgallucci32. I need to update the documentation for self-hosted to work with Image Builder Mk3. I'll schedule this work for tomorrow

@jgallucci32
Copy link
Contributor Author

@SirLemyDanger See #2615 (comment) for kubectl patch commands to apply Custom CA certs to self-hosted Gitpod installation.

@mrsimonemms
Copy link
Contributor

Hi @jgallucci32. I've had a look at releasing from main rather than from the 0.10.0 Helm release. As we're currently moving away from Helm releases to releasing from main (and with an Installer), this is going to be a pain point until we have this work finished - for the record, this is currently my main focus, so hopefully it won't be for long.

The image-builder-mk3:0.10.0 image is not published to the self-hosted registry There is an image published called gcr.io/gitpod-io/self-hosted/image-builder-mk3@sha256:23fab89b745436e714d18df33f1bb4543541e3049ef51ea6aa148c58d4399b00, but I'm not sure what the state of this is.

@stale
Copy link

stale bot commented Oct 16, 2021

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the meta: stale This issue/PR is stale and will be closed soon label Oct 16, 2021
@flickerfly
Copy link
Contributor

flickerfly commented Oct 18, 2021 via email

@stale stale bot removed the meta: stale This issue/PR is stale and will be closed soon label Oct 18, 2021
@stale
Copy link

stale bot commented Oct 28, 2021

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the meta: stale This issue/PR is stale and will be closed soon label Oct 28, 2021
@stale stale bot closed this Nov 3, 2021
@iQQBot
Copy link
Contributor

iQQBot commented Nov 4, 2021

@jgallucci32 Do you mind if I pick up you commit and finish this job again?

@jgallucci32
Copy link
Contributor Author

@iQQBot I don't mind, I have no way to test this right now since the main branch has deviated from the 0.10.0 installer and the MK3 image builder needs to be fixed, but I can't test it.

I can certainly review your updated PR.

@iQQBot
Copy link
Contributor

iQQBot commented Nov 4, 2021

Great,thank you so much.

@gtsiolis
Copy link
Contributor

gtsiolis commented Nov 4, 2021

Thanks for coming back to this @jgallucci32!

@iQQBot feel free to cherry pick any of the commits from @jgallucci32 if changes here are still relevant and open a follow up PR for this. 🏀

@iQQBot
Copy link
Contributor

iQQBot commented Nov 6, 2021

/assign

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
community-contribution meta: stale This issue/PR is stale and will be closed soon
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Self-Hosted] Support for own CA certificates