This provides a minimal Docker container for keeping the connections to remote servers that are placed behind (several layers) of NATed networks. I use this to keep track of Raspberry Pis, "in the wild" and behind mobile connections. The image sacrifices a little bit of security for ease of use, but this can be turned off.
The idea is to provide a dockerised sshd (on top of Alpine), remote servers will open a reverse ssh tunnels to the exposed host (running the docker container) and you will then be able to log into the remote servers via the reverse tunnels, i.e. via the exposed host.
As long as you carefully mount host directories through the -v
option, you
will be able to keep your settings between restarts. Let's take a real life
example to kickstart the description:
docker run -it --rm -p 2222:22 --name rsshd -p 10000-10100:10000-10100 -e PASSWORD=secret -v /opt/keys/host:/etc/ssh/keys -v /opt/keys/clients:/root/.ssh efrecon/rsshd
This example would:
- Start a container listening for incoming ssh connections on port
2222
. - Be able to accept 101 clients, through exposing ports
10000
to10100
. These will be the ports to which you will direct ssh connection on the host once everything is setup. - Arrange to give a "very secret" password to the
root
user within the Alpine-based container. This is because Alpine has no default password forroot
and because this is probably not a very good idea, and not something that is supported by ssh. If you do not provide a password, one will be generated randomly at start, and printed to the logs for capture and use. - Mount the host keys onto the
/opt/keys/host
on the host computer. This enables to keep the same keys at every restart of the container. The keys are generated if they do not exist whenever the container is started. - Mount the list of authorised clients (your servers!) in the host directory at
/opt/keys/clients
, to pertain restarts. - The command run in interactive mode, but you will probably want to replace the
options
-it --rm
, with at least-d
and even perhaps-d --restart=always
to make sure your remote servers can always connect.
To test things out, from a remote server, you could issue a command such as:
ssh -p 2222 [email protected]
The command will prompt you for the password of the root
user in the container
(e.g. secret
in the previous example) and let you in. The command supposes
that you can access your server on domain.tld
and that its firewall permits
connections on port 2222
. However, to open a permanent tunnel, you would
rather enter a command such as:
ssh -fN -R 10000:localhost:22 -p 2222 [email protected]
This would create a reverse tunnel on port 10000
so you can connect to your
server from the host running the docker container using (user
being a user on
the remote server):
ssh -p 10000 user@localhost
Using autossh
and through making sure you can login without the need for a
password, you should be able to keep those connections alive for longer periods
of time. More information is available in this
guide,
but in summary you should perform the following steps:
On the remote server, create the DSA key (if necessary) and copy it to the host running the container through the following commands:
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub -p 2222 [email protected]
To keep the connection open at all times through autossh
, issue the following:
autossh -M 10099 -fN -o "PubkeyAuthentication=yes" -o "StrictHostKeyChecking=false" -o "PasswordAuthentication=no" -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R 10000:localhost:22 -p 2222 [email protected]
On a RaspberryPi, adding this line to /etc/rc.local
will ensure that the
connection is kept alive at all times.
If you set the environment variable LOCAL
to 1
, e.g. -e LOCAL=1
when
starting with docker run
, you will not be able to access the tunnels from
outside the container. Instead, you will have to jump in the container with
docker exec -it rsshd ash
and from within, issue commands such as:
ssh -p 10000 user@localhost
This provides complete encapsulation, at the expense of another layer of "jumping" whenver you need to access your servers.