Run an ssh server

Newly published guide: Run an ssh server. A somewhat belated response to questions such as this one. Being able to run your own ssh server is a common requirement as a building block for higher level services. I’ve been using it for quite a while to enable rsync to/from volumes in my application.

The current topic that triggered this for me is that I was looking into Kamal. This exploration has expanded into other tools such as docker compose, and ansible. The guide linkeda above is a longer explanation, but collapsing it down, the following will produce something that could be used as a starting point for ansible or Kamal:

FROM cruizba/ubuntu-dind

# install and configure sshd, python3
RUN apt-get update \
 && apt-get install -y openssh-server python3 \
 && cp /etc/ssh/sshd_config /etc/ssh/sshd_config-original \
 && sed -i 's/^#\s*Port.*/Port 2222/' /etc/ssh/sshd_config \
 && sed -i 's/^#\s*PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config \
 && mkdir -p /root/.ssh \
 && chmod 700 /root/.ssh \
 && mkdir /var/run/sshd \
 && chmod 755 /var/run/sshd \
 && sed -i "/# Execute/i # Start sshd\necho \$AUTHORIZED_KEYS > /root/.ssh/authorized_keys\n/usr/sbin/sshd\n" /usr/local/bin/entrypoint.sh \
 && rm -rf /var/lib/apt/lists /var/cache/apt/archives

ENTRYPOINT ["entrypoint.sh"]
CMD ["sleep", "infinity"]

The corresponding fly.toml updates would look like:

[[services]]
  internal_port = 2222
  protocol = "tcp"
  auto_stop_machines = true
  auto_start_machines = true
  [[services.ports]]
    port = 22

To complete this picture, set a single secret:

fly secrets set "AUTHORIZED_KEYS=$(cat ~/.ssh/id_rsa.pub)"

While that’s a starting point, it actually is a bare machine that wouldn’t pass a health check if one were defined. Either deploying the full app and then later updating it via ansible/kamal/whatever, or deploying a stub that is replaced gets us further.

There is lots more to be explored. It would be really nice if Kamal could use our builders and registry directly, there might be unfortunate interactions between Traefik and our load balancer, and there undoubtedly are other unknowns.

docker compose turns out to be a different beast entirely. The technical problems with running multiple docker images in a single vm are all solvable; the biggest issue is that having CMD docker compose up leads to a rather poor user experience: fly deploy assimes that a new machine can start in milliseconds. Inserting the start of an entire build process into that flow leads to bad things.

In any case, the published guide is useful immediately. And should it spark a larger discussion, that would be a wonderful bonus.

5 Likes