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

Self signed SSL Certificate support for DevContainers #6092

Open
jeeftor opened this issue Dec 17, 2021 · 97 comments
Open

Self signed SSL Certificate support for DevContainers #6092

jeeftor opened this issue Dec 17, 2021 · 97 comments
Assignees
Labels
containers Issue in vscode-remote containers feature-request Request for new features or functionality plan-review PM-highlighted item determined to be P1 or P2 proxy Issues regarding network proxies
Milestone

Comments

@jeeftor
Copy link

jeeftor commented Dec 17, 2021

I'm working behind a corporate network that uses SSL inspection and I have thus far been unable to use DevContainers due to SSL issues at work. I'd love the ability to have a trusted cert be able to be inserted into the devcontainers somehow.

Thanks

@ghost ghost assigned chrmarti Dec 17, 2021
@chrmarti chrmarti transferred this issue from microsoft/vscode Dec 22, 2021
@chrmarti chrmarti added containers Issue in vscode-remote containers feature-request Request for new features or functionality proxy Issues regarding network proxies labels Dec 22, 2021
@bamurtaugh bamurtaugh added the plan-review PM-highlighted item determined to be P1 or P2 label Jan 27, 2022
@egnerfl
Copy link

egnerfl commented Jun 22, 2022

Hi @bamurtaugh ,

This feature is especially important for GitHub Enterprise Customers with own instances.
Hope to see it implemented soon 🎉

Best,
Florian

@bamurtaugh
Copy link
Member

Thanks @egnerfl! We'll be sure to provide an update if/when this is added to an iteration plan.

@jeeftor
Copy link
Author

jeeftor commented Jul 26, 2022

I hope its soon!

@robwafle
Copy link

Hi, this still seems to be a challenge, roughly a year later. Has this been added to an iteration plan?

@jeeftor
Copy link
Author

jeeftor commented Mar 17, 2023

I'd love to have an update!!!

@fightingsleep
Copy link

This would be great since the corporate MITM attack completely prevents the use of dev containers right now

@jeeftor
Copy link
Author

jeeftor commented Jun 13, 2023

@bdsoha - so it sure seems like it would be worth somebody looking into this :(

@bamurtaugh
Copy link
Member

Thank you all for your continued patience and interest in this issue, we really appreciate it.

I've made a note for us to discuss this further during our next month's planning cycle, and you'll be able to see it on an iteration plan if we have a chance to prioritize it (this month's plan as example).

@jeeftor
Copy link
Author

jeeftor commented Jun 13, 2023

@bamurtaugh - I'm at a 10k person company and frankly only a handful of people have implemented dev containers due to the annoyance of our self-signed certs...

@bdsoha
Copy link

bdsoha commented Jun 14, 2023

@jeeftor I find myself in a very similar situation, at a company with 6k employees.
IMO, over time, we see more and more companies that employ stricter firewall, policies, and compliances.
Many of which implement a cooperate CA somewhere in the middle.

@dkwgit
Copy link

dkwgit commented Jun 14, 2023

Same, 5k-10K employee company and this issue prevents good adoption of dev containers. @bamurtaugh. Ty for considering.

@dkwgit
Copy link

dkwgit commented Jun 14, 2023

One additional point: I can make things work if I do a Dockerfile explicitly. (I can copy our certificate into the container, etc.). I can then manually add "features" in the Dockerfile, (i.e. "code explicitly"). But I cannot make things like the "features" section of devcontainer.json work, because that stuff is evaluated in a context where I have not fixed the cert issue. @bamurtaugh.

So the whole features section does not work.

@bdsoha
Copy link

bdsoha commented Jun 15, 2023

@dkwgit I published a feature that is supposed to transparently handle the CA installation into the container during startup.
Due to the abovementioned issues, it does not currently work.

https://github.com/bdsoha/dev-containers

@dkwgit
Copy link

dkwgit commented Jun 15, 2023

Great feature idea @bdsoha. Hope we get to the point where that is doable!!

@shaneholder
Copy link

shaneholder commented Jun 15, 2023

I've been hitting this issue as well. We use a data loss prevention tool that directs all HTTPs traffic through a set of servers that issue self signed certs. I've written up instructions for our company on how to address the issue with lots of different tools but the dev container of VS code is problematic. The way we normally address node programs is to set the environment variable NODE_EXTRA_CA_CERTS to point to the location of the root self signed cert. In fact if I install the devcontainer cli I can run it and have it generate configs for containers. It's like however VS Code is running node it's ignoring that environment variable.

Hope this information helps in troubleshooting.

Oh, and I ran a bunch of different versions, looks like it started around .262.3. Version .255.4 behaves as I would expect.

@dkwgit
Copy link

dkwgit commented Jun 16, 2023

@bamurtaugh Been thinking about this issue a lot. I'm new to dev containers, so there is a lot I don't yet understand and my thoughts may be "off" as a result. But what is impressing itself on me is;

This is not so much about certificate support (that's the symptom here) as it is about a missing lifecycle hook in the devcontainer spec. There is no hook such as initializeCommand that targets the bootstrapping of the devcontainer system (as far as I can tell). If there were such a hook, users could do things like inject their certificates into node at that stage. They could also do other needed things. I realize that the faster (and helpful!) thing to do is provide a way to deal with the certificate issue. (I'd welcome that). But long term, what would really make sense is to have a hook that allows customization at the right moment, imo.

@shaneholder
Copy link

@dkwgit Yeah, we ran into that after we build containers and try to install software. We've been copying the root cert into projects and using the Docker build process to copy the cert into the container when it's being built. But the current problem I have is what seems to be a regression in behavior between versions of the extension. I was pretty happy once I discovered I can run the CLI to generate the config, but it's not nearly as nice as using the VSCode UI.

@chrmarti
Copy link
Contributor

How you add a certificate seems to vary by distro (reading https://technotes.shemyak.com/posts/docker-behind-ssl-proxy/).

Features are added after any user-provided Dockerfile runs, so that Dockerfile should be able to add custom certificates.

A feature should be able to add custom certificates too, but since there is no way for the feature to say it wants to run first among any other features, only features that happen to install afterwards benefit from it.

If you have a CI environment without the proxy restriction: You could pre-build the Docker image in CI (devcontainer build) and then use the prebuilt image in a second devcontainer.json locally.

@OneCyrus
Copy link

Features are added after any user-provided Dockerfile runs, so that Dockerfile should be able to add custom certificates.

unfortunately this isn‘t the case for more than a year. the features are downloaded outside of this dockerfile after a change in the extension. it worked before.

as far as certificates go. may be just support to import the local trusted certificates into the bootstrap container. this way you don‘t need to support multiple linux distributions.

@chrmarti
Copy link
Contributor

There are multiple points where custom certificates are needed:

  • Host OS when running the devcontainer CLI. (NODE_EXTRA_CA_CERTS might work.)
  • Bootstrap container for "clone in volume". (Dev Containers extension could copy the OS certificates or NODE_EXTRA_CA_CERTS to the bootstrap container.)
  • While building the container image. (Distro-specific.)
  • While running the container. (Distro-specific.)

@dkwgit
Copy link

dkwgit commented Jun 20, 2023

Features are added after any user-provided Dockerfile runs, so that Dockerfile should be able to add custom certificates.

@chrmarti In my version of dev container extension, v0.295.0, it does something to resolve features (and fails because of the certificate issue) before it even gets to my Dockerfile. I successfully add the cert in the Dockerfile, so that things inside the container work)--but enabling the features section of my devcontainer.json with any feature immediately causes a failure before the Dockerfile is built. Can post logs if that would help.

@cymylau
Copy link

cymylau commented Feb 8, 2024

Any chance someone can share a link on how we elect to use "Dev Containers 0.340.0-pre-release"; my searchfoo is failing me. Thanks.

@mholttech
Copy link

Find the extension to install as you normally would and right click on it in the list and select use pre release

@NebraskaCoder
Copy link

today i tested also with devcontainer features and that worked as well 👍 the only issue i hit was with the node feature which also is invoking npm which failed with a not trusted self signed certificate error. as far as i can tell npm doesn't use the node settings (would have been too easy ;)). there are a couple of ways to handle this though.

great that we have this now. it will simplify so many things here.

This is what I experienced. I had to comment out the RUN cd && npm i node-pty as it was having CA cert issues. Then everything ran just fine.

Here is the issue:

image

Text version:

[+] Building 1.9s (10/11)                                docker:rancher-desktop
 => [internal] load build definition from bootstrap.Dockerfile             0.0s
 => => transferring dockerfile: 869B                                       0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
 => [internal] load metadata for mcr.microsoft.com/devcontainers/base:0-a  0.0s
 => [1/7] FROM mcr.microsoft.com/devcontainers/base:0-alpine-3.16          0.0s
 => [internal] load build context                                          0.0s
 => => transferring context: 64.06kB                                       0.0s
 => CACHED [2/7] COPY host-ca-certificates.crt /usr/local/share/ca-certif  0.0s
 => CACHED [3/7] RUN cat /usr/local/share/ca-certificates/host-ca-certifi  0.0s
 => CACHED [4/7] RUN echo "@old https://dl-cdn.alpinelinux.org/alpine/v3.  0.0s
 => CACHED [5/7] RUN apk add --no-cache  git-lfs  nodejs  python3  npm  m  0.0s
 => ERROR [6/7] RUN cd && npm i node-pty                                   1.8s
------
 > [6/7] RUN cd && npm i node-pty:
1.747 npm ERR! code E403
1.749 npm ERR! 403 403 Forbidden - GET https://registry.npmjs.org/node-pty
1.749 npm ERR! 403 In most cases, you or one of your dependencies are requesting
1.749 npm ERR! 403 a package version that is forbidden by your security policy, or
1.750 npm ERR! 403 on a server you do not have access to.
1.751 
1.752 npm ERR! A complete log of this run can be found in:
1.752 npm ERR!     /root/.npm/_logs/2024-02-08T21_13_36_873Z-debug-0.log
------
bootstrap.Dockerfile:23
--------------------
  21 |          ;
  22 |     
  23 | >>> RUN cd && npm i node-pty
  24 |     
  25 |     COPY .vscode-remote-containers /root/.vscode-remote-containers
--------------------
ERROR: failed to solve: process "/bin/sh -c cd && npm i node-pty" did not complete successfully: exit code: 1

Do we have a way to get certs working with NPM in the bootstrap container? Commenting out that run command works fine but I'd rather not have to keep doing that (and have to instruct others in a large company to do that).

