Last active
October 23, 2020 03:22
-
-
Save pwillis-els/446f00b6df5caf033dd86ae951eb3938 to your computer and use it in GitHub Desktop.
Run an sshd-enabled version of any Docker container so you can login to the container remotely and do work in it
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Runs a detached Docker container with an entrypoint to run an sshd daemon. | |
CONTAINER_IMG="my-container-image:latest" | |
CONTAINER_USER="deploy" # the user the container runs as | |
CONTAINER_HOME="/home/$CONTAINER_USER" # home directory in the container | |
HOST_SSH_PORT="2222" # The port to export sshd to on localhost | |
CONTAINER_SSH_PORT="2222" # The port of sshd in the container | |
set -eu | |
# Before running this script, export an environment variable SSH_AUTHORIZED_KEY to | |
# the value of the SSH public key you want to login to the container. | |
# Then run the sshd container below. | |
# | |
# This will volume-map the host's docker.sock, | |
# make a persistent Terraform plugin cache, | |
# a persistent volume for miscellaneous uses, | |
# the SSH public key created above (so we can login with it), | |
# maps in the entrypoint to set up and start sshd, | |
# and exports the sshd port to the local host. | |
docker run \ | |
--rm --detach \ | |
-v sshd-persist:$CONTAINER_HOME/persist \ | |
-e SSH_AUTHORIZED_KEY \ | |
-v `pwd`/sshd-entrypoint.sh:/sbin/sshd-entrypoint.sh \ | |
--entrypoint=/sbin/sshd-entrypoint.sh \ | |
-p 127.0.0.1:$HOST_SSH_PORT:$CONTAINER_SSH_PORT \ | |
"$CONTAINER_IMG" | |
# Now you can login from the Docker host with the following: | |
# ssh \ | |
# -v \ | |
# -o ForwardAgent=yes \ | |
# -o IdentitiesOnly=yes \ | |
# -i container-ssh-key.pem \ | |
# -l $CONTAINER_USER \ | |
# -p $HOST_SSH_PORT \ | |
# 127.0.0.1 | |
# | |
# Or you can use the Docker host as a bastion for the container, with the following: | |
# ssh \ | |
# -o ProxyCommand="ssh -o IdentitiesOnly=yes -i ~/.ssh/docker-host.pem -p 22 docker-host-user@docker-host-ip -N -W %h:%p" \ | |
# -i container-ssh-key.pem \ | |
# -o IdentitiesOnly=yes \ | |
# -o ForwardAgent=yes \ | |
# -o CheckHostIP=no -o StrictHostKeyChecking=no \ | |
# -p $HOST_SSH_PORT \ | |
# -l $CONTAINER_USER \ | |
# 127.0.0.1 | |
# | |
# Note that with ForwardAgent=yes, your SSH keys have been forwarded into the container so you don't need to | |
# download them there. | |
# | |
# The CheckHostIP=no and StrictHostKeyChecking=no options are needed because the container's ssh host keys will | |
# change every time it starts. You may have to remove the previous host keys to get ForwardAgent to work again. | |
# |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Install and run sshd in a Docker container | |
# | |
# The idea is to take any existing container, not have to rebuild or change it, and still | |
# run an ssh daemon inside it. Therefore we don't assume the container is running as root, | |
# so we set up and run sshd as whatever user the container runs as. | |
# | |
# We also assume the container contains openssh-server, but if not, we try to install it | |
# with a package manager. If the user isn't root and sudo isn't bundled, this will fail. | |
# You can try running the container as root to get around this (`docker run --user root`) | |
# The sshd port to listen on in the container. As this might be a non-root user, use a high port. | |
[ -n "${SSHD_PORT:-}" ] || SSHD_PORT="2222" | |
# Install sshd if it wasn't before. Try to use sudo if we're not root. | |
[ -n "${USER:-}" ] || USER="`id -un`" | |
[ ! "$USER" = "root" ] && command -v sudo && SUDO=sudo | |
if [ ! -x /usr/sbin/sshd ] ; then | |
command -v apk && $SUDO apk add --update --no-cache openssh-server # Alpine | |
command -v apt-get && $SUDO apt-get update && $SUDO apt-get install -y openssh-server # Debian | |
command -v yum && $SUDO yum -y install openssh-server # CentOS | |
fi | |
# Here we don't mess with the .ssh folder too much in case you want to volume-mount | |
# your own .ssh folder into the container. If you don't volume-mount in the | |
# $HOME/.ssh_key.pub file, .ssh will be left alone. You can also set the environment | |
# variable SSH_AUTHORIZED_KEY to your public key and this will be added to .ssh/authorized_keys | |
mkdir -p .ssh | |
[ -n "${SSH_AUTHORIZED_KEY:-}" ] && printf "%s\n" "$SSH_AUTHORIZED_KEY" >> .ssh/authorized_keys | |
[ -r "$HOME/.ssh_key.pub" ] && cat "$HOME/.ssh_key.pub" >> .ssh/authorized_keys | |
# Compose the sshd_config file | |
mkdir -p .sshd/etc/ssh | |
ssh-keygen -A -f .sshd # generate new SSH host keys | |
cd .sshd ; CWD="`pwd`" | |
echo "Port $SSHD_PORT | |
PasswordAuthentication no | |
PermitUserEnvironment yes" > sshd_config | |
for i in `ls etc/ssh/ssh_host_* | grep -v pub` ; do | |
echo "HostKey $CWD/$i" >> sshd_config | |
done | |
# Fix this user's login shell if it's currently set to nologin | |
( getent passwd "$USER" | grep -q nologin ) && $SUDO usermod -s /bin/sh "$USER" | |
# Unlock account but disable the password (only ssh keys allowed) | |
$SUDO usermod -p '*' "$USER" | |
# If you remove "-D" here it should run sshd in the background, but that means the container may | |
# stop running if no command is specified at runtime (we are overriding the entrypoint, remember). | |
# Try running sshd with sudo in case we want to try binding to low ports. | |
$SUDO /usr/sbin/sshd -D -e -f sshd_config |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment