Acceder por SSH a Web App for Containers

Cuando despliegas una aplicación dockerizada en Web App for Containers es posible que necesites acceder en algún momento por SSH al contenedor. En el portal tienes un apartado llamado SSH que, si no configuras correctamente tu imagen, quedará inservible.

Web App for Containers – conexión fallida por SSH

En este artículo te comparto la configuración necesaria para poder acceder.

Dockerfile

Dependiendo de la distribución de Linux sobre la que bases tu contenedor, la instalación de paquetes puede ser diferente. En este ejemplo te muestro cómo sería para Alpine:

FROM php:7.2.13-fpm-alpine3.8
ENV SSH_PORT 2222
RUN apk add --update openssh supervisor \
&& rm  -rf /tmp/* /var/cache/apk/*
RUN mkdir -p /var/run/sshd /var/log/supervisor
RUN echo 'root:Docker!' | chpasswd
COPY sshd_config /etc/ssh/
ADD supervisord.conf /etc/supervisord.conf
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod -R +x /usr/local/bin
EXPOSE 2222
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["supervisord", "--nodaemon", "--configuration", "/etc/supervisord.conf"]

Como ves, a través de apk add instalo openssh, además de supervisord que me ayudará a monitorizar mis procesos.

La contraseña que debes utilizar para que puedas acceder desde el portal es Docker!. Por otro lado tengo un archivo llamado sshd_config donde tengo la configuración propia del servidor SSH:

# This is ssh server systemwide configuration file.
#
# /etc/sshd_config
Port 			2222
ListenAddress 		0.0.0.0
LoginGraceTime 		180
X11Forwarding 		yes
Ciphers aes128-cbc,3des-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr
MACs hmac-sha1,hmac-sha1-96
StrictModes 		yes
SyslogFacility 		DAEMON
PasswordAuthentication 	yes
PermitEmptyPasswords 	no
PermitRootLogin 	yes
Subsystem sftp internal-sftp

Como estoy haciendo uso de supervisord, también tengo que tener su configuración, donde le especifico cuál es el proceso que quiero ejecutar y monitorizar, que es sshd:

[supervisord]
logfile=/var/log/supervisor/supervisord.log
nodaemon=true
unmask=0000
user=root
 
[program:sshd]
command=/usr/sbin/sshd -D
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log

El puerto que debes exponer es el 2222, que es el que usará el portal para intentar realizar la conexión por SSH.

Por último, puedes ver que utilizo como ENTRYPOINT un archivo llamado docker-endpoint.sh donde genero las claves necesarias para el servidor ssh:

#!/bin/sh
if [ ! -f "/etc/ssh/ssh_host_rsa_key" ]; then
  # generate fresh rsa key
  ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa
fi
if [ ! -f "/etc/ssh/ssh_host_dsa_key" ]; then
  # generate fresh dsa key
  ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N '' -t dsa
fi
if [ ! -f "/etc/ssh/ssh_host_ecdsa_key" ]; then
  # generate fresh ecdsa key
  ssh-keygen -f /etc/ssh/ssh_host_ecdsa_key -N '' -t dsa
fi
if [ ! -f "/etc/ssh/ssh_host_ed25519_key" ]; then
  # generate fresh ecdsa key
  ssh-keygen -f /etc/ssh/ssh_host_ed25519_key -N '' -t dsa
fi
#prepare run dir
if [ ! -d "/var/run/sshd" ]; then
  mkdir -p /var/run/sshd
fi
exec "$@"

Probando el acceso

Para comprobar que la configuración es correcta, genera una imagen a través de docker build:

docker build . -t 0gis0/docker-ssh

Si quieres, antes de desplegar el contenedor en Web App for Containers puedes probarlo en tu local:

docker run -p 2222:2222 0gis0/docker-ssh

Una vez que se esté ejecutando abre un terminal y lanza el siguiente comando:

ssh root@localhost -p 2222

En este artículo voy a publicar la misma en Docker Hub, pero podrías utilizar cualquier otro registro, como Azure Container Registry.

docker push 0gis0/docker-ssh

Una vez que lo tengas, crea un recurso del tipo Web App for Containers y asocia dicha imagen para tu contenedor.

Por último, accede al apartado SSH de tu cuenta.

y haz clic en Go y verás que tienes acceso a tu contenedor en Web App for Containers.

No obstante, te darás cuenta de que la IP contra la que estás haciendo la conexión es una privada del rango 172.16.1.X, por lo que no es accesible a priori desde fuera de esta consola. Si quisieras acceder de manera remota, necesitarás crear un túnel a través del siguiente comando:

az webapp create-remote-connection --subscription YOUR_SUBSCRIPTION_ID --resource-group docker-ssh -n docker-ssh

La forma de conectarte, una vez abierto el túnel, sería la siguiente:

ssh root@127.0.0.1 -p <port>

El código lo tienes en mi GitHub.

¡Saludos!