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

Bug 1895053: Allow builds to mount the proxy CA #831

Merged
merged 1 commit into from Feb 22, 2021

Conversation

adambkaplan
Copy link
Contributor

@adambkaplan adambkaplan commented Jan 4, 2021

Add option that allows the cluster's proxy certificate authority to be
mounted via a buildah bind mount. When the CA is bind mounted, the
contents of /etc/pki/ca-trust are managed by the build container.
The folder and its subdirectories can be manipulated; however any changes
to the directory or its subdirectories are not persisted in the resulting
image.

For example, with this option set to true, a Dockerfile RUN instruction
that changes the ownership of /etc/pki/ca-trust/extracted will not have
the updated ownership appear in the build's output image.

@openshift-ci-robot openshift-ci-robot added bugzilla/severity-high Referenced Bugzilla bug's severity is high for the branch this PR is targeting. bugzilla/valid-bug Indicates that a referenced Bugzilla bug is valid for the branch this PR is targeting. labels Jan 4, 2021
@openshift-ci-robot
Copy link

@adambkaplan: This pull request references Bugzilla bug 1895053, which is valid. The bug has been updated to refer to the pull request using the external bug tracker.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target release (4.7.0) matches configured target release for branch (4.7.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, ON_DEV, POST, POST)

In response to this:

Bug 1895053: Allow builds to mount the proxy CA

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

// true, the contents of `/etc/pki/ca-trust` within the build are managed by the build
// container and cannot be modified during the build (example - via a Dockerfile `RUN`
// instruction).
MountProxyTrustedCA *bool `json:"mountProxyTrustedCA,omitempty" protobuf:"varint,10,opt,name=mountProxyTrustedCA"`
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pointer is used here in the event we want to support build defaults, which requires us to determine user intent.

Copy link
Contributor

Choose a reason for hiding this comment

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

i wonder if we should just call this MountTrustedCA? we have been a bit wishy-washy on the concept, in some places we call it trusted CA, in others proxy CA. What are the other APIs a user/admin interacts with that would setup/populate the CAs that ultimately get mounted here?

@adambkaplan
Copy link
Contributor Author

Usage by openshift-controller-manager: openshift/openshift-controller-manager#154

@adambkaplan
Copy link
Contributor Author

Test to verify: openshift/origin#25778

// as defined in the cluster's proxy configuration, into the build. When this field is set to
// true, the contents of `/etc/pki/ca-trust` within the build are managed by the build
// container and cannot be modified during the build (example - via a Dockerfile `RUN`
// instruction).
Copy link
Contributor

Choose a reason for hiding this comment

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

they can be modified, but the files (neither the original nor the modified versions) will be included in the output image.

the output image will contain whatever contents the original from image included for /etc/pki/ca-trust

//
// When this field is set to true, the contents of `/etc/pki/ca-trust` within the build are
// managed by the build container, and any changes to this directory or its subdirectories (for
// example - via a Dockerfile `RUN` instruction) are not persisted in the build's output image.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bparees updated this to also clarify the field purpose (particularly HTTPS proxies).

/cc @rolfedh

@openshift-ci-robot
Copy link

@adambkaplan: GitHub didn't allow me to request PR reviews from the following users: rolfedh.

Note that only openshift members and repo collaborators can review this PR, and authors cannot review their own PRs.

In response to this:

@bparees updated this to also clarify the field purpose (particularly HTTPS proxies).

/cc @rolfedh

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Copy link

@rolfedh rolfedh left a comment

Choose a reason for hiding this comment

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

LGTM but, going forward, please use the English equivalent of Latin words such as "via." This helps with localization and improves comprehension for readers who are less familiar with academic English.

@openshift-ci-robot
Copy link

@adambkaplan: This pull request references Bugzilla bug 1895053, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target release (4.7.0) matches configured target release for branch (4.7.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, ON_DEV, POST, POST)

In response to this:

Bug 1895053: Allow builds to mount the proxy CA

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@adambkaplan
Copy link
Contributor Author

@bparees @rolfedh api doc updated, commits squashed. PTAL.

@rolfedh
Copy link

rolfedh commented Jan 18, 2021

@bparees @rolfedh api doc updated, commits squashed. PTAL.

LGTM

@adambkaplan adambkaplan changed the title Bug 1895053: Allow builds to mount the proxy CA WIP - Bug 1895053: Allow builds to mount the proxy CA Feb 10, 2021
@openshift-ci-robot openshift-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 10, 2021
Add option that allows the cluster's proxy certificate authority to be
mounted via a buildah bind mount. When the CA is bind mounted, the
contents of `/etc/pki/ca-trust` are managed by the build container.
The folder and its subdirectories can be manipulated; however any changes
to the directory or its subdirectories are not persisted in the resulting
image.

For example, with this option set to true, a Dockerfile `RUN` instruction
that changes the ownership of `/etc/pki/ca-trust/extracted` will not have
the updated ownership appear in the build's output image.
@adambkaplan adambkaplan changed the title WIP - Bug 1895053: Allow builds to mount the proxy CA Bug 1895053: Allow builds to mount the proxy CA Feb 11, 2021
@openshift-ci-robot openshift-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 11, 2021
@adambkaplan
Copy link
Contributor Author

/assign @bparees

Feature now works end to end with my WIP pull requests.
Note that the mounts.conf key was removed, as we no longer override the mounts.conf file for buildah. We use a different feature to mount the trust store into the image under construction (transient mounts)

@adambkaplan
Copy link
Contributor Author

cc @openshift/api-reviewers

@bparees
Copy link
Contributor

bparees commented Feb 11, 2021

/approve

@openshift-ci-robot openshift-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Feb 11, 2021
@deads2k
Copy link
Contributor

deads2k commented Feb 12, 2021

Trying to understand the downstream impact of this on builds. The impl looks to be doing a mount from inside of a container, which I expect will run afoul of attempts to limit the scope of pod security permissions. Could this not be modeled as a localvolume mount in the pod so the kubelet can manage the mounting and we can properly permission it?

@adambkaplan
Copy link
Contributor Author

@deads2k in the implementation the trust bundle is mounted into the sub-containers buildah creates during the build [1]. These sub containers live within the build pod, inside the docker-build container. Thanks to a recent bugfix, these are true sub containers, controlled by runc inside the build container.

The path to getting the trust bundle into builds is as follows:

  1. The user's ca ConfigMap in openshift-config is synced to the openshift-controller-manager namespace.
  2. When a build is started, the copied user ca ConfigMap is again copied to the build's namepsace, is added as a volume to the build pod, and has the build set as an owner-ref to ensure proper GC.
  3. Each container in the build pod mounts the user ca at a neutral location. On startup, the containers look for the user ca. If found, the ca is added as a trust anchor, and update ca-trust extract is run to merge that CA to the OS trust store [2].

This lets custom PKIs be trusted for git clone and image source extraction operations. However, things running within the build itself (example - RUN mvn install in a Dockerfile) currently do not have access to the custom PKI. With this option set to true, the custom PKI is made available via buildah's transient mount feature. We use the same feature to bring RHEL subscription keys in from the node.

[1] https://github.com/openshift/builder/pull/218/files#r574068125
[2] https://github.com/openshift/builder/blob/master/imagecontent/bin/entrypoint.sh

@deads2k
Copy link
Contributor

deads2k commented Feb 12, 2021

A proxy CA should not be confused with, "use this CA to trust all connections". It isn't used for that and usage is not uniform. It's also not projected into any user-facing pods today. If you want to project a "system" trust bundle of some kind into a pod, that would be a reasonable enhancement to write. If you want to support "use the cluster proxy for my build", this is also reasonable, but I would expect that to be an option that talks about "use-cluster-proxy", somehow handles cases where credentials are included in the env vars, and properly sets those env vars.

This appears to be an attempt at something in the middle that uses a proxy CA bundle in a non-standard way and doesn't include the proxy env vars?

@adambkaplan
Copy link
Contributor Author

It isn't used for that and usage is not uniform. It's also not projected into any user-facing pods today. If you want to project a "system" trust bundle of some kind into a pod, that would be a reasonable enhancement to write.

I believe you can project a system trust bundle by adding the config.openshift.io/inject-trusted-cabundle="true" label to a ConfigMap. This does generate a full system trust bundle, intended to be mounted into /etc/pki/ca-trust/extracted/pem within containers [1]. Unforunately, this doesn't work for Builds because tools like maven cannot use PEM-encoded trust bundles.

Instead, builds effectively generate their own system trust bundle by adding the proxy CA as an anchor and merging the trust stores together.

This appears to be an attempt at something in the middle that uses a proxy CA bundle in a non-standard way and doesn't include the proxy env vars?

We also include the proxy env vars in builds. If the cluster has a proxy configured, the *_PROXY env vars are automatically added to builds [2] and are set in the build's sub-containers [3]. We previously considered naming this field MountProxyTrustedCA - @deads2k does this clarify that the CA is intended to be used only for proxy connections?

What may be of concern is that builds can override the proxy env vars, in which case the proxy CA could be abused as a "use this CA for everything" anchor. We do this today, and IMO should be treated as a separate bug.

[1] https://docs.openshift.com/container-platform/4.6/networking/configuring-a-custom-pki.html#certificate-injection-using-operators_configuring-a-custom-pki
[2] https://github.com/openshift/openshift-controller-manager/blob/master/pkg/build/controller/build/build_controller.go#L385-L425
[3] https://github.com/openshift/builder/blob/master/pkg/build/builder/daemonless.go#L301

// When this field is set to true, the contents of `/etc/pki/ca-trust` within the build are
// managed by the build container, and any changes to this directory or its subdirectories (for
// example - within a Dockerfile `RUN` instruction) are not persisted in the build's output image.
MountTrustedCA *bool `json:"mountTrustedCA,omitempty" protobuf:"varint,10,opt,name=mountTrustedCA"`
Copy link
Contributor

Choose a reason for hiding this comment

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

MountClusterProxyCA if that's what you're mounting (I think it is)


// mountTrustedCA bind mounts the cluster's trusted certificate authorities, as defined in
// the cluster's proxy configuration, into the build. This lets processes within a build trust
// components signed by custom PKI certificate authorities, such as private artifact
Copy link
Contributor

Choose a reason for hiding this comment

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

it's not appropriate to indicate that a proxy CA is used to validate private artifact repositories. that is more of a bug than a feature.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To piggy back on Ben's comment - unfortunately we explicitly tell customers today to use the Proxy "trusted CA" as the trusted CA for the whole cluster [1]. Connecting to a private Artifactory or Nexus repository with a corporate cert is perhaps the most common reason why a customer would use this feature.

[1] https://docs.openshift.com/container-platform/4.6/networking/configuring-a-custom-pki.html

Copy link
Contributor

Choose a reason for hiding this comment

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

unfortunately we explicitly tell customers today to use the Proxy "trusted CA" as the trusted CA for the whole cluster

it's not unfortunate, it was a deliberate choice that we built a mechanism to distribute the CAs generically, not specifically for proxy.

The mistake was that you have to tie the trusted CA bundle configmap to the proxy config (via a ref in the proxyconfig to the ca bundle CM) to make that happen, which makes it seem like the CAs are explicitly tied to proxy.

we said at the time we did this that if we got pushback/uses cases from customers to more finely subdivide their CA bundles, we would add additional mechanisms/configs to support that subdivision. So far i haven't heard of any.

// When this field is set to true, the contents of `/etc/pki/ca-trust` within the build are
// managed by the build container, and any changes to this directory or its subdirectories (for
// example - within a Dockerfile `RUN` instruction) are not persisted in the build's output image.
MountTrustedCA *bool `json:"mountTrustedCA,omitempty" protobuf:"varint,10,opt,name=mountTrustedCA"`
Copy link
Contributor

Choose a reason for hiding this comment

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

If you want a way to manage trust, why not create a way to mount a configmap and use that? That seems both more useful and could be consistent with the proxy use-case.

@bparees
Copy link
Contributor

bparees commented Feb 18, 2021

A proxy CA should not be confused with, "use this CA to trust all connections". It isn't used for that and usage is not uniform. It's also not projected into any user-facing pods today.

the annotation that projects the CAs into the configmap was named config.openshift.io/inject-trusted-cabundle deliberately to allow for use cases such as this, rather than express that the CAs were specifically "proxy" CAs. It's why we didn't call it "inject-proxy-cabundle". (And this choice was discussed extensively at the time the api went in).

Those CAs are already used for more than proxy (they are also used to trust registries that have custom certs, both for disconnected installs and at runtime for imagestream imports and image pulls).

Does this have security implications admins need to understand/be aware of? yes. But until/unless we design additional CA injection mechanisms that distinguish different sets of CAs(which there was no appetite for at the time the current CA distribution mechanism was defined, hence why it was created as generic), it's what we have and i think it's reasonable for the build component to leverage it in this way, as other cluster components already do.

@deads2k
Copy link
Contributor

deads2k commented Feb 22, 2021

I'm not personally impressed or convinced by using a questionable previous decision to justify continued questionable choices. I also don't have confidence that it will stay contained to builds in the future. Add to that the fact that we know it's not difficult to create viable alternative that reflects what you actually want if you can describe the boundaries on a particular injection and usage mechanism, it seems like a real shame to do this. But I won't actively attempt to block it.

@bparees
Copy link
Contributor

bparees commented Feb 22, 2021

Add to that the fact that we know it's not difficult to create viable alternative that reflects what you actually want if you can describe the boundaries on a particular injection and usage mechanism, it seems like a real shame to do this.

The build api does already provide ways to supply explicit CAs to be used, on a per build basis, for someone who wants to constrain the use of the CAs. This is about making builds follow the pattern used by other components in the system which is to consume the cluster trusted CA bundle, if desired.

So for now this is about builds respecting the mechanism/config that exists. Yes we can certainly introduce "cluster scoped build CA bundles" in the future (along with something that is truly a proxy CA bundle, since today what we have is not a proxy CA bundle, it is just a cluster scoped trust bundle), though again the need for that is somewhat limited since builds already allow you to provide your own CAs on a per-build basis (it would be nice to have a way to do it at a cluster-scoped config level). So far i'm not aware of any users/customers requesting such a thing, but we'd entertain it (more likely in builds v2 however, as we are trying to constrain new feature additions to builds v1)

@bparees
Copy link
Contributor

bparees commented Feb 22, 2021

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Feb 22, 2021
@openshift-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: adambkaplan, bparees, rolfedh

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-robot openshift-merge-robot merged commit 70b287c into openshift:master Feb 22, 2021
@openshift-ci-robot
Copy link

@adambkaplan: Some pull requests linked via external trackers have merged:

The following pull requests linked via external trackers have not merged:

These pull request must merge or be unlinked from the Bugzilla bug in order for it to move to the next state. Once unlinked, request a bug refresh with /bugzilla refresh.

Bugzilla bug 1895053 has not been moved to the MODIFIED state.

In response to this:

Bug 1895053: Allow builds to mount the proxy CA

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. bugzilla/severity-high Referenced Bugzilla bug's severity is high for the branch this PR is targeting. bugzilla/valid-bug Indicates that a referenced Bugzilla bug is valid for the branch this PR is targeting. lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants