SSH es uno de los comandos más utilizados en la caja de herramientas de un administrador de sistemas, pero no se ve comúnmente junto con Docker. Aquí le mostramos cómo puede conectarse mediante SSH a un contenedor en ejecución y por qué debería pensarlo dos veces antes de hacerlo.
¿Debería usar SSH con contenedores Docker?
SSH-ing en un contenedor Docker es generalmente una mala práctica que debe evitar. Casi siempre es mejor usar docker exec
comando para obtener un caparazón dentro de un contenedor.
Los recién llegados a Docker pueden verse tentados a usar SSH para actualizar archivos dentro de un contenedor. Sin embargo, los contenedores están destinados a ser desechables, por lo que deben tratarse como inmutables después de la creación, a excepción de los datos persistentes almacenados dentro de los volúmenes. Cree una nueva imagen y reinicie su contenedor cuando edite el código fuente.
Además del proceso de configuración de varios pasos, la instalación de SSH en una imagen de Docker agrega varios paquetes de dependencia y expone otro posible vector de ataque. En un sistema con varios contenedores activos, ejecutará varios procesos SSH independientes y deberá recordar el puerto correcto para cada contenedor.
En lugar de agregar SSH a contenedores individuales, instálelo una vez en el host físico que ejecuta Docker. Use SSH para conectarse a su host, luego ejecute docker exec -it my-container bash
para acceder a contenedores individuales.
Mientras que docker exec
es el enfoque preferido, todavía hay escenarios en los que SSH podría ser útil. Podría presentarlo como una medida provisional para integrarse con los sistemas de implementación heredados. También puede ser utilizado por algunos IDE y herramientas de compilación para proporcionar capacidades de recarga en vivo durante el desarrollo.
Instalación del servidor SSH en un contenedor Docker
Las imágenes base de Docker más populares se mantienen simplificadas intencionalmente. Deberá agregar el servidor OpenSSH usted mismo, incluso en imágenes derivadas de distribuciones de sistemas operativos populares.
Aquí hay un ejemplo Dockerfile
para una imagen basada en Debian:
RUN apt-get update && apt-get install -y openssh-server RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config ENTRYPOINT service ssh start && bash
La configuración de SSH se modifica para que pueda iniciar sesión como root
, el usuario predeterminado en un contenedor de Docker. Para mayor seguridad, configure una cuenta de usuario dedicada en su lugar:
RUN useradd -m -s /bin/bash sshuser
Esto crea un nuevo usuario llamado sshuser
con un directorio de inicio (-m
). El -s
switch establece el shell de inicio de sesión predeterminado del usuario en Bash.
El uso de ENTRYPOINT
asegura que el servicio SSH siempre se inicia cuando lo hace el contenedor. Luego, la ejecución se transfiere a Bash como el proceso de primer plano del contenedor. Puede reemplazar esto con el binario de su aplicación.
Configuración de autenticación
A continuación, debe configurar un sistema de autenticación. Podría asignar una contraseña a su sshuser
cuenta e inicie sesión con eso:
RUN echo "sshuser:Changeme" | changepasswd
Una forma más segura es configurar la autenticación de clave SSH. Deberá crear un par de claves en su máquina cliente y luego copiar la parte pública en el contenedor. De esta forma, el demonio SSH puede verificar la identidad de su máquina cuando se conecte.
Modifique su Dockerfile
para configurar .ssh
carpeta de configuración para su usuario. Copie en una clave pública desde su directorio de trabajo, ya sea con un docker cp
comando o un COPY
instrucción en el Dockerfile
. En el último caso, la clave se integraría en la imagen, visible para cualquier persona con acceso.
COPY id_rsa.pub /home/sshuser/.ssh/authorized_keys RUN chown -R sshuser:sshuser /home/sshuser/.ssh RUN chmod 600 /home/sshuser/.ssh/authorized_keys
Esta secuencia de comandos crea authorized_keys
de SSH archivo con el id_rsa.pub
clave pública en su directorio de trabajo. Los permisos del sistema de archivos se ajustan para que coincidan con los requisitos de SSH.
Conectando al Contenedor
Ahora está listo para conectarse a su contenedor. Ejecute el contenedor con el puerto 22 vinculado al host:
docker run -p 22:22 my-image:latest
Ejecutando ssh [email protected]
le dará un caparazón dentro de su contenedor.
Puede omitir la vinculación del puerto si se conectará desde la máquina que aloja el contenedor Docker. Usar docker inspect
para obtener la dirección IP de su contenedor, luego pásela al comando de conexión SSH.
docker inspect <id-or-name> | grep 'IPAddress' | head -n 1
Use el cliente SSH en su máquina para conectarse al contenedor:
ssh [email protected] # OR ssh [email protected]
Necesitará usar un puerto alternativo si está ejecutando un servidor SSH separado en el host o si tiene varios contenedores que necesitan el puerto 22. A continuación, le mostramos cómo iniciar una conexión cuando SSH está vinculado al puerto 2220:
docker run -p 22:2220 my-image:latest ssh [email protected] -p 2220
Configuración de accesos directos de contenedor con configuración SSH
Puede manipular su archivo de configuración SSH para simplificar las conexiones a contenedores individuales. Editar ~/.ssh/config
para definir hosts abreviados con puertos preconfigurados:
Host my-container HostName 172.17.0.1 Port 2220 User sshuser
Ahora puede ejecutar ssh my-container
para caer directamente en su contenedor. Esto hace que sea más fácil hacer malabarismos con varias conexiones sin recordar los puertos y las direcciones IP de los contenedores.
Use Dockssh para simplificar la gestión de contenedores
El proyecto Dockssh lleva esto un paso más allá al proporcionar otro demonio que le permite ejecutar ssh [email protected]
, sin ninguna configuración SSH manual. No necesita instalar un servidor SSH en sus contenedores; Dockssh procesa automáticamente las conexiones SSH y ejecuta el docker exec
correcto comando en su lugar.
Primero debe instalar Redis para almacenar los datos de configuración de Dockssh:
sudo apt install redis
A continuación, defina los contenedores que desea exponer agregando un registro de Redis con el nombre del contenedor y una contraseña para las conexiones SSH:
redis-cli set dockssh:my-container:pass "container-password-here"
Luego descarga Dockssh:
sudo curl https://github.com/alash3al/dockssh/releases/download/v1.1.0/dockssh_linux_amd64 -O /usr/local/bin/dockssh sudo chmod +x /usr/local/bin/dockssh sudo ufw allow 22022 # Start DockSSH server dockssh
Ahora puede conectarse a su contenedor:
ssh [email protected] -p 22022
Dockssh escucha en el puerto 22022 de forma predeterminada. El cortafuegos se abre para permitir conexiones entrantes utilizando el puerto.
Se le pedirá la contraseña del contenedor cuando se conecte. Esto se estableció como container-password-here
en nuestro registro de Redis anterior.
El uso de Dockssh facilita el SSH en una gran cantidad de contenedores Docker. Este enfoque es ideal cuando se conecta regularmente a sus contenedores desde un host remoto, ya que simplifica el "SSH de dos pasos y luego docker exec
” secuencia en un solo comando memorable.
Registre Dockssh como un servicio del sistema para uso a largo plazo:
sudo nano /etc/systemd/system/dockssh.service
[Unit] Description=Dockssh service After=network.target [Service] type=simple Restart=always RestartSec=1 User=root ExecStart=/usr/local/bin/dockssh [Install] WantedBy=multi-user.target
Habilite el servicio usando systemctl
:
sudo systemctl enable dockssh.service sudo systemctl start dockssh
Dockssh ahora se iniciará automáticamente cuando arranque su sistema.
Resumen
La combinación de SSH con contenedores Docker se considera en términos generales como un antipatrón, pero todavía tiene sus usos en entornos de desarrollo, prueba y heredados. Cuando no haya otra alternativa, puede agregar el servidor SSH a su contenedor, copiar una clave pública y conectarse a través de la IP del contenedor o un enlace de puerto de host.
Los administradores de sistemas que deseen administrar de forma remota una gran cantidad de contenedores Docker pueden probar Dockssh. Te permite ejecutar ssh
familiar comandos a través de un mapeo tras bambalinas perfecto a docker exec
, brindándole lo mejor de ambos mundos usando imágenes sin modificar.