Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
1e2e5e1
Fixes tini path
netj Jan 24, 2017
e565e45
Ensures ssh uses no connection sharing (`-S none`)
netj Jan 24, 2017
99bca4c
Updates installation directions to include cd command
cleathers Jan 25, 2017
d79b54f
Volume-based approach (WIP)
Feb 3, 2017
186366c
Make pinata-ssh-mount fish compatible
djmaze Feb 5, 2017
2ba664c
Inject authorized keys via env instead of volume
djmaze Feb 5, 2017
01524e4
Use temp file for known hosts
djmaze Feb 5, 2017
d615ba5
Rename LOCAL_* variables to HOST_*
djmaze Feb 5, 2017
979dd6a
Make agent socket accessible by all
djmaze Feb 6, 2017
2b35f4f
Make ssh-agent a named volume
djmaze Feb 6, 2017
e79d9ca
Fix for new volume create syntax
Feb 7, 2017
cedc7d8
Merge remote-tracking branch 'djmaze/socat-based-approach'
BlinkyStitt Feb 8, 2017
d89f0ed
Merge remote-tracking branch 'netj/fix-glitches'
BlinkyStitt Feb 8, 2017
f5567fd
combine apk commands
BlinkyStitt Feb 8, 2017
953624d
run ssh-add -l during forward setup
BlinkyStitt Feb 8, 2017
b495728
line breaks for readability
BlinkyStitt Feb 8, 2017
9defdce
always exit on any error
BlinkyStitt Feb 8, 2017
a3235dd
shellcheck
BlinkyStitt Feb 8, 2017
68c211e
remove duplicate script
BlinkyStitt Feb 8, 2017
c5d2353
move to hub.docker.com/r/uber
BlinkyStitt Feb 8, 2017
de4c4ba
fixes
BlinkyStitt Feb 8, 2017
d4fca3a
Work around missing base64 option on OSX
djmaze Feb 8, 2017
421651f
Merge remote-tracking branch 'djmaze/socat-based-approach'
BlinkyStitt Feb 13, 2017
976c723
rearrange for less layer rebuilds
BlinkyStitt Feb 13, 2017
76a95d8
pin to alpine 3.5
BlinkyStitt Feb 13, 2017
3e0b725
pull from dockerhub instead of build
BlinkyStitt Feb 13, 2017
9bec4b3
rename and rearrange
BlinkyStitt Feb 13, 2017
4743cd6
readme
BlinkyStitt Feb 13, 2017
812ac1a
ssh -T git@github
BlinkyStitt Feb 13, 2017
e2d1756
use our own image
BlinkyStitt Feb 13, 2017
4ad8329
use short flags
BlinkyStitt Feb 13, 2017
cddf2cd
better pull
BlinkyStitt Feb 13, 2017
0e7a935
fix link
BlinkyStitt Feb 13, 2017
4f7cbbe
shorter name
BlinkyStitt Feb 13, 2017
ecf8003
fix for yosemite
BlinkyStitt Feb 14, 2017
a3c3b71
echo a single line
BlinkyStitt Feb 14, 2017
a23575e
Fix clone link in readme
BlinkyStitt Feb 14, 2017
dfc7673
Use mktemp syntax compatible with Yosemite
djmaze Feb 14, 2017
cd9b12b
Generate SSH host key during container startup
djmaze Feb 14, 2017
5a0f070
Merge remote-tracking branch 'djmaze/socat-based-approach'
BlinkyStitt Feb 14, 2017
494b72d
put tini back. not everyone uses docker's init
BlinkyStitt Mar 23, 2017
d5d3931
alpine 3.7 and new style
BlinkyStitt Dec 18, 2017
590369a
remove unhelpful, non-portable options
BlinkyStitt Dec 18, 2017
14357c1
use bash which always has pipefail
BlinkyStitt Dec 18, 2017
bbc77f2
shellcheck
BlinkyStitt Dec 18, 2017
39d5411
Update README.md
durhamka Mar 7, 2018
43d09e9
Merge pull request #5 from durhamka/patch-1
baxor Mar 6, 2019
7e26e9b
Create launch.json
SibuVilakazi Oct 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": []
}
34 changes: 23 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
FROM alpine
MAINTAINER Anil Madhavapeddy <[email protected]>
RUN apk update && apk add openssh && \
apk add --update --repository http://dl-cdn.alpinelinux.org/alpine/edge/community/ tini
RUN mkdir /root/.ssh && \
chmod 700 /root/.ssh && \
ssh-keygen -A
COPY ssh-find-agent.sh /root/ssh-find-agent.sh
FROM alpine:3.7

RUN { set -eux; \
\
mkdir /root/.ssh; \
chmod 700 /root/.ssh; \
}

EXPOSE 22
VOLUME ["/root/.ssh/authorized_keys"]
ENTRYPOINT ["/usr/bin/tini","--"]
CMD ["/usr/sbin/sshd","-D"]

VOLUME ["/ssh-agent"]

ENTRYPOINT ["/sbin/tini", "--", "/docker-entrypoint.sh"]

CMD ["/usr/sbin/sshd", "-D"]

RUN apk add --no-cache \
openssh \
socat \
tini \
;

COPY docker-entrypoint.sh /
COPY ssh-entrypoint.sh /
8 changes: 2 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
all:
./pinata-build-sshd.sh
./pinata-ssh-pull.sh || ./pinata-ssh-build.sh
@echo Please run "make install"

PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin

install:
@if [ ! -d "$(PREFIX)" ]; then echo Error: need a $(PREFIX) directory; exit 1; fi
@mkdir -p $(PREFIX)/share/pinata-ssh-agent
cp Dockerfile $(PREFIX)/share/pinata-ssh-agent
cp ssh-build.sh $(PREFIX)/share/pinata-ssh-agent/ssh-build
cp ssh-find-agent.sh $(PREFIX)/share/pinata-ssh-agent/ssh-find-agent.sh
@mkdir -p $(BINDIR)
cp pinata-build-sshd.sh $(BINDIR)/pinata-build-sshd
cp pinata-ssh-forward.sh $(BINDIR)/pinata-ssh-forward
cp pinata-ssh-mount.sh $(BINDIR)/pinata-ssh-mount
cp pinata-ssh-pull.sh $(BINDIR)/pinata-ssh-pull
39 changes: 30 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,63 @@
Forward SSH agent socket into a container

Still experimental -- contact [email protected] if you want help.
Still experimental -- contact [email protected] or [email protected] if you want help.


## Installation

Assuming you have a `/usr/local`

```
$ git clone git://github.com/avsm/docker-ssh-agent-forward
$ git clone git://github.com/uber-common/docker-ssh-agent-forward
$ cd docker-ssh-agent-forward
$ make
$ make install
```

On every boot, do:

```
$ pinata-ssh-forward
pinata-ssh-forward
```

and the you can run `pinata-ssh-mount` to get a Docker CLI fragment
that adds the SSH agent socket and set `SSH_AUTH_SOCK` within the container.
and the you can run `pinata-ssh-mount` to get a Docker CLI fragment that adds
the SSH agent socket and sets `SSH_AUTH_SOCK` within the container.

```
$ pinata-ssh-mount
-v /Users/avsm/.pinata-sshd/ssh-1azk9Mmd27/agent.16:/tmp/ssh-agent.sock --env SSH_AUTH_SOCK=/tmp/ssh-agent.sock
$ pinata-ssh-mount
-v ssh-agent:/ssh-agent -e SSH_AUTH_SOCK=/ssh-agent/ssh-agent.sock

$ docker run -it `pinata-ssh-mount` ocaml/opam ssh [email protected]
$ docker run -it $(pinata-ssh-mount)
/ssh-agent-forward ssh -T [email protected]
The authenticity of host 'github.com (192.30.252.128)' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,192.30.252.128' (RSA) to the list of known hosts.
PTY allocation request failed on channel 0
Hi avsm! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.
```

To fetch the latest image, do:

```
pinata-ssh-pull
```

## Troubleshooting

If pinata-ssh-forward fails to run, run `ssh-add -l`. If there are no identities, then run `ssh-add`.

## Developing

To build an image yourself rather than fetching from Docker Hub, run
`./pinata-ssh-build.sh` from your clone of this repo.

We didn't bother installing the build script with the Makefile since using the
hub image should be the common case.

## Contributors

* Justin Cormack
* https://github.com/uber-common/docker-ssh-agent-forward/graphs/contributors

[License](LICENSE.md) is ISC.
10 changes: 10 additions & 0 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh
set -eo pipefail

echo "$AUTHORIZED_KEYS" | base64 -d >/root/.ssh/authorized_keys

chown root:root /root/.ssh/authorized_keys

ssh-keygen -A

exec "$@"
4 changes: 0 additions & 4 deletions pinata-build-sshd.sh

This file was deleted.

2 changes: 2 additions & 0 deletions pinata-ssh-build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
exec docker build -t uber/ssh-agent-forward:latest .
67 changes: 50 additions & 17 deletions pinata-ssh-forward.sh
Original file line number Diff line number Diff line change
@@ -1,29 +1,62 @@
#!/bin/sh -e
#!/usr/bin/env bash
set -eo pipefail

IMAGE_NAME=pinata-sshd
IMAGE_NAME=uber/ssh-agent-forward:latest
CONTAINER_NAME=pinata-sshd
LOCAL_STATE=~/.pinata-sshd
LOCAL_PORT=2244
VOLUME_NAME=ssh-agent
HOST_PORT=2244
AUTHORIZED_KEYS=$(ssh-add -L | base64 | tr -d '\n')
KNOWN_HOSTS_FILE=$(mktemp -t dsaf.XXX)

docker rm -f ${CONTAINER_NAME} >/dev/null 2>&1 || true
rm -rf ${LOCAL_STATE}
mkdir -p ${LOCAL_STATE}
trap 'rm ${KNOWN_HOSTS_FILE}' EXIT

docker run --name ${CONTAINER_NAME} \
-v ~/.ssh/id_rsa.pub:/root/.ssh/authorized_keys \
-v ${LOCAL_STATE}:/tmp \
-d -p ${LOCAL_PORT}:22 ${IMAGE_NAME} > /dev/null
docker rm -f "${CONTAINER_NAME}" >/dev/null 2>&1 || true

IP=`docker inspect --format '{{(index (index .NetworkSettings.Ports "22/tcp") 0).HostIp }}' ${CONTAINER_NAME}`
ssh-keyscan -p ${LOCAL_PORT} ${IP} > ${LOCAL_STATE}/known_hosts 2>/dev/null
docker volume create --name "${VOLUME_NAME}"

ssh -f -o "UserKnownHostsFile=${LOCAL_STATE}/known_hosts" \
-A -p ${LOCAL_PORT} root@${IP} \
/root/ssh-find-agent.sh
docker run \
--name "${CONTAINER_NAME}" \
-e AUTHORIZED_KEYS="${AUTHORIZED_KEYS}" \
-v ${VOLUME_NAME}:/ssh-agent \
-d \
-p "${HOST_PORT}:22" \
"${IMAGE_NAME}" >/dev/null \
;

if [ "${DOCKER_HOST}" ]; then
HOST_IP=$(echo "$DOCKER_HOST" | awk -F '//' '{print $2}' | awk -F ':' '{print $1}')
else
HOST_IP=127.0.0.1
fi

# FIXME Find a way to get rid of this additional 1s wait
sleep 1
while ! nc -z -w5 ${HOST_IP} ${HOST_PORT}; do sleep 0.1; done

ssh-keyscan -p "${HOST_PORT}" "${HOST_IP}" >"${KNOWN_HOSTS_FILE}" 2>/dev/null

# show the keys that are being forwarded
ssh \
-A \
-o "UserKnownHostsFile=${KNOWN_HOSTS_FILE}" \
-p "${HOST_PORT}" \
-S none \
"root@${HOST_IP}" \
ssh-add -l

# keep the agent running
ssh \
-A \
-f \
-o "UserKnownHostsFile=${KNOWN_HOSTS_FILE}" \
-p "${HOST_PORT}" \
-S none \
"root@${HOST_IP}" \
/ssh-entrypoint.sh

echo 'Agent forwarding successfully started.'
echo 'Run "pinata-ssh-mount" to get a command-line fragment that'
echo 'can be added to "docker run" to mount the SSH agent socket.'
echo ""
echo 'For example:'
echo 'docker run -it `pinata-ssh-mount` ocaml/opam ssh [email protected]'
echo "docker run -it \$(pinata-ssh-mount) uber/ssh-agent-forward ssh -T [email protected]"
7 changes: 2 additions & 5 deletions pinata-ssh-mount.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
#!/bin/sh

LOCAL_STATE=~/.pinata-sshd
AGENT=`cat ${LOCAL_STATE}/agent_socket_path | sed -e 's,/tmp/,,g'`
echo "-v ${LOCAL_STATE}/$AGENT:/tmp/ssh-agent.sock --env SSH_AUTH_SOCK=/tmp/ssh-agent.sock"
#!/usr/bin/env bash
echo "-v ssh-agent:/ssh-agent -e SSH_AUTH_SOCK=/ssh-agent/ssh-agent.sock"
2 changes: 2 additions & 0 deletions pinata-ssh-pull.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
exec docker pull uber/ssh-agent-forward:latest
5 changes: 0 additions & 5 deletions ssh-build.sh

This file was deleted.

10 changes: 10 additions & 0 deletions ssh-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh
# Forward SSH agent socket to a well-known location
set -eo pipefail

FORWARDED_SOCKET=/ssh-agent/ssh-agent.sock

[ -z "$SSH_AUTH_SOCK" ] && exit 1

rm -f "${FORWARDED_SOCKET}"
socat UNIX-LISTEN:"${FORWARDED_SOCKET}",fork,mode=777 UNIX-CONNECT:"${SSH_AUTH_SOCK}"
9 changes: 0 additions & 9 deletions ssh-find-agent.sh

This file was deleted.