• Modern UX

    Edit and navigate faster in the terminal with Warp's IDE-like input editor.

  • Warp AI

    AI suggests what commands to run and learns from your documentation.

  • Agent Mode

    Delegate tasks to AI and use natural language on the command line.

  • Warp Drive

    Save and share interactive notebooks, workflows, and environment variables.

  • All Features

Run SSH In Docker

Thumbnail for Gabriel ManricksGabriel Manricks

Gabriel Manricks

Chief Architect, ClearX

Published: 7/29/2024

About Terminus

Before getting started, if you want to inspect or execute commands in a running Docker container, you should read our other article on how to run a Bash shell in Docker.

Writing a Dockerfile for an SSH server with password-based authentication

To create a containerized SSH server running in Ubuntu with minimal configuration to which you can connect using a username/password pair, you can use the following Dockerfile:

FROM ubuntu

RUN apt-get update && apt-get install -y openssh-server

RUN mkdir /var/run/sshd

RUN echo "root:password" | chpasswd

RUN echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config

CMD ["/usr/sbin/sshd", "-D"]

Run in Warp

Where:

  • FROM ubuntu will set the base image as the latest available version of Ubuntu.
  • RUN apt-get update && apt-get install -y openssh-server will update the package index and install the openssh-server package used to run the SSH server.
  • RUN mkdir /var/run/sshd will create the /var/run/sshd directory used by the SSH server to store temporary runtime data.
  • RUN echo "root:mypassword" | chpasswd will set the password of the root user to mypassword.
  • RUN echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config will update the SSH configuration file to allow root login.
  • CMD ["/usr/sbin/sshd", "-D"] will launch the SSH server as a background task when the container starts.

Writing a Dockerfile for an SSH server with SSH keys authentication

The second way to connect to an SSH server is to use a pair of public/private keys.

Generating a pair of SSH keys

To generate a new pair of SSH keys, you can use the ssh-keygen command as follows:

$ ssh-keygen -b 4096 -t rsa -f dockerkey

Run in Warp

Where:

  • -b 4096 specifies a key length of 4096 bits.
  • -t rsa specifies a RSA key type.
  • -f dockerkey specifies dockerkey as the name of the key file.

Upon execution, this command will generate two files: dockerkey containing the private key and dockerkey.pub containing the public key.

Writing the Dockerfile

To create a containerized SSH server running in Ubuntu with minimal configuration to which you can connect using a pair of SSH keys, you can use the following Dockerfile:

FROM ubuntu:latest

RUN apt-get update && apt-get install -y openssh-server

RUN mkdir /var/run/sshd

COPY ./dockerkey.pub /root/.ssh/authorized_keys

CMD ["/usr/sbin/sshd", "-D"]

Run in Warp

Where:

  • COPY ./dockerkey.pub /root/.ssh/authorized_keys will copy the public key generated using the ssh-keygen command from the local machine into the /root/.ssh/authorized_keys[.inline-code] directory of the image.

Building and running the SSH container

To build the Dockerfile into a runnable Docker image, you can use the following docker build command:

$ docker build . -t ssh-host

Run in Warp

Where:

  • . specifies that the Dockerfile is located in the current directory.
  • -t ssh-host specifies the name of the Docker image.

Once built, you can launch a new container from this image using the following docker run command:

$ docker run -p 2222:22 ssh-host

Run in Warp

Where:

  • -p 2222:22 is used to map the port 2222 of the host to the SSH port 22 of the container.

Connecting to the SSH container

Connecting with a username/password pair

To connect to the SSH server running in the container using a username/password pair, you can use the ssh command as follows:

$ ssh <username>@<host> -p <port>

Run in Warp

Where:

  • username is the username defined in the Dockerfile.
  • host is the IP or address of the machine the container is running on.
  • port is the port on the host system defined in the docker run command.

Once executed, you will be prompted to enter the password.

For example, the following command will connect to the SSH server running on your local machine through the port 2222 with the root user:

$ ssh root@localhost -p 2222

