-
Notifications
You must be signed in to change notification settings - Fork 572
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
core: support automatic installation of custom CA certs. #7067
Conversation
Oof, yeah that sounds rough. Is there any way we can isolate "our" changes to a separate layer and then rebase it out somehow? (Haven't looked how it works yet, maybe it's not so bad, just thinking out loud)
Is the Or does it install-then-uninstall on each Would it be too weird to install certs as part of |
Not that I am aware of. At the beginning I was trying to use overlay mounts to do that but quickly realized that:
The update commands have to re-run on each
I considered that too but ruled it out since I want to avoid leaving those files around even in the intermediate layers. Leaving them in will still leak them to the layers of the published image (even if we append an extra layer on top cleaning them up).
I think the best we can do is optimize in follow-ups to not always run these update commands and instead selectively just directly fixup files/dirs in the same way the update command does. We can obviously only do this when we are really really sure we know what the update command is (i.e. probably have to match on distro versions too), so still need to support running these commands in each |
bklog.G(ctx).Debugf("> creating %s %v", id, process.Meta.Args) | ||
defer bklog.G(ctx).Debugf("> container done %s %v", id, process.Meta.Args) | ||
|
||
if installCACerts { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note for reviewers, the code in this file is mostly the same as upstream's runc executor except for this section that handles CA cert installation and some other minor re-arrangement/cleanup of irrelevant codepaths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verified tests fail if I comment out an important line (the one that installs the CA into the engine. Obviously there's a lot going on here but it's fully justified afaict. :laughcry:
WithMountedFile("/bin/dagger", daggerCliFile(t, c)). | ||
WithEnvVariable("_EXPERIMENTAL_DAGGER_CLI_BIN", "/bin/dagger"). | ||
WithEnvVariable("_EXPERIMENTAL_DAGGER_RUNNER_HOST", "tcp://engine:1234"). | ||
WithEnvVariable(executeTestEnvName, "ya"). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😁
Just FYI that I was adding more tests last night and did find some cases where we were incorrectly leaving around some parent dirs. This is pretty minor, so should be fine to address in follow up. I am getting close to finishing the fix there but am mentioning this since apparently my planes wifi is gonna cut off once we are too far into the pacific ocean... so we'll see if I have enough time to fix it before my vacation actually starts. Probably should work out. |
I'm gonna take this out of the milestone - given @sipsma is now on holiday, I'd rather we wait to merge this. |
Signed-off-by: Erik Sipsma <erik@dagger.io>
Signed-off-by: Erik Sipsma <erik@dagger.io>
Signed-off-by: Erik Sipsma <erik@dagger.io>
I had temporarily added a unique exit code per shim error because I was hitting errors there during development but could not actually see the error message, only the exit code (likely due to the integ test needing to run against a dev engine service, thus increasing nesting). However, that wasn't really maintainable. This changes the shim to always try to write errors, including panics, to the best available error writer at the time, which is usually enough to actually see the error. Signed-off-by: Erik Sipsma <erik@dagger.io>
Signed-off-by: Erik Sipsma <erik@dagger.io>
Signed-off-by: Erik Sipsma <erik@dagger.io>
Signed-off-by: Erik Sipsma <erik@sipsma.dev>
Signed-off-by: Erik Sipsma <erik@sipsma.dev>
Fixed the aforementioned issue of leaving parent dirs and not resetting mtime on files (which results in the diff being non-empty when it should be empty) and added test coverage for all that. Will merge this once green. There's going to be a few more immediate follow ups to add |
…o more funcs is worth it Signed-off-by: Erik Sipsma <erik@sipsma.dev>
Still some cleanup left, but good enough for feedback. TODOs:
/usr/local/share/ca-certificates
)This adds support for automatic installation of custom CA certs to containers. Originally this was gonna just be the first step outlined here but as I started implementing the CA certs part it required enough complication that it seemed best to just implement the full support for automatic CA installation for all containers.
Helpful docs/prior art
CA Certs
I learned a lot about the various nuances surrounding CAs as part of this (and I'm sure I've only scratched the surface), braindump below.
CAs are not standardized in any way; the way they are configured depends on a few (sometimes orthogonal) factors:
c_rehash
command)curl
with options that point to the right bundle file and/or CA dir to use.PKCS #11
andp11-kit
trust
orupdate-ca-trust
command.trust
command has anextract
subcommand that creates a layout compatible with the above "generic" setup, for better compatibility with libs that don't uselibp11-kit
/etc/ssl/certs
and/etc/ssl1.1/certs
libc
) and whether said package is installed in base images varies from distro to distro:ca-certificates
fully installeddebian
comes without it installedalpine
does not have it installed, but nonetheless does have a base bundle file installed (though no separate cert files)Implementation Notes
/usr/local/share/ca-certificates
in their custom engine image, the engine will attempt to install that in all containers (but only if it can identify the distro of the container, fallback is a nop right now)apk install curl
off the base alpine image theca-certificates
package will be installed as a dep and modify the bundle file and CA dir.update-ca-certificates
Executor
(which runs in thedagger-engine
process). I ended up going with theExecutor
approach for a few reasons:ftp_proxy
cmd/engine/cacerts/fs.go
ascontainerFS
. The main complication comes from needing to very carefully handle symlinks so that any symlinks in parent dirs of a given path are always resolved correctly to the final mount where they actually point to.update-ca-certificates
and similar by actually starting separate container that reuses the same rootfs+mounts as the "actual" user exec container.debian
), but other packages may still try to check those (we need to manually set those up in these cases)./etc/
files. Used https://github.com/dekobon/distro-detect/blob/master/linux/distrochecks.go as a reference