Skip to content

Instantly share code, notes, and snippets.

@d11wtq
Created January 29, 2014 23:32
Show Gist options
  • Save d11wtq/8699521 to your computer and use it in GitHub Desktop.
Save d11wtq/8699521 to your computer and use it in GitHub Desktop.
How to SSH agent forward into a docker container
docker run -rm -t -i -v $(dirname $SSH_AUTH_SOCK) -e SSH_AUTH_SOCK=$SSH_AUTH_SOCK ubuntu /bin/bash
@slmingol
Copy link

This exposes the value of the $SSH_AUTH_SOCK (whichiis the path to a socket file on the host) as a volume into the docker container (at the location /ssh-agent). Inside the container you then set the environment variable $SSH_AUTH_SOCK with the path to the volume inside, /ssh-agent). Since this environment variable is now set, ssh-agent -l can make use of it inside the container. When you run these commands inside the docker container you're root and so you have access.

@arunthampi
Copy link

If you're running this command in a Vagrant created VM, you might have problems with the file in $SSH_AUTH_SOCK being a symlink, so this worked for me:

docker run -i -t -v $(readlink -f $SSH_AUTH_SOCK):/ssh-agent -e SSH_AUTH_SOCK=/ssh-agent ubuntu /bin/bash

@tobowers
Copy link

Anyone get this to work in boot2docker yet?

@penguincoder
Copy link

+1 @arunthampi That works very well in my Vagrant+Docker setup. I was using a Docker container to run Capistrano commands, so I had a few other things. I needed to add a --env CAP_USER=$CAP_USER and then in my Vagrant VM .bashrc source a file that contained my remote CAP_USER username.

File /home/vagrant/.cap_user contains just remote-user
Then in file: /home/vagrant/.bashrc I have a line like this:

    test -f ~/.cap_user && export CAP_USER=$(cat ~/.cap_user) || true

I set that file up in the VM using the Vagrantfile shell provisioner to copy both files into the VM.

Viola. Capistrano deploying happening inside a Docker container.

@dts
Copy link

dts commented Mar 1, 2015

@tobowers: Works for me on boot2docker on mac, but I have to do it in two steps, SSH into the host VM, then run @arunthampi's code. Like so:

 $ boot2docker ssh
 $ docker run -i -t -v $(readlink -f $SSH_AUTH_SOCK):/ssh-agent -e SSH_AUTH_SOCK=/ssh-agent ubuntu /bin/bash

Once you're in to the host VM, you can check out forwarding status with ssh-add -L. If you get the publickeys you expect, proceed into the container.

@bigeasy
Copy link

bigeasy commented Apr 1, 2015

@dts You forgot -A.

$ boot2docker ssh -A
$ ssh-add -l
2048 97:f0:e8:b3:c6:cb:2b:06:93:31:f5:a5:c6:0c:22:07 /Users/alan/.ssh/id_rsa (RSA)
$ docker run -i -t -v $(readlink -f $SSH_AUTH_SOCK):/ssh-agent -e SSH_AUTH_SOCK=/ssh-agent ubuntu /bin/bash
$ apt-get -q=2 update && apt-get -q=2 install ssh > /dev/null 2>&1
$ ssh-add -l
2048 97:f0:e8:b3:c6:cb:2b:06:93:31:f5:a5:c6:0c:22:07 /Users/alan/.ssh/id_rsa (RSA)

@andrerocker
Copy link

@tobowers On boot2docker Just your home dir is available on boot2docker-vm, maybe if you symlink the ssh-agent socket to $HOME/something this can work.

@rosskevin
Copy link

I'm trying this, but with docker-compose. I was typing a comment, but too much for this gist. Any help is appreciated over on http://stackoverflow.com/questions/32897709/ssh-key-forwarding-inside-docker-compose-container

@f3l1x
Copy link

f3l1x commented Apr 5, 2016

Great thanks.

docker run --volume $SSH_AUTH_SOCK:/ssh-agent --env SSH_AUTH_SOCK=/ssh-agent ubuntu ssh-add -l

Works pretty well!

@kynan
Copy link

kynan commented Oct 23, 2016

Has anyone managed to use SSH agent forwarding in combination with running the container as a different user e.g. docker run -u $(id -u):$(id -g) --volume $SSH_AUTH_SOCK:/ssh-agent --env SSH_AUTH_SOCK=/ssh-agent ...?

SSH actually checks that the effective UID is present in the password database and fails with You don't exist, go away! otherwise.

@whistler
Copy link

whistler commented Oct 27, 2016

I get the following error when trying this out. I'm using a mac and have tried this on both docker for mac and docker-machine. I had to first install git on the ubuntu image.

docker run --volume $SSH_AUTH_SOCK:/ssh-agent --env SSH_AUTH_SOCK=/ssh-agent ubuntu ssh-add -l                             ✹ ✭
Error connecting to agent: Connection refused

@gautaz
Copy link

gautaz commented Nov 3, 2016

@whistler, sharing the auth socket is currently not working for docker for mac, see:
docker/for-mac#410

It seems there is a work in progress that should be available before the end of November:
docker/for-mac#483

@jrolfs
Copy link

jrolfs commented Dec 23, 2016

@gautaz thanks for the heads up!

@vladkras
Copy link

vladkras commented Jul 18, 2017

What if I have Windows? How to use SSH_AUTH_SOCK?

I can clone repo with common git for WIndows, but not inside the container

@sylvain261
Copy link

It would very helpfull to get a clarification on how to share ssh keys when the hots is windows (maybe by a key copy..)

@leandrocrs
Copy link

@Sylvain, give a chance to WSL (Windows Subsystem for Linux).

@dragon788
Copy link

@kynan if you aren't using a remote user database for your system (eg LDAP/AD) you can map in /etc/passwd read-only so SSH can find your user.

Copy link

ghost commented Nov 9, 2017

Maybe, there is similar way to integrate gpg into docker container?

@tamsky
Copy link

tamsky commented Aug 4, 2018

@ghost asks

Maybe, there is similar way to integrate gpg into docker container?

Browsing around, I saw this: https://github.com/transifex/docker-gpg-agent-forward

@marxangels
Copy link

marxangels commented Mar 5, 2019

How if docker-compose and docker-daemon not in a same machine such as boot2docker?
I want to put this bunch of parameters in the docker-compose.yaml instead of typing them every time.

@sbussetti
Copy link

sbussetti commented Jul 8, 2019

For anyone who comes across this: This will not work for anyone using Docker for Mac due to os limitations around file socket access. See: docker/for-mac#410

@benjertho
Copy link

This works for me for the first shell logon, but fails for successive attempts. My use case is a remote container that has a longer lifespan, usually of a couple weeks. Is there a solution that is robust against the changing of the SSH_AUTH_SOCK target?

docker run -dit \
	--network host \
	--gpus all \
	--restart unless-stopped \
	--privileged \
	-e "DISPLAY=$DISPLAY" \
	-e "QT_X11_NO_MITSHM=1" \
        -e "$SSH_AUTH_SOCK:/ssh-agent" \
        -e "SSH_AUTH_SOCK=/ssh-agent" \
	-v "$XSOCK:$XSOCK" \
	-v "$HOME/data:/root/data:rw" \
	-v "$HOME/.gitconfig:/root/.gitconfig" \
	--name $NAME $NAME:latest bash

@jameshopkins
Copy link

The official guidance works for me, when nothing else has. It's not very well explained, but the bind mount paths are magic values to allow SSH agent forwarding.

@GuillermoAndrade
Copy link

-e "$SSH_AUTH_SOCK:/ssh-agent" \

maybe -v here instead of -e ?

@timur265
Copy link

timur265 commented Apr 21, 2021

Hi everyone. I have the same problem. Has anyone found the solution?
This works for me for the first shell login, but fails for successive attempts

sudo docker run --restart always --network host --name github-runner -v $SSH_AUTH_SOCK:/ssh-agent -e SSH_AUTH_SOCK=/ssh-agent -e REPO_URL="$REPO_NAME" -e ACCESS_TOKEN="$ACCESS_TOKEN" myoung34/github-runner:latest

@conf
Copy link

conf commented May 24, 2021

If you're on a mac, the current incantation should be:

docker run -it --rm -v /run/host-services/ssh-auth.sock:/run/host-services/ssh-auth.sock -e SSH_AUTH_SOCK="/run/host-services/ssh-auth.sock" debian bash

@tomdavies
Copy link

For anyone struggling to get ssh-agent forwarding to work for non-root container users, here's the workaround I came up with, running my entry point script as root, but using socat + su-exec to expose the socket to the non-root user and then run commands as that user:

  1. Add socat and su-exec to the container in your Dockerfile (you might not need the later if you're not using alpine)
USER root
RUN apk add socat su-exec
# for my use case I need www-data to have access to SSH, so 
RUN \
    mkdir -p /home/www-data/.ssh && \
    chown www-data:www-data /home/www-data/.ssh/
  1. In your entrypoint:
#!/bin/sh
# Map docker's "magic" socket to one owned by www-data
socat UNIX-LISTEN:/home/www-data/.ssh/socket,fork,user=www-data,group=www-data,mode=777 \
    UNIX-CONNECT:/run/host-services/ssh-auth.sock \
    &
# set SSH_AUTH_SOCK to the new value
export SSH_AUTH_SOCK=/home/www-data/.ssh/socket
# exec commands as www-data via su-exec
su-exec www-data ssh-add -l
# SSH agent works for the www-data user, in reality you probably have something like su-exec www-data "$@" here
  1. Run your container as @conf states:
docker run -it --rm -v /run/host-services/ssh-auth.sock:/run/host-services/ssh-auth.sock -e SSH_AUTH_SOCK="/run/host-services/ssh-auth.sock" name cmd

@unphased
Copy link

shrug this: -v "$SSH_AUTH_SOCK:$SSH_AUTH_SOCK" -e SSH_AUTH_SOCK=$SSH_AUTH_SOCK worked for me. The original gist did not.

@josepsmartinez
Copy link

@unphased Probably due to the symlink situation, as @arunthampi noticed here.

The line the worked for me was docker run -i -t -v $(readlink -f $SSH_AUTH_SOCK):/ssh-agent -e SSH_AUTH_SOCK=/ssh-agent ubuntu /bin/bash

@Paprikas
Copy link

Paprikas commented Jun 7, 2022

@unphased
volume $SSH_AUTH_SOCK:/ssh-agent
and ENV SSH_AUTH_SOCK=/ssh-agent worked for me for years.
But after I've upgraded packages to the latest (ubuntu 22), the agent just stopped working! I mean - ssh-add -l was saying that it does not have access to the agent.
Thank you, your snippet works! Spent the whole day on this issue ))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment