├── .travis.yml ├── Dockerfile ├── Makefile ├── README.md └── run.sh /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | services: 4 | - docker 5 | 6 | language: c 7 | install: true 8 | 9 | script: 10 | - make 11 | - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD" -e "$DOCKER_EMAIL" 12 | - docker push whilp/ssh-agent 13 | 14 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:edge 2 | 3 | ENV SOCKET_DIR /ssh 4 | ENV SSH_AUTH_SOCK ${SOCKET_DIR}/auth/sock 5 | RUN apk add --update openssh && rm -rf /var/cache/apk/* 6 | COPY run.sh /run.sh 7 | RUN mkdir -p ${SOCKET_DIR} && chmod 777 ${SOCKET_DIR} 8 | VOLUME ${SOCKET_DIR} 9 | ENTRYPOINT ["/run.sh"] 10 | CMD ["ssh-agent"] 11 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DOCKER ?= docker 2 | 3 | image: 4 | $(DOCKER) build -t whilp/ssh-agent:latest -f Dockerfile . 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ssh-agent 2 | 3 | ssh-agent in a container. 4 | 5 | ## Usage 6 | 7 | ### Run a long-lived container named `ssh-agent`. 8 | 9 | This container declares a volume that hosts the agent's socket so that other invocations of the `ssh` client can interact with it. Specify a UID if you would like non-root `ssh` clients in other containers to be able to connect. 10 | 11 | ```console 12 | docker run -u 1001 -d -v ssh:/ssh --name=ssh-agent whilp/ssh-agent:latest 13 | ``` 14 | 15 | ### Add your ssh keys 16 | 17 | Run a temporary container which has access to both the volumes from the long-lived `ssh-agent` container as well as a volume mounted from your host that includes your SSH keys. This container will only be used to load the keys into the long-lived `ssh-agent` container. Run the following command once for each key you wish to make available through the `ssh-agent`: 18 | 19 | ```console 20 | docker run -u 1001 --rm -v ssh:/ssh -v $HOME:$HOME -it whilp/ssh-agent:latest ssh-add $HOME/.ssh/id_rsa 21 | ``` 22 | 23 | ### Access via other containers 24 | 25 | Now, other containers can access the keys via the `ssh-agent` by setting the `SSH_AUTH_SOCK` environment variable. For convenience, containers that have access to the volume containing `SSH_AUTH_SOCK` can configure their environment using `runit`'s `chpst` tool: 26 | 27 | ```console 28 | docker run --rm -v ssh:/ssh -it alpine:edge /bin/sh -c "apk --update --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing add runit && chpst -e /ssh/env /usr/bin/env | grep SSH_AUTH_SOCK" 29 | fetch http://dl-cdn.alpinelinux.org/alpine/edge/testing/x86_64/APKINDEX.tar.gz 30 | fetch http://dl-cdn.alpinelinux.org/alpine/edge/main/x86_64/APKINDEX.tar.gz 31 | fetch http://dl-cdn.alpinelinux.org/alpine/edge/community/x86_64/APKINDEX.tar.gz 32 | (1/1) Installing runit (2.1.2-r3) 33 | 0% [ ]78 1% [ ]78 10% [#### ]78 17% [####### ]78 24% [########## ]78 36% [############### ]78 51% [###################### ]78 62% [########################## ]78 72% [############################### ]78 82% [################################### ]78100% [###########################################]78Executing busybox-1.24.2-r2.trigger 34 | OK: 5 MiB in 12 packages 35 | SSH_AUTH_SOCK=/ssh/auth/sock 36 | ``` 37 | 38 | ## Examples 39 | 40 | ### List Keys 41 | 42 | ```console 43 | docker run --rm -it -v ssh:/ssh -e SSH_AUTH_SOCK=/ssh/auth/sock ubuntu /bin/bash -c "apt-get update && apt-get install -y openssh-client && ssh-add -l" 44 | ``` 45 | 46 | ## Notes 47 | 48 | - this container provides `ssh-agent` support; other common `ssh` functionality (including `known_hosts` management) is out of scope 49 | 50 | ## Compatibility 51 | 52 | This approach is tested with: 53 | 54 | - OSX / Virtualbox / docker-machine 55 | - OSX / docker for mac 56 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | case "$1" in 4 | ssh-agent) 5 | auth_dir=$(dirname "${SSH_AUTH_SOCK}") 6 | env_dir=$(dirname "${auth_dir}")/env 7 | rm -f "${SSH_AUTH_SOCK}" 8 | mkdir -p "${auth_dir}" 9 | chmod 700 "${auth_dir}" 10 | 11 | # Create an envdir such that `chpst -e /ssh/env /bin/sh` works. 12 | rm -rf "${env_dir}" 13 | mkdir -p "${env_dir}" 14 | echo "${SSH_AUTH_SOCK}" > "${env_dir}/SSH_AUTH_SOCK" 15 | 16 | exec /usr/bin/ssh-agent -a "${SSH_AUTH_SOCK}" -D 17 | ;; 18 | *) 19 | exec $@;; 20 | esac 21 | --------------------------------------------------------------------------------