Search code examples
dockersshcontainersalpine-linuxsshd

Setup Docker Container with SSH server?


I want to setup a very minimalistic alpine linux docker container with the following capabilities:

  • It runs an ssh server
  • It copies over a SSH public key of my choice to which I can then authenticate

I looked into various options, and in the end decided to write my own small Dockerfile. However, I ran into some problems.

Dockerfile

FROM alpine:latest

RUN apk update
RUN apk upgrade
RUN apk add openssh-server

RUN mkdir -p /var/run/sshd
RUN mkdir -p /root/.ssh

ADD authorized_keys /root/.ssh/authorized_keys
ADD entrypoint.sh /entrypoint.sh
RUN chmod 755 /entrypoint.sh

EXPOSE 22
CMD ["/entrypoint.sh"]

entrypoint.sh

#!/bin/sh
/usr/sbin/sshd -D

authorized_keys

ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBP8cIHIPgV9QoAaSsYNGHktiP/QnWfKPOeyzjujUXgQMQLBw3jJ1EBe04Lk3FXTMxwrKk3Dxq0VhJ+Od6UwzPDg=

Starting the container gives an error: sshd: no hostkeys available -- exiting. How can I fix my Dockerfile, to ensure the ssh server is running correctly and the authorized_keys file is there. What am I missing?


Solution

  • In order to start, the SSH daemon does need host keys.
    Those does not represents the keys that you are going to use to connect to your container, just the keys that define this specific host.

    A host key is a cryptographic key used for authenticating computers in the SSH protocol.

    Source: https://www.ssh.com/ssh/host-key

    So you have to generate some keys for your host, you can then safely ignore those if you do not really intend to use them.

    Generating those keys can be done via

    ssh-keygen -A
    

    So in your image, just adding a

    RUN ssh-keygen -A
    

    should do.


    For the record, here is my own sshd Alpine image:

    FROM alpine
    
    RUN apk add --no-cache \ 
            openssh \
        && ssh-keygen -A \
        && mkdir /root/.ssh \
        && chmod 0700 /root/.ssh \
        && echo "root:$(openssl rand 96 | openssl enc -A -base64)" | chpasswd \
        && ln -s /etc/ssh/ssh_host_ed25519_key.pub /root/.ssh/authorized_keys
    
    EXPOSE 22
    
    CMD ["/usr/sbin/sshd", "-D", "-e"]
    

    Extra notes:

    • I am reusing the SSH keys generated by ssh-keygen -A, exposing them in a volume, this is the reason why I am doing the command:
      ln -s /etc/ssh/ssh_host_ed25519_key.pub /root/.ssh/authorized_keys
      
    • Because this is just an Ansible node cluster lab, I am SSH'ing this machine as the root user, this is why I need the, quite insecure
      echo "root:$(openssl rand 96 | openssl enc -A -base64)" | chpasswd