Run in Warp

Connecting with a private key file

To connect to the SSH server running in the container using a private key file, you can use the ssh command with the -i flag as follows:

$ ssh -i <key> <username>@<host> -p <port>

Run in Warp

Where:

  • key is the path to the private key file.
  • username is the username defined in the Dockerfile.
  • host is the IP or address of the machine the container is running on.
  • port is the port on the host system defined in the docker run command.

For example, the following command will connect to the SSH server running on your local machine through the port 2222 with the root user account using the dockerkey private key file:

$ ssh -i dockerkey root@localhost -p 2222

Run in Warp

Easily retrieve this syntax using the Warp AI feature

If you’re using Warp as your terminal, you can easily retrieve this syntax using the Warp AI feature:

Thumbnail for

Entering docker image with ssh and keys in the AI question input will prompt a human-readable step by step guide including code snippets.

Handling terminal signals gracefully

As Linux tends to disregard the signals sent to the primary process, thus preventing it from being manually stopped using for instance CTRL + C, you have to manually handle these signals by wrapping the main process in a script as follows:

#!/bin/bash

/usr/sbin/sshd -D &
pid="$!"
trap "kill -SIGTERM $pid" SIGINT SIGTERM
wait $pid

Run in Warp

Where:

  • /usr/sbin/sshd -D & runs the SSH server as a background task.
  • pid="$!" stores the process ID of the server into the pid variable.
  • trap is used to catch and handle SIGINT and SIGTERM signals to kill the server.
  • wait $pid prevents the container from terminating while the server is still running.

In the server's Dockerfile, you can then replace this instruction:

CMD ["/usr/sbin/sshd", "-D"]

Run in Warp

By the following one:

COPY ./init.sh /init.sh
RUN chmod +x /init.sh

CMD ["/init.sh"]

Run in Warp

Where the new lines:

  • COPY ./init.sh /init.sh will copy the script into the container.
  • RUN chmod +x /init.sh will make the script executable.
  • CMD will set the script as the container's startup command.

Securing the SSH server configuration

When working with OpenSSH, you can mitigate potential exposure and enhance overall security measures by creating a configuration file named sshd_config containing the following properties:

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
AcceptEnv LANG LC_*
Subsystem	sftp	/usr/lib/openssh/sftp-server

Run in Warp

Where:

  • PermitRootLogin no will disable root login via SSH.
  • PasswordAuthentication no will disable password-based authentication, encouraging the use of more secure authentication methods such as SSH keys.
  • KbdInteractiveAuthentication no will disable keyboard-interactive authentication, which typically involves mechanisms like challenge-response authentication.
  • AllowAgentForwarding no will prevent the SSH client from using the SSH keys stored on the local host to connect to other remote servers.
  • AllowTcpForwarding no will prevent TCP traffic from being forwarded over the SSH connection.
  • X11Forwarding no will prevent GUI applications running on the remote server to display on the local machine
  • AcceptEnv LANG LC_* specifies that the only accepted environment variables from the client are related to language and locale settings.
  • Subsystem sftp /usr/lib/openssh/sftp-server will define the subsystem for handling SFTP requests.

And add the following instruction to your Dockerfile:

COPY ./sshd_config /etc/ssh/sshd_config

Run in Warp

Which will copy the sshd_config file into the /etc/ssh/ directory of the image at build time.

Forwarding the SSH agent to a Docker container

ssh-agent is a command-line tool used to simplify the management of SSH keys by keeping them encrypted in memory and automatically providing them to SSH when needed.

This allows users to avoid repeatedly typing passphrases when using SSH keys, and in the context of Docker, to avoid copying SSH keys into containers to connect to third-party services like Git.

Creating a containerized SSH client

To create a containerized SSH client that allows you to connect to an SSH server from within a Docker container, you can use the following Dockerfile:

FROM ubuntu

RUN apt-get update && apt-get install -y openssh-client

CMD ["sleep", "infinity"]

Run in Warp

Where:

  • FROM ubuntu will set the base image as the latest available version of Ubuntu.
  • RUN apt-get update && apt-get install -y openssh-client will update the package index and install the OpenSSH client.
  • CMD ["sleep", "infinity"] will make the container sleep indefinitely, keeping it running in the background without executing any other commands.

And build the Dockerfile into a Docker image named ssh-client using the following docker build command:

$ docker build . -t ssh-client

Run in Warp

Setting up the SSH agent for a standard Docker installation

ssh-agent works by creating a socket file where tools can proxy requests to communicate commands and authenticate, so to forward the agent into a container you basically have to mount this socket into the container and set an environment variable with the path to the socket. This will make all requests inside the container for ssh-agent essentially be forwarded to the host session.

In a standard CLI installation of Docker you can create a new ssh-agent session by running:

To start the ssh-agent tool in the background and set the value of the SSH_AUTH_SOCK environment variable to the path of the SSH agent socket, you can use the following command:

$ eval $(ssh-agent)

Run in Warp

Next, you can add SSH keys to the SSH agent session using the ssh-add command as follows:

$ ssh-add <path>

Run in Warp

Where:

  • path is the relative or absolute path to the SSH key file.

Finally, you can run the ssh-client container in interactive mode using the following docker run command:

$ docker run -it -v $SSH_AUTH_SOCK:$SSH_AUTH_SOCK -e SSH_AUTH_SOCK=$SSH_AUTH_SOCK ssh-client bash

Run in Warp

Where: 

  • The -v flag is used to mount the SSH agent socket from the host into the container, whose location is stored in the SSH_AUTH_SOCK environment variable.
  • The -e flag is used to set the SSH_AUTH_SOCK environment variable so that the SSH client inside the container knows where to find the SSH agent socket.

Written by

Thumbnail for Gabriel ManricksGabriel Manricks

Gabriel Manricks

Chief Architect, ClearX

Filed Under

Related Articles

Override the Container Entrypoint With docker run

Learn how to override and customize the entrypoint of a Docker container using the docker run command.

Docker

The Dockerfile ARG Instruction

Learn how to define and set build-time variables for Docker images using the ARG instruction and the --build-arg flag.

Docker
Thumbnail for Razvan LudosanuRazvan Ludosanu

Start a Docker Container

Learn how to start a new Docker container from an image in both the foreground and the background using the docker-run command.

Docker
Thumbnail for Razvan LudosanuRazvan Ludosanu

Stop All Docker Containers

How to gracefully shutdown running containers and forcefully kill unresponsive containers with signals in Docker using the docker-stop and docker-kill commands.

Docker
Thumbnail for Razvan LudosanuRazvan Ludosanu

Use An .env File In Docker

Learn how to write and use .env files in Docker to populate the environment of containers on startup.

Docker

Launch MySQL Using Docker Compose

Learn how to launch a MySQL container in Docker Compose.

DockerSQL

Execute in a Docker Container

Learn how to execute one or multiple commands in a Docker container using the docker exec command.

Docker
Thumbnail for Razvan LudosanuRazvan Ludosanu

Expose Docker Container Ports

Learn how to publish and expose Docker container ports using the docker run command and Dockerfiles.

Docker

Restart Containers In Docker Compose

Learn how to restart and rebuild one or more containers in Docker Compose.

Docker
Thumbnail for Razvan LudosanuRazvan Ludosanu

Output Logs in Docker Compose

Learn how to output, monitor, customize and filter the logs of the containers related to one or more services in Docker Compose

Docker
Thumbnail for Razvan LudosanuRazvan Ludosanu

Rename A Docker Image

Learn how to rename Docker images locally and remotely using the docker tag command.

Docker

Understand healthcheck in Docker Compose

Learn how to check if a service is healthy in Docker Compose using the healthcheck property.

Docker
Thumbnail for Gabriel ManricksGabriel Manricks

Trusted by hundreds of thousands of professional developers

Download Warp to get started

Download for Mac
Thumbnail for null