@chrmarti
Copy link
Contributor

chrmarti commented Feb 9, 2024

today i tested also with devcontainer features and that worked as well 👍 the only issue i hit was with the node feature which also is invoking npm which failed with a not trusted self signed certificate error. as far as i can tell npm doesn't use the node settings (would have been too easy ;)). there are a couple of ways to handle this though.

great that we have this now. it will simplify so many things here.

I see NPM can be configured to use the system's CA file (assuming you have your CAs already added there): npm config set cafile /etc/ssl/certs/ca-certificates.crt

@NebraskaCoder I missed that in the bootstrap container, I will change that line to:

RUN npm config set cafile /etc/ssl/certs/ca-certificates.crt && cd && npm i node-pty

Thanks!

@chrmarti
Copy link
Contributor

chrmarti commented Feb 9, 2024

Dev Containers 0.342.0-pre-release is available with the latest fixes.

@NebraskaCoder
Copy link

@NebraskaCoder I missed that in the bootstrap container, I will change that line to:

RUN npm config set cafile /etc/ssl/certs/ca-certificates.crt && cd && npm i node-pty

Thanks!

So, after updating to 0.342.0-pre-release, it still had the same error. I looked into my company's developer "getting started" guide and we block access to the public npm registry. I added RUN npm config set registry="https://npm.company.com/" above your npm command and it worked (I'm sure I could have just added it to the same npm line using an && statement). Are there any options for automating that (maybe grabbing that from the settings)?

@lucaspottersky
Copy link

The following still seems to fail when in a corporate MITM certificate scenario. Could this be related to this issue?

.devcontainer:

{
  "name": "Dev Java",
  "image": "mcr.microsoft.com/devcontainers/java:1-21-bullseye",
  "features": {
    "ghcr.io/devcontainers/features/java:1": {
      "installMaven": "true"
    }
  }
}
 > [dev_containers_target_stage 5/5] RUN --mount=type=bind,from=dev_containers_feature_content_source,source=java_0,target=/tmp/build-features-src/java_0     cp -ar /tmp/build-features-src/java_0 /tmp/dev-container-features  && chmod -R 0755 /tmp/dev-container-features/java_0  && cd /tmp/dev-container-features/java_0  && chmod +x ./devcontainer-features-install.sh  && ./devcontainer-features-install.sh  && rm -rf /tmp/dev-container-features/java_0:
0.270 ===========================================================================
0.270 Feature       : Java (via SDKMAN!)
0.270 Description   : Installs Java, SDKMAN! (if not installed), and needed dependencies.
0.270 Id            : ghcr.io/devcontainers/features/java
0.270 Version       : 1.4.0
0.270 Documentation : https://github.com/devcontainers/features/tree/main/src/java
0.270 Options       :
0.270     VERSION="latest"
0.270     JDKDISTRO="ms"
0.270     INSTALLGRADLE="false"
0.270     GRADLEVERSION="latest"
0.270     INSTALLMAVEN="true"
0.270     MAVENVERSION="latest"
0.270     INSTALLANT="false"
0.270     ANTVERSION="latest"
0.270     INSTALLGROOVY="false"
0.270     GROOVYVERSION="latest"
0.270 ===========================================================================
0.764 ==== INTERNET NOT REACHABLE! ===================================================
0.764 
0.764  Some functionality is disabled or only partially available.
0.764  If this persists, please enable the offline mode:
0.764 
0.764    $ sdk offline
0.764 
0.764 ================================================================================
0.764 
0.766 This command is not available while offline.
0.767 ERROR: Feature "Java (via SDKMAN!)" (ghcr.io/devcontainers/features/java) failed to install! Look at the documentation at https://github.com/devcontainers/features/tree/main/src/java for help troubleshooting this error.
------
[2024-02-21T21:04:26.521Z] Dockerfile.extended:26
--------------------
  25 |     ENV PATH="/usr/local/sdkman/bin:/usr/local/sdkman/candidates/java/current/bin:/usr/local/sdkman/candidates/gradle/current/bin:/usr/local/sdkman/candidates/maven/current/bin:/usr/local/sdkman/candidates/ant/current/bin:${PATH}"
  26 | >>> RUN --mount=type=bind,from=dev_containers_feature_content_source,source=java_0,target=/tmp/build-features-src/java_0 \
  27 | >>>     cp -ar /tmp/build-features-src/java_0 /tmp/dev-container-features \
  28 | >>>  && chmod -R 0755 /tmp/dev-container-features/java_0 \
  29 | >>>  && cd /tmp/dev-container-features/java_0 \
  30 | >>>  && chmod +x ./devcontainer-features-install.sh \
  31 | >>>  && ./devcontainer-features-install.sh \
  32 | >>>  && rm -rf /tmp/dev-container-features/java_0
  33 |     
--------------------
[2024-02-21T21:04:26.521Z] ERROR: failed to solve: process "/bin/sh -c cp -ar /tmp/build-features-src/java_0 /tmp/dev-container-features  && chmod -R 0755 /tmp/dev-container-features/java_0  && cd /tmp/dev-container-features/java_0  && chmod +x ./devcontainer-features-install.sh  && ./devcontainer-features-install.sh  && rm -rf /tmp/dev-container-features/java_0" did not complete successfully: exit code: 1
[2024-02-21T21:04:26.524Z] Stop (1893 ms): Run: docker buildx build --load --build-context dev_containers_feature_content_source=/tmp/devcontainercli-s166537/container-features/0.56.0-1708549463216 --build-arg _DEV_CONTAINERS_BASE_IMAGE=mcr.microsoft.com/devcontainers/java:1-21-bullseye --build-arg _DEV_CONTAINERS_IMAGE_USER=root --build-arg _DEV_CONTAINERS_FEATURE_CONTENT_SOURCE=dev_container_feature_content_temp --target dev_containers_target_stage -t vsc-lab-devcontainer-efaaa9b3295ae3fbfefc5dad0b0a7bf3097099c5bc65d7fe74961a54424232cd-features -f /tmp/devcontainercli-s166537/container-features/0.56.0-1708549463216/Dockerfile.extended /home/s166537/.config/Code/User/globalStorage/ms-vscode-remote.remote-containers/data/empty-folder
[2024-02-21T21:04:26.524Z] Error: Command failed: docker buildx build --load --build-context dev_containers_feature_content_source=/tmp/devcontainercli-s166537/container-features/0.56.0-1708549463216 --build-arg _DEV_CONTAINERS_BASE_IMAGE=mcr.microsoft.com/devcontainers/java:1-21-bullseye --build-arg _DEV_CONTAINERS_IMAGE_USER=root --build-arg _DEV_CONTAINERS_FEATURE_CONTENT_SOURCE=dev_container_feature_content_temp --target dev_containers_target_stage -t vsc-lab-devcontainer-efaaa9b3295ae3fbfefc5dad0b0a7bf3097099c5bc65d7fe74961a54424232cd-features -f /tmp/devcontainercli-s166537/container-features/0.56.0-1708549463216/Dockerfile.extended /home/s166537/.config/Code/User/globalStorage/ms-vscode-remote.remote-containers/data/empty-folder
[2024-02-21T21:04:26.524Z]     at J$ (/home/s166537/.vscode/extensions/ms-vscode-remote.remote-containers-0.338.1/dist/spec-node/devContainersSpecCLI.js:464:1253)
[2024-02-21T21:04:26.524Z]     at $J (/home/s166537/.vscode/extensions/ms-vscode-remote.remote-containers-0.338.1/dist/spec-node/devContainersSpecCLI.js:464:997)
[2024-02-21T21:04:26.524Z]     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
[2024-02-21T21:04:26.524Z]     at async tAA (/home/s166537/.vscode/extensions/ms-vscode-remote.remote-containers-0.338.1/dist/spec-node/devContainersSpecCLI.js:481:3660)
[2024-02-21T21:04:26.524Z]     at async CC (/home/s166537/.vscode/extensions/ms-vscode-remote.remote-containers-0.338.1/dist/spec-node/devContainersSpecCLI.js:481:4775)
[2024-02-21T21:04:26.524Z]     at async NeA (/home/s166537/.vscode/extensions/ms-vscode-remote.remote-containers-0.338.1/dist/spec-node/devContainersSpecCLI.js:614:11107)
[2024-02-21T21:04:26.524Z]     at async MeA (/home/s166537/.vscode/extensions/ms-vscode-remote.remote-containers-0.338.1/dist/spec-node/devContainersSpecCLI.js:614:10848)
[2024-02-21T21:04:26.528Z] Stop (3566 ms): Run: /usr/share/code/code /home/s166537/.vscode/extensions/ms-vscode-remote.remote-containers-0.338.1/dist/spec-node/devContainersSpecCLI.js up --user-data-folder /home/s166537/.config/Code/User/globalStorage/ms-vscode-remote.remote-containers/data --container-session-data-folder /tmp/devcontainers-5ba7e40b-c406-4520-98ff-2eb2327ee7191708549462294 --workspace-folder /home/s166537/lab-devcontainer --workspace-mount-consistency cached --id-label devcontainer.local_folder=/home/s166537/lab-devcontainer --id-label devcontainer.config_file=/home/s166537/lab-devcontainer/.devcontainer/devcontainer.json --log-level debug --log-format json --config /home/s166537/lab-devcontainer/.devcontainer/devcontainer.json --default-user-env-probe loginInteractiveShell --remove-existing-container --mount type=volume,source=vscode,target=/vscode,external=true --skip-post-create --update-remote-user-uid-default on --mount-workspace-git-root
[2024-02-21T21:04:26.528Z] Exit code 1
[2024-02-21T21:04:26.529Z] Command failed: /usr/share/code/code /home/s166537/.vscode/extensions/ms-vscode-remote.remote-containers-0.338.1/dist/spec-node/devContainersSpecCLI.js up --user-data-folder /home/s166537/.config/Code/User/globalStorage/ms-vscode-remote.remote-containers/data --container-session-data-folder /tmp/devcontainers-5ba7e40b-c406-4520-98ff-2eb2327ee7191708549462294 --workspace-folder /home/s166537/lab-devcontainer --workspace-mount-consistency cached --id-label devcontainer.local_folder=/home/s166537/lab-devcontainer --id-label devcontainer.config_file=/home/s166537/lab-devcontainer/.devcontainer/devcontainer.json --log-level debug --log-format json --config /home/s166537/lab-devcontainer/.devcontainer/devcontainer.json --default-user-env-probe loginInteractiveShell --remove-existing-container --mount type=volume,source=vscode,target=/vscode,external=true --skip-post-create --update-remote-user-uid-default on --mount-workspace-git-root
[2024-02-21T21:04:26.529Z] Exit code 1

@chrmarti
Copy link
Contributor

So, after updating to 0.342.0-pre-release, it still had the same error. I looked into my company's developer "getting started" guide and we block access to the public npm registry. I added RUN npm config set registry="https://npm.company.com/" above your npm command and it worked (I'm sure I could have just added it to the same npm line using an && statement). Are there any options for automating that (maybe grabbing that from the settings)?

@NebraskaCoder The NPM extension would be good place for such a setting, unfortunately that request didn't get any traction when it was filed previously: microsoft/vscode#7430. We could use npm config get registry to read the config, but that incurs some runtime costs. Do you have an ~/.npmrc file with that registry configured?

@lucaspottersky Have you configured your proxy for Docker? (https://docs.docker.com/network/proxy/)

@NebraskaCoder
Copy link

So, after updating to 0.342.0-pre-release, it still had the same error. I looked into my company's developer "getting started" guide and we block access to the public npm registry. I added RUN npm config set registry="https://npm.company.com/" above your npm command and it worked (I'm sure I could have just added it to the same npm line using an && statement). Are there any options for automating that (maybe grabbing that from the settings)?

@NebraskaCoder The NPM extension would be good place for such a setting, unfortunately that request didn't get any traction when it was filed previously: microsoft/vscode#7430. We could use npm config get registry to read the config, but that incurs some runtime costs. Do you have an ~/.npmrc file with that registry configured?

Yup. Our company has us define a ~/.npmrc file with registry=https://npm.company.com/ as the first line.

@tusv
Copy link

tusv commented Apr 4, 2024

@chrmarti Thanks for this fix. It works great. Can I request the same fix for InspectVolume as well?

I tried following to test it manually and it's working.

  1. Copied following lines from <random>/vsch/bootstrap-image/0.348.0/bootstrap.Dockerfile to <random>/vsch/inspect-volume/0.348.0/volume.Dockerfile
    COPY host-ca-certificates.crt /tmp/host-ca-certificates.crt
    RUN cat /tmp/host-ca-certificates.crt >> /etc/ssl/certs/ca-certificates.crt
    RUN csplit -f /usr/local/share/ca-certificates/host-ca-certificate- -b '%02d.pem' -z -s /tmp/host-ca-certificates.crt '/-----BEGIN CERTIFICATE-----/' '{*}'
    ENV NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
    
  2. Copied host-ca-certificates.crt from bootstrap-image/0.348.0 to inspect-volume/0.348.0
  3. Deleted existing image (vsc-0.348-<random>) for recovery container
  4. Opened repository from volume in recovery container

@chrmarti
Copy link
Contributor

chrmarti commented Apr 5, 2024

@NebraskaCoder node-pty should be optional. I will update the Dockerfile to continue when it can't install it.

@tusv Adding that, thanks.

@chrmarti
Copy link
Contributor

chrmarti commented Apr 5, 2024

The two mentioned changes are available in Dev Containers 0.356.0-pre-release.

@dal13002
Copy link

dal13002 commented Jun 7, 2024

For some reason, this is still not working for me. When I try to build my dev container using "Rebuild and Reopen container" option, it seems to read my .devcontainer.json file but then I get this error:

------
 > [internal] load metadata for artifactory.my.company.com/go:1-1.22-bullseye:
------
[2024-06-07T02:11:19.861Z] Dockerfile-with-features:3
[2024-06-07T02:11:19.862Z] 
[2024-06-07T02:11:19.862Z] --------------------
[2024-06-07T02:11:19.862Z] 
[2024-06-07T02:11:19.862Z]    1 |     
[2024-06-07T02:11:19.863Z] 
[2024-06-07T02:11:19.864Z]    2 |     	ARG _DEV_CONTAINERS_BASE_IMAGE=placeholder
   3 | >>> FROM  artifactory.my.company.com/go:1-1.22-bullseye AS dev_container_auto_added_stage_label
[2024-06-07T02:11:19.864Z] 
[2024-06-07T02:11:19.864Z]    4 |     
[2024-06-07T02:11:19.864Z] 
[2024-06-07T02:11:19.864Z]    5 |     # Set destination for COPY
[2024-06-07T02:11:19.864Z] 
[2024-06-07T02:11:19.864Z] --------------------
[2024-06-07T02:11:19.865Z] 
[2024-06-07T02:11:19.865Z] ERROR: failed to solve: artifactory.my.company.com/go:1-1.22-bullseye: failed to resolve source metadata for artifactory.my.company.com/go:1-1.22-bullseye: failed to do request: Head "https://artifactory.my.company.com/go/manifests/1-1.22-bullseye": tls: failed to verify certificate: x509: certificate signed by unknown authority
[2024-06-07T02:11:19.872Z] Stop (6338 ms): Run: docker buildx build --load --build-arg BUILDKIT_INLINE_CACHE=1 -f /tmp/devcontainercli-dal/container-features/0.62.0-1717726273530/Dockerfile-with-features -t vsc-sample-go-app-97414b8993c589e2a2bc80a45af9955ecde9ba5c289076577a98b7bc00b33560 --target dev_containers_target_stage --build-arg _DEV_CONTAINERS_BASE_IMAGE=dev_container_auto_added_stage_label /home/dal/code/sample-go-app/.devcontainer
[2024-06-07T02:11:18.010Z] Error: Command failed: docker buildx build --load --build-arg BUILDKIT_INLINE_CACHE=1 -f /tmp/devcontainercli-dal/container-features/0.62.0-1717726273530/Dockerfile-with-features -t vsc-sample-go-app-97414b8993c589e2a2bc80a45af9955ecde9ba5c289076577a98b7bc00b33560 --target dev_containers_target_stage --build-arg _DEV_CONTAINERS_BASE_IMAGE=dev_container_auto_added_stage_label /home/dal/code/sample-go-app/.devcontainer
[2024-06-07T02:11:18.010Z]     at mtA (/home/dal/.vscode-remote-containers/dist/dev-containers-cli-0.369.0/dist/spec-node/devContainersSpecCLI.js:465:1933)
[2024-06-07T02:11:18.010Z]     at async Pm (/home/dal/.vscode-remote-containers/dist/dev-containers-cli-0.369.0/dist/spec-node/devContainersSpecCLI.js:464:1841)
[2024-06-07T02:11:18.011Z]     at async NH (/home/dal/.vscode-remote-containers/dist/dev-containers-cli-0.369.0/dist/spec-node/devContainersSpecCLI.js:464:610)
[2024-06-07T02:11:18.011Z]     at async KtA (/home/dal/.vscode-remote-containers/dist/dev-containers-cli-0.369.0/dist/spec-node/devContainersSpecCLI.js:481:3692)
[2024-06-07T02:11:18.011Z]     at async eB (/home/dal/.vscode-remote-containers/dist/dev-containers-cli-0.369.0/dist/spec-node/devContainersSpecCLI.js:481:4807)
[2024-06-07T02:11:18.011Z]     at async hrA (/home/dal/.vscode-remote-containers/dist/dev-containers-cli-0.369.0/dist/spec-node/devContainersSpecCLI.js:661:13373)
[2024-06-07T02:11:18.011Z]     at async lrA (/home/dal/.vscode-remote-containers/dist/dev-containers-cli-0.369.0/dist/spec-node/devContainersSpecCLI.js:661:13114)

I have my company's private ca certs loaded on the remote host OS, which is bringing up the dev container. It seems like vscode creates a container from moby/buildkit:buildx-stable-1 to help build my image and that container does not have my ca certs. I am using dev containers version v0.369.0
Is there a way to fix this?

@chrmarti
Copy link
Contributor

chrmarti commented Jun 7, 2024

@dal13002 Not sure where moby/buildkit:buildx-stable-1 comes from, are you using a custom builder? What do you get for running docker buildx ls on the remote host?

@dal13002
Copy link

dal13002 commented Jun 7, 2024

@chrmarti Thank you so much! It seems like I was using a custom builder. I changed the builder back to default and everything works without a problem

@shaneholder
Copy link

Hello,

Things are getting better for data loss preventions services that use self signed certs. I am hitting one additional issue though when installing the terraform feature. I'm trying to do this using only the devcontainer.json file.

I am using WSL environment on Windows 10. Below is an example devcontainer.json file I'm using.

// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu
{
	"name": "Ubuntu",
	// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
	"image": "mcr.microsoft.com/devcontainers/base:jammy",
	"features": {
		"ghcr.io/devcontainers/features/terraform:1": {},
		"ghcr.io/devcontainers/features/azure-cli": {}
	}
}

The issue is that the terraform feature is running curl commands which fail on certificate verification. I'm trying to see if there is a way to get the self signed cert mounted and installed in the container so that curl can see it. It appears that the, onCreateCommand, postCreateCommand and postStartCommand all run after the features are installed. I was attempting to mount the wsl /usr/local/share/ca-certificates folder into the docker image and run update-ca-certificates but it's just not happening early enough it seems. I was able to download the install.sh file for the terraform feature and execute it in a container that performs the above so I'm pretty sure that it will work if I can get the ordering correct.

Thanks,
Shane

@chrmarti
Copy link
Contributor

@shaneholder You need to add the certificates before the features are built. You can do that by using a Dockerfile like, e.g., #6092 (comment). There is also documentation on using the devcontainer.json with a Dockerfile: https://containers.dev/guide/dockerfile . HTH!

@shaneholder
Copy link

@chrmarti thanks for that. It's what I ended up doing yesterday. Turns out you can do it with a very minimal Dockerfile and compose.yml file and continue to use the features in devcontainer.json. That last part was an unexpected bonus!

@OneCyrus
Copy link

OneCyrus commented Jan 20, 2025

one thing that that would be cool is if we could also consume this cert bundle in our own containers. maybe a devcontainer option to mount this bundle? or is ther already a hidden way to get to this bundle?

You could probably pick it up from NODE_EXTRA_CA_CERTS. Though ideally we would find a way to automatically add it, but I expect that to be more involved.

@chrmarti we are setting up a repo for internal and external users where we hit this problem again (for internal repos we are just adding the certificates in a static way). but we would like to have a proper/clean solution for a shared repo.
just tried to access the NODE_EXTRA_CA_CERTS but it seems to be empty in the dockerfile so looks like a dead end. are you aware of another way to get access to the injected certificate from the bootstrap container?

@chrmarti
Copy link
Contributor

@OneCyrus NODE_EXTRA_CA_CERTS is set locally, you can access it as ${localEnv:NODE_EXTRA_CA_CERTS} in the devcontainer.json. It holds the filepath of the certificate file.

@OneCyrus
Copy link

@chrmarti just tried with a basic post start command but couldn't get any values in my test.txt file.

"postStartCommand": "echo ${localEnv:NODE_EXTRA_CA_CERTS} > /tmp/test.txt",

so i guess it's not completely clear to me which is the localenv if we use rancher desktop on windows. so is localenv supposed to be on windows (where the vscode UI process is run) or on the wsl instance where rancher desktop executes the docker commands? or would it be inside the boostrap container?

@chrmarti
Copy link
Contributor

@OneCyrus That should put the filepath in the test.txt. Are you using the Dev Containers extension for VS Code? The Dev Containers CLI standalone wouldn't set the env variable. It should work with Rancher. Please append the Dev Containers log after connecting to the dev container. (F1 > Dev Containers: Show Container Log)

@OneCyrus
Copy link

not sure what exactly triggered the change but after some more testing I have the value which is set on windows in ${localEnv:NODE_EXTRA_CA_CERTS}. while I can access this variable it has not too much value to us as we don't have those environment variables configured on the local system. or was the expectation that the NODE_EXTRA_CA_CERTS is set through vscode and is not just the local variable?
for us the perfect solution would be to gain access to the host-ca-certificates.crt from the boostrap container/local OS.

basically mount %temp%\vsch\bootstrap-image\0.394.0\host-ca-certificates.crt to the devcontainer so we can access the data. or automatically set the content to a local env variable after generating the host-ca-certificates.crt file. in the end i would like to eliminate the manual setup of a special local environment to get the devcontainer working.

@pBogey
Copy link

pBogey commented Feb 8, 2025

VSCode vesrion:

Image

Dev Containers version: v0.327.0

Issue:

[3456 ms] Resolving Feature dependencies for 'ghcr.io/devcontainers/features/docker-outside-of-docker:1.6.0'...
[3456 ms] * Processing feature: ghcr.io/devcontainers/features/docker-outside-of-docker:1.6.0
[3785 ms] Error: unable to get local issuer certificate
[3785 ms]     at TLSSocket.onConnectSecure (node:_tls_wrap:1543:34)
[3785 ms]     at TLSSocket.emit (node:events:513:28)
[3785 ms]     at TLSSocket._finishInit (node:_tls_wrap:962:8)
[3785 ms]     at ssl.onhandshakedone (node:_tls_wrap:746:12)
[3790 ms] Exit code 1

Dockerfile:

FROM whatever
ARG DEBIAN_FRONTEND=noninteractive

USER root
COPY --chmod=755 zscaler_certificate.crt /usr/local/share/ca-certificates
RUN update-ca-certificates

USER vscode
ENV NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/zscaler_certificate.crt

dev-containers.json:

    "build": {
        "dockerfile": "Dockerfile"
    },
    "features": {
        "ghcr.io/devcontainers/features/docker-outside-of-docker:1.6.0": {},
    },
    "containerEnv": {
        "SHELL": "/bin/bash",
        "NODE_EXTRA_CA_CERTS": "/usr/local/share/ca-certificates/zscaler_certificate.crt",
    },

Also tried to set "NODE_TLS_REJECT_UNAUTHORIZED": "0" in devcontainers.json, but no effect.
Also tried to set "NODE_EXTRA_CA_CERTS": "/etc/ssl/certs/ca-certificates.crt" in devcontainers.json, but no effect.
Also tried to set "NODE_OPTIONS": "--use-openssl-ca" in devcontainers.json, but no effect.

I have commented out "ghcr.io/devcontainers/features/docker-outside-of-docker:1.6.0": {}, and built the container without just to check the environment,
printenv | grep NODE outputs:
NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/zscaler_certificate.crt

I have set NODE_EXTRA_CA_CERTS in the windows host, in WSL and in the docker image. Nothing worked.
Tried to set NODE_OPTIONS=--use-openssl-ca on host, no effect.

I don't have nodejs installed in the container by default so I don't know if that's alright and how vscode handles it.
But I did install it on my own and ran node -e "console.log(process.env.NODE_EXTRA_CA_CERTS)"
The output was: /usr/local/share/ca-certificates/zscaler_certificate.crt which seems ok.

  • the output of node -e "require('https').get('https://ghcr.io', res => console.log(res.statusCode)).on('error', console.error)" is 301.
  • the output of NODE_OPTIONS="--use-openssl-ca" node -e "require('https').get('https://ghcr.io', res => console.log(res.statusCode)).on('error', console.error)" is also 301.
  • the output of NODE_TLS_REJECT_UNAUTHORIZED=0 node -e "require('https').get('https://ghcr.io', res => console.log(res.statusCode)).on('error', console.error)" is also 301.

I have NODE_EXTRA_CA_CERTS setup in my Windows host machine environment as well. Tried with both / and \ separators and like #6092 (comment):

The path value pointed to by local (Windows) NODE_EXTRA_CA_CERTS has to look like a Linux path. Using a Windows style path (on Windows) DOES NOT work for me. The path needs to look like:

/somepath/somesub1/somesub2/corporate_cert.crt

Inside the container, the output of curl -v https://ghcr.io is:

