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

Allow forwarding SSH agent in fig #551

Closed
clifton opened this issue Oct 17, 2014 · 24 comments
Closed

Allow forwarding SSH agent in fig #551

clifton opened this issue Oct 17, 2014 · 24 comments

Comments

@clifton
Copy link

clifton commented Oct 17, 2014

What's the best practice on cloning private repos (e.g. gems or npm modules)? Currently, I'd need to add my private ssh keys into the repo via volumes in fig.yml. Is there a better way?

I'd think the optimal way of handling this would be to forward the ssh agent. Perhaps have an option in the fig.yml for doing that?

Example: https://gist.github.com/d11wtq/8699521

@dnephin
Copy link

dnephin commented Oct 17, 2014

This example is using a volume to share the socket, and setting the environment variable to tell ssh to use that socket. That seems like a good solution, and you can do that from fig.yml using volumes and environment.

@clifton
Copy link
Author

clifton commented Oct 17, 2014

Having some difficulties with this approach. Given:

web:
  build: .
  command: sh -c "bundle install --local && bundle exec rackup -p 3000"
  volumes:
    - .:/app
    - $(dirname $SSH_AUTH_SOCK):/ssh-agent
  environment:
    - SSH_AUTH_SOCK=/ssh-agent/Listeners
  ports:
    - "3000:3000"

I get as output:

λ docker inspect `dl`
    "Volumes": {
        "/app": "/Users/clifton/code/app",
        "/ssh-agent": "/Users/clifton/code/app/$(dirname /private/tmp/com.apple.launchd.oJSUPJOFqq/Listeners)"
    },

So, host env variables are parsed when using volumes, but subshells do not run and are just parsed as text. In the environment, host variables are not parsed which seems inconsistent.

@clifton
Copy link
Author

clifton commented Oct 17, 2014

Related: moby/moby#6396 and moby/moby#6697. Would be open to hearing other thoughts or if it would be OK to allow shell code in the yaml.

@nicklinnell
Copy link

@clifton I too am having the same issue and I guessing like me you are using a vm in OSX? The problem as I see it is that currently boot2docker will automatically mount the /Users directory but the /tmp directory where the SSH socket is on a mac will not be. This means that instead of mounting the path on the host machine the path on the vm is mounted which is wrong.

Could the /tmp directory be automated too or is that not a good idea?

@clifton
Copy link
Author

clifton commented Oct 23, 2014

Yep, I'm using boot2docker from OSX. I'm still lost as to how I can could get non-trival environments up and running without resorting to hacks.

@defunctzombie
Copy link

I imagine one day docker will have a way of building using secrets. Until then, I wrote a docker build replacement called docket which lets you build with private files from your host machine. If you can hack fig to run docket instead of the regular docker build, it should let you build with your private ssh keys.

@pwaller
Copy link

pwaller commented Apr 28, 2015

This works:

  volumes:
    - /run/user/1000/keyring-foo/ssh:/run/user/1000/keyring-foo/ssh
  environment:
    - SSH_AUTH_SOCK

So if you were able to put $SSH_AUTH_SOCK under volumes:, we'd be set.

/ref #495 #939 #1338

@aanand
Copy link

aanand commented Apr 29, 2015

@pwaller Actually, with volumes you can already pass in environment variables, so that should work.

@pwaller
Copy link

pwaller commented Apr 29, 2015

Thanks for the tip @aanand ! I don't see that documented anywhere over here, is it a secret/new feature? :)

@aanand
Copy link

aanand commented Apr 29, 2015

No, just a hole in the documentation I'm afraid.

@cddr
Copy link

cddr commented May 26, 2015

So someone clarify for this dummy the undocumented feature? What should I put in my volumes to make this work?

@pwaller
Copy link

pwaller commented May 26, 2015

@cddr: try

volumes:
    - $SSH_AUTH_SOCK:$SSH_AUTH_SOCK
  environment:
    - SSH_AUTH_SOCK

Good luck!

@djhi
Copy link

djhi commented Jun 8, 2015

I had no luck with this. Did you manage to get this working ?

volumes:
    - $SSH_AUTH_SOCK:$SSH_AUTH_SOCK

Env variables are not replaced

@clifton
Copy link
Author

clifton commented Jun 8, 2015

@djhi, in our Vagrantfile we have

  config.trigger.after [:up, :reload] do
    command = %Q(vagrant ssh -- -t 'ln -sf `ls -d /tmp/ssh*/* | head -n 1` /tmp/authsock; sh')
    pid = Process.spawn(command, out: '/dev/null', err: '/dev/null')
    Process.detach(pid)
  end
web:
  volumes:
    - /tmp:/tmp
  environment:
    SSH_AUTH_SOCK: /tmp/authsock

@catuss-a
Copy link

@clifton nice one! This is what I needed but apparently ssh cannot follow authsock:

$> docker exec -it ID_CONTAINER bash
root@id:/usr/src/app: echo $SSH_AUTH_SOCK
/tmp/authsock

root@id:/usr/src/app: ssh-add -L
coult not open a connection to your authentification agent.

root@id:/usr/src/app: ls -l /tmp/authsock
/tmp/authsock -> /tmp/ssh-..../agent.blabla

root@id:/usr/src/app: SSH_AUTH_SOCK=/tmp/ssh-..../agent.blabla
root@id:/usr/src/app: ssh-add -L
ssh-rsa AAAAA....................................................................................

do you have any idea to fix that ?

EDIT: Never mind, I just remplaced ln -s by mv and it works. Thanks again!

@clifton
Copy link
Author

clifton commented Jun 25, 2015

Yep, no problem! @hadronzoo came up with the solution, so credit to him

@djhi
Copy link

djhi commented Jul 2, 2015

Thx clifton, we don't use vagrant and ended up mouting the user .ssh folder in the container.

--volume home/your_user_name/.ssh: /home/user/.ssh:ro

The container user is user, ro to make it readonly.

@objectfox
Copy link

Passing env variables on both sides of the volume option doesn't work yet, but (thanks to @dnephin for pointing this out in #1626) this should work:

volumes:
    - $SSH_AUTH_SOCK:/tmp/agent.sock
environment:
    - SSH_AUTH_SOCK=/tmp/agent.sock

You mount the randomly named SSH_AUTH_SOCK file as a fixed name file in the container, and then instead of passing the env variable, you set it explicitly.

@catuss-a
Copy link

catuss-a commented Jul 3, 2015

@jeffk This always worked for me on Linux, without any VM since I run docker on an available linux kernel.
However on Mac I had to use @hadronzoo's trick to make it work. Problem is (IMHO) Vbox does not allow sharing sockets.

@djhi
Copy link

djhi commented Jul 3, 2015

Where can I find the trick from @hadronzoo ? Some of my colleagues are on Mac

@catuss-a
Copy link

catuss-a commented Jul 3, 2015

@djhi Get rid of boot2docker and use Vagrant. Then in your Vagrantfile write that:

config.trigger.after [:up, :reload] do
    command = %Q(vagrant ssh -- -t 'ln -sf `ls -d /tmp/ssh*/* | head -n 1` /tmp/authsock; sh')
    pid = Process.spawn(command, out: '/dev/null', err: '/dev/null')
    Process.detach(pid)
end

You need to install the triggers vagrant plugin. Then in your docker-compose you can share the socket by creating a volume on /tmp:/tmp and set SSH_AUTH_SOCK to /tmp/authsock

EDIT: don't forget to set ssh-forwarding option to true in your Vagrantfile

@djhi
Copy link

djhi commented Jul 3, 2015

Ok, thx @catuss-a !

@atrauzzi
Copy link

atrauzzi commented Apr 29, 2016

There's an issue here when someone doesn't want to run their container as root. If I forward either an SSH directory or the agent and I'm running the container as a UID to match my filesystem, I can't use SSH due to the fact that it insists on the user being in passwd.

You end up getting this:

image

I'm basically stuck again having to run an entrypoint script to hand off a username that I then have to ensure exists inside the container to satisfy ssh. Not optimal.

@zimbatm
Copy link

zimbatm commented Apr 29, 2016

I think you might want to use socat on the host, a bridge to bypass the uid detection. With socat you could bind on another socket and connect to the original SSH_AUTH_SOCK. Since socat would be running under the same uid the connection would work fine.

EDIT: On the host run socat -v -dd unix-listen:./foo.sock,fork unix-connect:$SSH_AUTH_SOCK. Then volume-mount the foo.sock file and set it as your SSH_AUTH_SOCK inside of the container.

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

No branches or pull requests