SSH server in containers
This is a write-up of my encounter with https://docs.linuxserver.io/images/docker-openssh-server/. I needed to copy few files from one laptop to another (Mac). Both laptops had file sharing disabled (ie no ssh server) by management software. Given I use containers almost every day, I decided to run an ssh server on a custom (non-privileged) port on destination laptop and copy the files over.
Disclaimer
There are easier and faster ways to copy from one machine to another. This method is neither.
Setup
I was thinking of simply pulling a base image and installing OpenSSH server on it. Luckily, I didn't have to - a google search ("docker hub openssh") yielded a link to linuxserver.io site full of goodies - list of widely used container images with nice documentation.
This works as long as you have docker running on your machine.
- Create an ssh key on the client and copy its public key over to machine hosting the openssh-server
- Never share SSH private keys (or any private keys) with users/systems you do not know or trust.
- Run the server on port 8022
- Copy with
scp
SSH keys
This is optional. You could just use your existing keys, but I recommend creating dedicated ones in case you accidentally expose the private key (for example, you commit it into a repo when blogging about it).
If you don't have the ssh-keygen
utility installed, you can generate one with the container image:
$ mkdir mykeys
$ docker run --rm --entrypoint=/bin/sh -v "$(pwd)/mykeys:/keys" linuxserver/openssh-server -c 'ssh-keygen -q -f /keys/id_rsa -N ""'
$ ls -lR mykeys
-rw------- 1 user usergroup 2602 Jan 21 14:52 id_rsa
-rw-r--r-- 1 user usergroup 571 Jan 21 14:52 id_rsa.pub
The id_rsa.pub
is the public key that needs to be transferred to target machine.
For prompted options, you can choose to use the bundled generator script
$ docker run --rm -it --entrypoint /keygen.sh linuxserver/openssh-server
Please select your key type to generate
1.) ecdsa
2.) rsa
3.) ed25519
4.) dsa
[default ecdsa]:
...
Running the server
On the target machine, create a directory named openssh
under your home directory. Inside it create a directory for public SSH keys and another one for putting the sent files - let's name them pubkeys
and dropzone
respectively. Put the SSH public key from the previous step (file name can be arbitrary).
$ mkdir -p $HOME/openssh/{pubkeys,dropzone}
$ cp <mykey.pub> $HOME/openssh/pubkeys/pubkey
Instead of putting these parameters into command line, let's run it with docker compose. Create a docker-compose.yml
file (anywhere on the system, or under $HOME/openssh
) with following contents:
# ~/openssh/docker-compose.yml
---
version: "2.1"
services:
openssh-server:
image: lscr.io/linuxserver/openssh-server:latest
container_name: openssh-server
hostname: openssh-server #optional
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- PUBLIC_KEY_DIR=/config/pubkeys
- SUDO_ACCESS=false
- USER_NAME=johndoe
volumes:
- ${HOME}/openssh/:/config
ports:
- 8022:2222
restart: unless-stopped
The PUID and PGID parameters can be ignored as docker will use local user's UID and GID for copied files. The USER_NAME
will be used on the client side to establish the connection.
Now it's time to launch the server with docker compose up
. Add -d
flag at the end to daemonize the process.
Copying the files from the client
Rest is a regular SSH transfer. Assuming the private key is stored under ~/.ssh/mykey
, you can copy a file with scp
:
$ scp -F /dev/null -o UserKnowHostsFile=/dev/null -o StrictHostKeyChecking=no -P 8022 -i ~/.ssh/mykey archive.zip johndoe@192.168.1.2:dropzone/
What are these /dev/null
s? We are telling the scp
not to read any ssh_config (if there is one under ~/.ssh
which might affect connection), write the host info into nothing and not to check server's host key (as the key will be rotating with each container boot-up). As this was a test usage in local network, I did not care about validating the server. In work or production environments, you need to pay attention to those.
Conclusion
With this post, I wanted to highlight using containerized tools to accomplish task without relying on system applications. In reality, I was annoyed by not being able to simply copy files between laptops (btw, external cards were disabled too). I could have easily uploaded files to cloud and download it from the other side, but did the hard way from a principle.