-
Notifications
You must be signed in to change notification settings - Fork 641
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
Support for SSL man-in-the-middle proxies #6599
Comments
Thank you for posting this issue I am in a similar env and have the same issues Some context/related work: They are more aligned to corp proxies but same deal with things like certificates. CC @sipsma |
Additional context based on recent findings - any version mismatch (go toolchain) in https://discord.com/channels/707636530424053791/1209532081697325147 A temporary fix is the make sure any |
Fully tackling every variation on this general issue and making everything totally seamless will be a significant effort, but as a first step to improve the current situation I think we could perhaps mount the engine's It would still require users setup a custom engine (as described here). But it should at least stop the worst of the bleeding and set us up for more iterative improvements. (adding to |
Thank you @sipsma I think that will unblock us partially. The other requirement that I think goes hand in hand are system proxies. I think having a way to "passthrough" the system proxies to the SDK containers is equally important as the certificates. My company requires the proxies to pull any go dependencies from the internet. |
EDIT: put most up-to-date proposal in the PR description Previous proposalWant to contextualize the problem and possible solutions short to long term so we can get a consensus on how to approach it before going through any one-way doors.Unfortunately this issue goes very wide and deep, so I apologize in advance for the wall of text here 😅 The problem is obviously that users need to use dagger with custom CA certs and proxy settings. I'd break this down into 4 problem areas:
My previous comment was a quick fix to just That doesn't rule it out as a first step, but here's an outline of one way we could start there and lift the one insurmountable blocker relatively quickly, but in such a way that we can follow-up with more comprehensive solutions iteratively. Step 1 - Read-only API for Engine-wide configuration and SDK supportCA certs and proxy settings are operator-level and system-wide concerns, so they should still be configured on the engine as a whole rather than hardcoded by developers in their Dagger code. However, these settings should be exposed via a core API (read-only to start). Putting an API in front of these allows us more safely iterate on how they are configured in subsequent steps. The API could look something like this: extend type Query {
daggerEngine: DaggerEngine!
}
type DaggerEngine {
caCerts: Directory
httpProxy: String
httpsProxy: String
# etc.
# arbitrary key/value engine-wide settings
setting(key: String!): String
} The idea is that CA certs and "standard" proxy settings are wide-spread enough that that can get their own dedicated fields, but we also need to support things like This alone would help with (referring to the list of problems above)
To start, these settings will be read-only in the API and instead still set by custom provisioning an engine:
Thankfully, this would also be fairly straightforward implementation-wise, so if we go with it we can still unblock users relatively quickly. Open QuestionsThe arbitrary key/value store exposed by (Optional) Step 2 - Default all containers to use CA and standard proxy settingsThis next step would result in CA certs and standard proxy settings to be applied to all containers automatically, including This solves the problems in dag.Container.
From("foo").
WithMountedDirectory("/etc/ssl/certs", dag.DaggerEngine().CACerts()).
WithEnv("HTTP_PROXY", dag.DaggerEngine().HTTPProxy())
// etc. This would be a breaking-change, though only to any users that have custom provisioned an engine with custom CA certs and proxy settings, and the extent to which it would actually break them is not totally clear since in many (if not most) cases it would actually be fixing something that previously didn't work. If we default all containers with this, there would still be corner cases to deal with:
Technically, this step is optional. We could just accept the problems in Step 3 - Write API for Engine-wide configurationThe last step would allow the engine-wide settings to be set via an API rather than set by custom provisioning an engine. The hard part here is that this should ideally be a "privileged" API that's only intended for use by operators setting up an engine as opposed to something any module or any user could call.
Doing this would save users from having to custom provision engines in order to configure any of this (and reprovision them if the settings change, etc.) Those steps are just one possibility of course. There are also options to read settings from the client (i.e. a session attachable that reads CA certs, I really want us to be able to unblock users here quickly, so even if we leave open a few questions on the long-term plan, provided we agree on the immediate steps and general outline we can get going on the actual fixes. |
I like this API idea a lot 🎉 One potential point of contention though - how does this new config API interact with the old |
Fantastic analysis and potential solution! One issue I have with the "setting everything in a custom engine image" is that proxies sometimes tend to need authentication. So we'd pass in The other issue is we have different egress proxies for local (on-prem) vs cloud (remote, aws). For that scenario we'd have to produce 2 different engine images and ask users to set different I really like the dagger SDK (non function) way of being able to "pass-through" these settings from the local environment. Maybe some kind of config we can set where we tell the dagger engine to use the local env vars (just for proxies?). I believe that's what Step 3 is working towards. |
@sipsma Nice job unpacking all that. Having gone through almost exactly this situation with Concourse (concourse/concourse#1027) and arrived at a similar conclusion (engine-side TSL/proxy config auto-injected into containers), here's what I can provide:
How do we want proxy + TLS config to affect caching? If someone re-configures their engine with a new proxy env var or TLS cert, does that bust every cache? Combined with @nipuna-perera's point about creds sometimes being in the proxy env var, I'm thinking we don't want these to end up in cache keys. But does that also mean we need the proxy envs to be |
Thanks for the feedback everyone! All super helpful.
Yeah good question, I think it would be reasonable to do something like this order of precedence:
If we do end up supporting client-side settings (i.e. picked up from their env, a config file, etc. via a session attachable), then I think that would come first in the precedence order, even above writes to the engine API (though this could be debated separately).
Great callouts, didn't think about that at all. For the security aspects, I agree that this means you'd want to avoid hardcoding any credentials into the engine container. I think the options are:
This is all making me a bit more biased towards implementing support for client-side configuration of all this early on (with precedence as described above). If the user's container runtime supports secrets, that seems best all around; but the write-API is a pretty huge rabbit hole so client-side settings may make sense to prioritize support for first as the next best thing.
Another thing that came to mind is that transparently setting proxy env vars that contain credentials on all containers inherently means that any 3rd party modules will have access to those creds.
For the caching aspect, yeah I think it would make sense to just always use a
Yeah makes sense, that is the sort of pain that would be alleviated with a write-API. But this is another pro for implementing client-side settings early on.
Nice! Thanks for all the links to the prior art, super helpful. Yeah I was avoiding "autodetect" idea because I wasn't sure it was really viable, but if we can get it to work in like 99% of cases that changes everything quite a bit. It may mean we could avoid the API entirely (at least, it would be internal only and not exposed to end users). @vito in your experience was this sort of approach pretty robust or was there a small-but-significant tail of cases where it didn't work?
Yeah I really don't like I could go either way on whether proxy config should just be combined into the k/v map, but the CA certs specifically should probably stay a separate field since they should be a
But either way, thinking again today, I'm wondering if there's some other approach to support the "arbitrary global settings" like
I'm gonna write an updated proposal based on all this and post to PR description, I think there's enough new considerations/ideas to make some changes. Will re-ping once done. |
Well, with a user base of 1, I can say it worked great for everyone. In all seriousness, it didn't get a whole lot of mileage, but it never gave me any trouble either once I figured out a versatile enough pattern (which was done in the first commit). It'll probably take some fiddling to deal with exotic distros and such as they come up, but the shim is in a pretty luxurious position since it runs in the container context and can auto-detect that all pretty easily, so I'm somewhat confident in that approach. I'm at least more confident in it than mounting over a not-quite-even-standard directory and crossing our fingers. 😄 Don't have much to add re: the rest, agree they sound worth exploring. I think it's a great idea to think up a few approaches here without getting too married to the first one. |
@nipuna-perera @vito @jedevc updated the PR description with a new iteration on the proposed fixes. It's cobbled together from the previous one and other comments, so apologies for anything you've already read; just want it to be clear for anyone else reading it the first time. Have a few remaining open questions at the end that I'd appreciate any feedback on. |
I like the updated plan! My favorite is Step 4 where we get to configure this client side as I would love to not have to maintain our own dagger engine. One note: I am assuming you are including NO_PROXY also as a special proxy env. Just want to confirm as I don't see a mention of it in your description. For No. 2 in open questions. I am currently using the Finally, not totally related, but do you have plans to remove the |
This is important to us, we can't wait to use dagger, but are blocked by this issue |
I have submitted a PR (#7186) to propagate We can't access |
Just FYI for everyone following this issue, I updated the description of the issue with the current state of support and what's planned for the future. These features are still very much experimental. They have e2e tests and some limited real-world validation, but given the complexity of proxies and especially CA certs, we will need some more real-world testing to help validate them. If you give them a try, please let us know how it goes (either here or on our discord)! |
Hey @sipsma , thank you so much for the awesome work on this! I tested the proxies and they definitely work. I don't have a use case currently to test cacerts but I will try to find a way to test it. I had a use case sometime back where it failed. We don't use GOPROXY yet but will start in Q3 or Q4 and I'll be able to test it. I can finally run dagger functions on our corporate Jenkins instance. yay! Final piece of this puzzle for me is #6113 and I can start sharing my modules with folks :) |
I have been testing the certificates side and no issues so far! #6113 is also something I'm waiting on before fully diving into modules. |
Good day. I've been waiting for the issues with CA certs to be resolved so I could start building out some dagger pipelines in our corporate environment. Really appreciate the summarized status on the initial post. Wondering if I should venture into using "registry.dagger.io/engine:2ae9f4d815c1fcf48626ce9437c788d0efb91a79 " or just wait for the next Dagger build. Been using stock dagger installs up to this point so it is not clear what needs to be done to use a interim build. Any thoughts or suggestions would be welcome. Also, just to chime in, getting #6113 is of great interest and will open up wider corp adoption. |
@OptikMist fyi we've fixed the CA certs issues with modules in #7356, which has been released (just now!) in https://github.com/dagger/dagger/releases/tag/v0.11.5 🎉 |
Thanks @jedevc, I pulled the latest dagger version and reran my pipeline. Unfortunately I'm still seeing the issue. (dagger-env) clarge@Ubuntu-22:~/Projects/Automation/Misc-Automation-Tools/github-automation/org-management/dagger$ dagger run python run-org-mgmnt.py So this is pulling from an internal docker repo. I can do a docker login and docker pull on that url from the host machines shell. |
Just double checking, did you leave out the name of the image for privacy reasons? Or did it actually show up as Either way, the CA support currently requires that you custom provision an engine using |
@sipsma , yes, I actually had added text with brackets into the output but it looks like the angle brackets is consumed by the formatter. So yes, there is a valid docker image URI specified, I removed it as it is an internal service. |
set env export _DAGGER_ENGINE_SYSTEMENV_GOPROXY=https://goproxy.io I run it still download package from proxy.golang.org
|
You have to set the env variable on the engine. Not the client side.
|
thanks, it works!!! |
Renamed the title to be more specific (this is a request for supporting corporate man-in-the-middle SSL proxies found in some corporate environments), and clarify that it's a feature request, not a bug report. |
What is the issue?
For security reasons many companies man-in-the-middle all SSL traffic to the internet with their own certificate. This causes a
x509: certificate signed by unknown authority
issue in two spots for dagger:/usr/local/share/dagger/go-module-sdk-image.tar
and building a go program when running any module command. The commands all fail when thego build
does ago get
for dependencies and hits the same x509 issue.Steps I have tried to work around this issue:
ModuleRuntime
as recommended in the discord thread here. I quickly found that all the existing module runtimes point back to go as a dependency, which was the issue.dagger mod init
it would always fail with "main object not found".Posting this as recommended in discord since there appears to be no workarounds and modules are completely broken in this environment.
Dagger version
v0.9.6
Steps to reproduce
No response
Log output
No response
Current Solutions
(this section and below is from edits by @sipsma)
Proxy Support
As of
v0.11.4
, the engine has support for "standard" proxy envs:HTTP_PROXY
,HTTPS_PROXY
,NO_PROXY
,ALL_PROXY
, andFTP_PROXY
.registry.dagger.io/engine:v0.11.4
) they will be automatically passed to all containers started by the engine.UPPER
andlower
case to support applications that have a preference for one or the other.Additionally, we also support custom
GOPROXY
values being set on the Go SDK (only the Go SDK for now, not all containers)._DAGGER_ENGINE_SYSTEMENV_GOPROXY=<value>
Custom CA Support
The engine also has support for use of custom CAs. When configured, the engine will use them for any of its internal requests (e.g. pulling/pushing container images) and makes a best-effort attempt at installing them in every container started by the engine (explained more below).
There was a bug in
v0.11.4
, so currently you will need to use the engine imageregistry.dagger.io/engine:2ae9f4d815c1fcf48626ce9437c788d0efb91a79
which is a build off of our main branch.To configure the engine with custom CA certs, you will need to provision a custom engine with the certs placed in the directory
/usr/local/share/ca-certificates
.update-ca-certificates
automatically so they are configured for use from there.The support for automatic installation in all containers is best-effort because CA certificates are very far from standardized and their configuration depends on the distro of the base image of the container being installed into.
If a container is supported, CAs will be installed before the container runs and uninstalled after it finishes.
If a container is not supported or a non-fatal error is hit during installation, then Dagger will not fail the exec and instead just continue on without the CAs installed.
withMountedFile
).Further support planned
Support for client-side settings
We should add support for configuring CA certs and proxy settings from the client side. This is intended for corporate use-cases where Dagger users are on a machine that also has all these settings available+configured to the same values that the engine should use (whether or not it's on the same machine).
The values may be set either from env vars, a config file, or both. Leaving that open as TBD for now, but will note that if env vars are supported we should require them to have a specific prefix like
DAGGER_ENGINE_
to ensure that users more explicitly opt-in to these values being propagated to their pipelines.This helps solve the problem of needing to custom provision an engine to set these values, though only for users that have these settings available client-side.
Generalized custom proxy support
Right now
GOPROXY
is supported only for our Go SDK. We also don't have support for other language/application specific proxy settings other than the "standard" ones mentioned above (HTTP_PROXY
,HTTPS_PROXY
, etc.).This is fairly limiting, so we need to design a way for more arbitrary support for passing system-wide application-specific proxy settings to containers. The current workaround is to explicitly set them on containers, but that has the problem of being tedious/boilerplate-y and also includes those values in the cache key of the operations, which invalidates them if they change.
The text was updated successfully, but these errors were encountered: