You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a devcontainer that I will be using in vscode and in CI.
In the CI we use devcontainer up/exec
in vscode, we see there is a dev container helper that sets up ssh-agent.
In the CI we setup ssh-agent and add the key, but I cannot find a way to have the same devcontainer works in both environment.
I run vscode on windows and remote container are on linux. I can mount my SSH_AUTH_SOCK to /tmp/ssh-agent.socket and then I can start ssh-agent -a /tmp/ssh-agent.socket, but ssh-add -L still report no identities and outside of the container ssh-add -L do report at least one key that I did add to the ssh-agent.
Would you have an example of how one can use devcontainer with docker-compose to access the local ssh-agent, in a compatible way that would also work within vscode itself?
(when I load the same devcontainer in vscode, the SSH_AUTH_SOCK gets transformed into a ".", yet my linux remove is using ssh-agent and has a proper SSH_AUTH_SOCK value). Somehow I think the Windows version is being used, for which no SSH_AUTH_SOCK exists, but I do have the ssh-agent running on Windows.
I would definitely prefer that the remote container uses the remote linux ssh-agent than my windows.
The ssh-agent forwarding is part of the Dev Containers extension and not part of the Dev Containers CLI. You could mount the ssh-agent's socket and then point SSH_AUTH_SOCK at it.
Strangely when I did mount the ssh-auth-socket to let's say /tmp/ssh-agent.socket and then set SSH_AUTH_SOCK to /tmp/ssh-agent.socket, I could confirm the mount was done and the env was set, but ssh-add was still unable to talk to the ssh-agent itself.
I then start a ssh-agent within the devcontainer itself telling it to use /tmp/ssh-agent.socket and ssh-add was happy but still not finding any of my key which I had in my how ssh-agent.
The other issue, is that when I did so, within vscode things stop working, because the SSH_AUTH_SOCK got converted to "." instead of the real SSH_AUTH_SOCK value, even thougth the dev conatiners extension is able to find that value propery.
If I do that in a docker container it works, but when I do it via the devcontainer cli it doesn't work.
Anyway it would be really nice for devcontainer teams to align and provide an example on how to use ssh-agent in devcontainer CLI in a way compatible with VSCode that is compatible with all OS/remote or not, etc. as it doesn't seem that easy to get working.
You only need to run an ssh-agent on your local machine (where the private keys are), not inside the container. Note that "runArgs" doesn't apply to Docker Compose. I can't get it to work on Mac right now, maybe this has changed.
Another option would be to mount ~/.ssh in the container to get access to the private keys.
Christof Marti (@chrmarti) I would prefer the option of ssh-agent because getting access to the key doesn't get you access to the passphrase to unlock the key which then raises another challenge.
It also simplifies cases where the key to use may not be in the .ssh, some users prefer to use a different folder to make it harder to attackers to find those, etc.
when I do not start the ssh-agent within the container, even thought the socket is mounted, ssh-add simply fail to connect to it and report an error.
I am using VSCode on Windows, then connect to Linux via Remote-SSH and use devcontainer.
Using VSCode, the dev containers helper connect my "Windows" ssh-agent to my devcontainer... which in itself is strange, as I would really like my remote linux to be the ssh-agent, as to not share my keys on my windows machine like I have to now. But that is another matter.
And as indicated then using SSH_AUTH_SOCK env variable it breaks VSCode because then SSH_AUTH_SOCK becomes . and the docker-compose complains that
.:/tmp/ssh-agent.socket
is not a valid volume format.
It somehow look like I would need to start VSCode with SSH_AUTH_SOCK set to my linux SSH_AUTH_SOCK so that VSCode continue to work... which doesn't appear usable.
Using VSCode, the dev containers helper connect my "Windows" ssh-agent to my devcontainer... which in itself is strange, as I would really like my remote linux to be the ssh-agent, as to not share my keys on my windows machine like I have to now. But that is another matter.
That should actually work. If SSH_AUTH_SOCK is properly set in your remote machine's shell startup scripts, the Dev Containers extension should prefer that over the local one. Try running with Dev Container's log level set to 'trace' in the user settings to get the env variables logged as seen by the extension.
And as indicated then using SSH_AUTH_SOCK env variable it breaks VSCode because then SSH_AUTH_SOCK becomes . and the docker-compose complains that
.:/tmp/ssh-agent.socket
is not a valid volume format.
Docker Compose should do the variable replacement there. Maybe another indicator that SSH_AUTH_SOCK isn't properly picked up on the remote machine.
That should actually work. If SSH_AUTH_SOCK is properly set in your remote machine's shell startup scripts, the Dev Containers extension should prefer that over the local one. Try running with Dev Container's log level set to 'trace' in the user settings to get the env variables logged as seen by the extension.
SSH_AUTH_SOCK is set by my .bashrc but in my linux, it works nicely when I use it with ssh, but vscode still translate to .
One interesting thing is that my ssh-agent in order to use a single socket start ssh-agent, create a symlink to the socket and then set SSH_AUTH_SOCK to the symlink.
if [ ! -S /tmp/yk-ssh_auth_sock ]; then
eval $(ssh-agent)
ln -sf "$SSH_AUTH_SOCK" /tmp/yk-ssh_auth_sock
fi
export SSH_AUTH_SOCK=/tmp/yk-ssh_auth_sock
So maybe that could be a reason for this issue. Another could be that .bashrc is only used for some interactive login and I may need to put it in a .profile or .bash_profile, I will try that to see if things change.
But I can assure you that it currently prefer my Windows ssh-agent over my Linux one.
[11009 ms] Start: Launching Dev Containers helper.
[11010 ms] ssh-agent: SSH_AUTH_SOCK in container (/tmp/vscode-ssh-auth-f0cca852-df04-4f31-8740-5fdba9bd0967.sock) forwarded to local host (\\.\pipe\openssh-ssh-agent).
[11010 ms] X11 forwarding: DISPLAY not set on host.
I wish this part was a little more verbose and somehow provide clues as to why my Linux ssh-agent was not found, maybe some kind of warning that the SSH_AUTH_SOCK is not set, the extension fallback to the native host ssh-agent ? With some URL pointing to how to properly set SSH_AUTH_SOCK in a way for Remote-SSH to detect it.
Because the issue my SSH_AUTH_SOCK is set when I used ssh manually, it is also set when I used remote-ssh feature of VSCode, it is only apparently not set when I used the remote-devcontainer plugin feature.
I have removed the symlink by using ssh-agent -a and no change.
if [ ! -S /tmp/yk-ssh_auth_sock ]; then
eval $(ssh-agent -a /tmp/yk-ssh_auth_sock)
fi
still attach to my windows ssh-agent:
[9765 ms] Start: Launching Dev Containers helper.
[9765 ms] ssh-agent: SSH_AUTH_SOCK in container (/tmp/vscode-ssh-auth-1c2a37c7-9284-4ad4-99a7-7013dc50c28a.sock) forwarded to local host (\\.\pipe\openssh-ssh-agent).
[9766 ms] X11 forwarding: DISPLAY not set on host.
I also added the ssh-agent setup in my .bash_profile and .profile, no impact.
That doesn't seem to be the full log. Check for userEnvProbe in the full log, that will run twice, first on the SSH server and then in the container. For the ssh-agent forwarding on the SSH server, the first is of interest.
Also check your local ~/.ssh/config for ForwardAgent yes, that might overwrite SSH_AUTH_SOCK.
Ryan Butler (@TheButlah) The ssh-agent is only forwarded when using the Dev Containers extension for VS Code. The Dev Containers CLI does not do that yet. Labelling as feature request.
One wishes I have is that once devcontainer/cli does it, that vscode stop doing it on its own and relies on the devcontainer/cli tool to do it instead. The idea is that there is a single mechanism to understand/document/debug.
It also seems like there is a similar system related to GPG, likely both would need to be moved from vscode to devcontainer/cli.
BTW, to solve this, I had to both mount the agent socket into the container, set the permission of the socket to allow the user to access it, and set SSH_AUTH_SOCK env var to point to the socket.
On mac, the socket path was the magic path of /run/host-services/ssh-auth.sock, whereas on linux this is likely dynamic.
I still advocate that this functionality be implemented directly in the devcontainers cli, as figuring out how to do all of that was a nightmare.
Ryan Butler (@TheButlah) I will see if I can repro your result, I am on Ubuntu and I have attempted many things, without success so far. Also there seem to be 2 modes of usage in devcontainer, either Dockefile, docker-compose. I am using docker-compose, which may be slightly different sometimes. I remember having tried to mount the socket in docker-compose and check permission, also move the ssh-agent socket location from ~/.ssh/ which was not accessible to /tmp/, and then also passing an SSH_AUTH_SOCK value that made sense within the container, but where I had success with normal docker container, it didn't work, from memory, using devcontainer.
Is unfortunately non-portable to other OS like Windows. Native support from devcontainer/cli is required.
I would also like to flag that vscode is additionally do some more magic that involved even .gitconfig. I wonder if is there a plan to migrate all these essential functionality to devcontainer/cli?
Based on what I'm gathering (and for my several years of trying to do this lazily across docker and k8s) this will require a wrapper so you can mux PTY/std fds and agent sock to target container over stdin/stdout. Which I'm guessing is what the extension does when it runs, based on what I see in lsof. Some similar logic to adapt to whatever Windows needs. Frankly, the easiest solution right now is to run an sshd inside the container (that's super ugly, but will result in less complaints from my devs that writing my own minimally used thing) since it will handle all this stuff out of the box.
It's a nontrivial effort because basically the same pty logic from docker's run/exec commands to setup the terminal and do the right thing over stdin/stdout to the daemon. Then, each channel (pty/ssh agent/gpg agent/x11 socket/...) needs its own flow control to avoid head-of-line blocking before demux. BTW, this technique is definitely required in k8s where you can't easily just reach in and mount stuff. Of course if Microsoft didn't hold the dev containers extension behind the proprietary firewall, this could probably be made to work a bit quicker with some copy+paest engineering.
My use-case is simple: I want to develop in containers without vscode or similar tooling and simply hop in, vim it good, commit, and push all from within the container. I should be able to leave the containers running, drop my ssh session, hop back in, deal with it being run as another user (so realistically, the socket should be proxied inside the container) and generally be as clean every time i do a devcontainer exec.
If the issue is socket permissions (e.g. host user is root, container user is non-root), you can use socat in the container to proxy to the host's ssh-agent socket. Stick something like this in the postCreateCommand lifecycle step:
# usage:# devcontainer up \# --remote-env "SSH_AUTH_SOCK=/tmp/ssh-auth-sock" \# --mount "type=bind,source=${SSH_AUTH_SOCK},target=/tmp/ssh-auth-sock" \# ... etc.# If SSH_AUTH_SOCK exists and isn't owned by the container user, use socat to proxy# between a socket owned by the container user and the one mounted in from the hostiftest -n "${SSH_AUTH_SOCK:-}" \
&&test"${SSH_AUTH_SOCK}"!= ~/.ssh/socket \
&&test"$(stat -c "%u:%g""${SSH_AUTH_SOCK}")"!= "$(id -u):$(id -g)";then
ssh_auth_sock=~/.ssh/socket;# If the remapped ssh socket doesn't already existif!test -f "${ssh_auth_sock}";then# Map the host's ssh-agent socket to one owned by the container user
sudo --background socat "UNIX-LISTEN:${ssh_auth_sock},fork,user=$(id -nu),group=$(id -ng),mode=777""UNIX-CONNECT:${SSH_AUTH_SOCK}";
sleep 5;fi# test the remapped ssh-agent socket
SSH_AUTH_SOCK="${ssh_auth_sock}" ssh-add -L 1>&2;# set SSH_AUTH_SOCK to the new remapped oneecho"SSH_AUTH_SOCK=${ssh_auth_sock}">>~/.bashrc;export SSH_AUTH_SOCK="${ssh_auth_sock}";unset ssh_auth_sock;fi
Activity
metaskills commentedon Mar 16, 2023
Curious as well, there seems to be tons of old documentation on how to do this (https://stackoverflow.com/questions/43418188/ssh-agent-forwarding-during-docker-build) but it appears there is more modern (still old) tooling with
docker build --sshtoo. moby/moby#6396 (comment)chrmarti commentedon Mar 21, 2023
The ssh-agent forwarding is part of the Dev Containers extension and not part of the Dev Containers CLI. You could mount the ssh-agent's socket and then point SSH_AUTH_SOCK at it.
hpe-ykoehler commentedon Mar 21, 2023
Strangely when I did mount the ssh-auth-socket to let's say /tmp/ssh-agent.socket and then set SSH_AUTH_SOCK to /tmp/ssh-agent.socket, I could confirm the mount was done and the env was set, but ssh-add was still unable to talk to the ssh-agent itself.
I then start a ssh-agent within the devcontainer itself telling it to use /tmp/ssh-agent.socket and ssh-add was happy but still not finding any of my key which I had in my how ssh-agent.
The other issue, is that when I did so, within vscode things stop working, because the SSH_AUTH_SOCK got converted to "." instead of the real SSH_AUTH_SOCK value, even thougth the dev conatiners extension is able to find that value propery.
hpe-ykoehler commentedon Mar 21, 2023
and docker-compose.yml:
If I do that in a docker container it works, but when I do it via the devcontainer cli it doesn't work.
Anyway it would be really nice for devcontainer teams to align and provide an example on how to use ssh-agent in devcontainer CLI in a way compatible with VSCode that is compatible with all OS/remote or not, etc. as it doesn't seem that easy to get working.
chrmarti commentedon Mar 21, 2023
You only need to run an ssh-agent on your local machine (where the private keys are), not inside the container. Note that "runArgs" doesn't apply to Docker Compose. I can't get it to work on Mac right now, maybe this has changed.
Another option would be to mount
~/.sshin the container to get access to the private keys.hpe-ykoehler commentedon Mar 21, 2023
Christof Marti (@chrmarti) I would prefer the option of ssh-agent because getting access to the key doesn't get you access to the passphrase to unlock the key which then raises another challenge.
It also simplifies cases where the key to use may not be in the .ssh, some users prefer to use a different folder to make it harder to attackers to find those, etc.
when I do not start the ssh-agent within the container, even thought the socket is mounted, ssh-add simply fail to connect to it and report an error.
I am using VSCode on Windows, then connect to Linux via Remote-SSH and use devcontainer.
Using VSCode, the dev containers helper connect my "Windows" ssh-agent to my devcontainer... which in itself is strange, as I would really like my remote linux to be the ssh-agent, as to not share my keys on my windows machine like I have to now. But that is another matter.
And as indicated then using SSH_AUTH_SOCK env variable it breaks VSCode because then SSH_AUTH_SOCK becomes . and the docker-compose complains that
is not a valid volume format.
It somehow look like I would need to start VSCode with SSH_AUTH_SOCK set to my linux SSH_AUTH_SOCK so that VSCode continue to work... which doesn't appear usable.
chrmarti commentedon Mar 22, 2023
I agree, using the ssh-agent seems preferable.
That should actually work. If
SSH_AUTH_SOCKis properly set in your remote machine's shell startup scripts, the Dev Containers extension should prefer that over the local one. Try running with Dev Container's log level set to 'trace' in the user settings to get the env variables logged as seen by the extension.Docker Compose should do the variable replacement there. Maybe another indicator that
SSH_AUTH_SOCKisn't properly picked up on the remote machine.hpe-ykoehler commentedon Mar 22, 2023
SSH_AUTH_SOCK is set by my .bashrc but in my linux, it works nicely when I use it with ssh, but vscode still translate to .
One interesting thing is that my ssh-agent in order to use a single socket start ssh-agent, create a symlink to the socket and then set SSH_AUTH_SOCK to the symlink.
So maybe that could be a reason for this issue. Another could be that .bashrc is only used for some interactive login and I may need to put it in a .profile or .bash_profile, I will try that to see if things change.
But I can assure you that it currently prefer my Windows ssh-agent over my Linux one.
I wish this part was a little more verbose and somehow provide clues as to why my Linux ssh-agent was not found, maybe some kind of warning that the SSH_AUTH_SOCK is not set, the extension fallback to the native host ssh-agent ? With some URL pointing to how to properly set SSH_AUTH_SOCK in a way for Remote-SSH to detect it.
Because the issue my SSH_AUTH_SOCK is set when I used ssh manually, it is also set when I used remote-ssh feature of VSCode, it is only apparently not set when I used the remote-devcontainer plugin feature.
hpe-ykoehler commentedon Mar 22, 2023
I have removed the symlink by using ssh-agent -a and no change.
still attach to my windows ssh-agent:
I also added the ssh-agent setup in my .bash_profile and .profile, no impact.
chrmarti commentedon Mar 23, 2023
Could you run with the Dev Container's log level set to 'trace' in the user settings to get the env variables logged as seen by the extension?

chrmarti commentedon Mar 23, 2023
I will also improve logging for this. For now we can use the trace logging output.
hpe-ykoehler commentedon Mar 23, 2023
In the area around ssh-agent, there apparently are no trace logs.
chrmarti commentedon Mar 24, 2023
That doesn't seem to be the full log. Check for
userEnvProbein the full log, that will run twice, first on the SSH server and then in the container. For the ssh-agent forwarding on the SSH server, the first is of interest.Also check your local
~/.ssh/configforForwardAgent yes, that might overwriteSSH_AUTH_SOCK.2 remaining items
chrmarti commentedon Apr 3, 2023
You can find log files from previous sessions with
F1>Dev Containers Developer: Show All Logs....TheButlah commentedon May 17, 2023
Would it be possible to add a cli arg to make this more easily possible? I am confused how to do this.
chrmarti commentedon May 19, 2023
Ryan Butler (@TheButlah) The ssh-agent is only forwarded when using the Dev Containers extension for VS Code. The Dev Containers CLI does not do that yet. Labelling as feature request.
hpe-ykoehler commentedon May 19, 2023
One wishes I have is that once devcontainer/cli does it, that vscode stop doing it on its own and relies on the devcontainer/cli tool to do it instead. The idea is that there is a single mechanism to understand/document/debug.
It also seems like there is a similar system related to GPG, likely both would need to be moved from vscode to devcontainer/cli.
TheButlah commentedon May 19, 2023
BTW, to solve this, I had to both mount the agent socket into the container, set the permission of the socket to allow the user to access it, and set
SSH_AUTH_SOCKenv var to point to the socket.On mac, the socket path was the magic path of
/run/host-services/ssh-auth.sock, whereas on linux this is likely dynamic.I still advocate that this functionality be implemented directly in the devcontainers cli, as figuring out how to do all of that was a nightmare.
hpe-ykoehler commentedon Aug 24, 2023
Ryan Butler (@TheButlah) I will see if I can repro your result, I am on Ubuntu and I have attempted many things, without success so far. Also there seem to be 2 modes of usage in devcontainer, either Dockefile, docker-compose. I am using docker-compose, which may be slightly different sometimes. I remember having tried to mount the socket in docker-compose and check permission, also move the ssh-agent socket location from ~/.ssh/ which was not accessible to /tmp/, and then also passing an SSH_AUTH_SOCK value that made sense within the container, but where I had success with normal docker container, it didn't work, from memory, using devcontainer.
andronat commentedon Aug 29, 2023
JFYI by mounting
/run/host-services/ssh-auth.sockon yourdevcontainer.jsonlike:Is unfortunately non-portable to other OS like Windows. Native support from
devcontainer/cliis required.I would also like to flag that vscode is additionally do some more magic that involved even
.gitconfig. I wonder if is there a plan to migrate all these essential functionality todevcontainer/cli?randomthingsandstuff commentedon Apr 22, 2024
Based on what I'm gathering (and for my several years of trying to do this lazily across docker and k8s) this will require a wrapper so you can mux PTY/std fds and agent sock to target container over stdin/stdout. Which I'm guessing is what the extension does when it runs, based on what I see in lsof. Some similar logic to adapt to whatever Windows needs. Frankly, the easiest solution right now is to run an sshd inside the container (that's super ugly, but will result in less complaints from my devs that writing my own minimally used thing) since it will handle all this stuff out of the box.
It's a nontrivial effort because basically the same pty logic from docker's run/exec commands to setup the terminal and do the right thing over stdin/stdout to the daemon. Then, each channel (pty/ssh agent/gpg agent/x11 socket/...) needs its own flow control to avoid head-of-line blocking before demux. BTW, this technique is definitely required in k8s where you can't easily just reach in and mount stuff. Of course if Microsoft didn't hold the dev containers extension behind the proprietary firewall, this could probably be made to work a bit quicker with some copy+paest engineering.
My use-case is simple: I want to develop in containers without vscode or similar tooling and simply hop in, vim it good, commit, and push all from within the container. I should be able to leave the containers running, drop my ssh session, hop back in, deal with it being run as another user (so realistically, the socket should be proxied inside the container) and generally be as clean every time i do a devcontainer exec.
trxcllnt commentedon May 13, 2024
If the issue is socket permissions (e.g. host user is
root, container user is non-root), you can use socat in the container to proxy to the host's ssh-agent socket. Stick something like this in thepostCreateCommandlifecycle step:Explicitly set SSH_AUTH_SOCK for devcontainer CLI
Explicitly set SSH_AUTH_SOCK for devcontainer CLI
ci: sign devcontainer commits through the forwarded ssh agent (#119)