* Uses proxy env variable no_proxy == 'auth,localhost,127.0.0.1,10.*'
* Uses proxy env variable https_proxy == 'http://zsproxy.com:443'
*   Trying 185.46.212.98:443...
* TCP_NODELAY set
* Connected to zsproxy.com (185.46.212.98) port 443 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to ghcr.io:443
> CONNECT ghcr.io:443 HTTP/1.1
> Host: ghcr.io:443
> User-Agent: curl/7.68.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection Established
< Proxy-Agent: Zscaler/6.2
<
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CONNECT phase completed!
* CONNECT phase completed!
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: CN=*.ghcr.io; O=Zscaler Inc.; OU=Zscaler Inc.
*  start date: Feb  6 02:04:14 2025 GMT
*  expire date: Feb 16 03:25:45 2025 GMT
*  subjectAltName: host "ghcr.io" matched cert's "ghcr.io"
*  issuer: C=US; ST=California; O=Zscaler Inc.; OU=Zscaler Inc.; CN=Zscaler Intermediate Root CA (zscloud.net) (t)
*  SSL certificate verify ok.
> GET / HTTP/1.1
> Host: ghcr.io
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Content-Type: application/json
< docker-distribution-api-version: registry/2.0
< Location: https://github.com/features/packages
< Date: Sat, 08 Feb 2025 10:14:16 GMT
< Content-Length: 0
< X-GitHub-Request-Id: 9D7D:6095:25EA8E2:2684F3E:67A72E78
<
* Connection #0 to host zsproxy.com left intact

Tried to ask AI for help, but nothing useful. I have no idea what else to do.

@stewartadam
Copy link
Member

I'm also running into this after ZScaler got installed on the client machine - devcontainer rebuild fails, it can't pull the base image at all (so we can't even use a customer Dockerfile to install the zscaler certificate/set env variables).

The certificate is trusted on in MacOS keychain, and we also tried setting NODE_EXTRA_CA_CERTS on the host as well as copying the certificate to ~/.docker/certs.d/mcr.microsoft.com/ca.crt to no avail.

=> ERROR [internal] load metadata for mcr.microsoft.com/devcontainers/ba  0.1s
=> [context dev_containers_feature_content_source] load .dockerignore     0.0s
[2025-03-07T21:03:53.178Z]  => => transferring dev_containers_feature_content_source: 2B              0.0s
------
> [internal] load metadata for mcr.microsoft.com/devcontainers/base:bookworm:
------
[2025-03-07T21:03:53.179Z] Dockerfile-with-features:3
--------------------
   1 |     # syntax=docker/dockerfile:1.4
   2 |     ARG _DEV_CONTAINERS_BASE_IMAGE=placeholder
   3 | >>> FROM mcr.microsoft.com/devcontainers/base:bookworm AS dev_container_auto_added_stage_label
[2025-03-07T21:03:53.179Z]    4 |     
   5 |     # Copy the Zscaler CA certificate to the container
--------------------
ERROR: failed to solve: failed to resolve source metadata for mcr.microsoft.com/devcontainers/base:bookworm: failed to do request: Head "[https://mcr.microsoft.com/v2/devcontainers/base/manifests/bookworm"](https://mcr.microsoft.com/v2/devcontainers/base/manifests/bookworm%22): tls: failed to verify certificate: x509: certificate signed by unknown authority
[2025-03-07T21:03:53.183Z] Stop (1252 ms): Run: docker buildx build --load --build-arg BUILDKIT_INLINE_CACHE=1 -f /var/folders/s3/55v4bvrx0nj5191x766nr3980000gq/T/devcontainercli/container-features/0.74.0-1741381424926/Dockerfile-with-features -t vsc-wellingtonv2-1c991f65f881f57212d72943e4a52ddcdba714b97613065316b1974faca911e9 --target dev_containers_target_stage --build-context dev_containers_feature_content_source=/var/folders/s3/55v4bvrx0nj5191x766nr3980000gq/T/devcontainercli/container-features/0.74.0-1741381424926 --build-arg _DEV_CONTAINERS_BASE_IMAGE=dev_container_auto_added_stage_label --build-arg _DEV_CONTAINERS_IMAGE_USER=root --build-arg _DEV_CONTAINERS_FEATURE_CONTENT_SOURCE=dev_container_feature_content_temp /Users/username/myProjects/wellingtonv2/.devcontainer

@chrmarti
Copy link
Contributor

@stewartadam This is Docker failing to connect to the registry. Make sure you add your root CA in your WSL distro too.

@stewartadam
Copy link
Member

@chrmarti this is on a MacOS host - on Windows this is fixed when ZScaler certificate is trusted in the host OS and a Dockerfile is used to update-ca-certificates, but on MacOS the Dockerfile fails to build (cannot pull the base image) even if the zscaler certificate is trusted in the host OS.

@chrmarti
Copy link
Contributor

@stewartadam Please check https://docs.docker.com/engine/network/ca-certs/. This mentions configuring the certificate as "Always Trust" in the key chain. My current understanding is that for downloading images (as the error seems to indicate) Docker needs the required certificates configured in the OS and Dev Containers can't help with that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
containers Issue in vscode-remote containers feature-request Request for new features or functionality plan-review PM-highlighted item determined to be P1 or P2 proxy Issues regarding network proxies
Projects
None yet
Development

No branches or pull requests