Saltar al contenido

Inyectar SSH del host keys en Docker Machine con Docker Compose

Este equipo de expertos luego de ciertos días de trabajo y de juntar de información, obtuvimos la respuesta, queremos que te resulte útil en tu proyecto.

Solución:

Puede agregar esto a su docker-compose.yml (suponiendo que su usuario dentro del contenedor sea root):

volumes:
    - ~/.ssh:/root/.ssh

También puede buscar una solución más avanzada con el agente ssh (no lo probé yo mismo)

Docker tiene una característica llamada secretos, que puede ser útil aquí. Para usarlo, se podría agregar el siguiente código a docker-compose.yml:

---
version: '3.1' # Note the minimum file version for this feature to work
services:
  stack:
    ...
    secrets:
      - host_ssh_key

secrets:
  host_ssh_key:
    file: ~/.ssh/id_rsa

Luego se puede acceder al nuevo archivo secreto en Dockerfile Me gusta esto:

RUN mkdir ~/.ssh && ln -s /run/secrets/host_ssh_key ~/.ssh/id_rsa

Los archivos secretos no se copiarán en el contenedor:

Cuando otorga acceso a un secreto a un servicio recién creado o en ejecución, el secreto descifrado se monta en el contenedor en un sistema de archivos en memoria.

Para obtener más detalles, consulte:

  • https://docs.docker.com/engine/swarm/secretos/
  • https://docs.docker.com/compose/compose-file/#secrets

Si está usando OS X y está encriptado keys esto va a ser PITA. Estos son los pasos que seguí para resolver esto.

Enfoque directo

Uno podría pensar que no hay problema. Simplemente monte su carpeta ssh:

...
volumes:
  - ~/.ssh:/root/.ssh:ro
...

Esto debería estar funcionando, ¿verdad?

Problema de usuario

Lo siguiente que notaremos es que estamos usando la identificación de usuario incorrecta. Bien, escribiremos un script para copiar y cambiar el propietario de ssh keys. También configuraremos el usuario ssh en la configuración para que el servidor ssh sepa quién se está conectando.

...
volumes:
  - ~/.ssh:/root/.ssh-keys:ro
command: sh -c ‘./.ssh-keys.sh && ...’
environment:
  SSH_USER: $USER
...

# ssh-keys.sh
mkdir -p ~/.ssh
cp -r /root/.ssh-keys/* ~/.ssh/
chown -R $(id -u):$(id -g) ~/.ssh

cat <> ~/.ssh/config
  User $SSH_USER
EOF

SSH key problema con la frase de contraseña

En nuestra empresa protegemos SSH keys utilizando una frase de contraseña. Eso no funcionaría en la ventana acoplable, ya que no es práctico ingresar una frase de contraseña cada vez que iniciamos un contenedor. Podríamos eliminar una frase de contraseña (consulte el ejemplo a continuación), pero existe un problema de seguridad.

openssl rsa -in id_rsa -out id_rsa2
# enter passphrase
# replace passphrase-encrypted key with plaintext key:
mv id_rsa2 id_rsa

solución de agente SSH

Es posible que haya notado que localmente no necesita ingresar una frase de contraseña cada vez que necesita acceso ssh. ¿Porqué es eso? Para eso está el agente SSH. El agente SSH es básicamente un servidor que escucha un archivo especial, socket Unix, llamado “ssh auth sock”. Puede ver su ubicación en su sistema:

echo $SSH_AUTH_SOCK
# /run/user/1000/keyring-AvTfL3/ssh

El cliente SSH se comunica con el agente SSH a través de este archivo para que ingrese la frase de contraseña solo una vez. Una vez que no esté encriptado, el agente SSH lo almacenará en la memoria y lo enviará al cliente SSH a pedido. ¿Podemos usar eso en Docker? Claro, simplemente monte ese archivo especial y especifique una variable de entorno correspondiente:

environment:
  SSH_AUTH_SOCK: $SSH_AUTH_SOCK
  ...
volumes:
  - $SSH_AUTH_SOCK:$SSH_AUTH_SOCK

Ni siquiera necesitamos copiar keys en este caso. para confirmar eso keys están disponibles, podemos usar la utilidad ssh-add:

if [ -z "$SSH_AUTH_SOCK" ]; then
  echo "No ssh agent detected"
else
  echo $SSH_AUTH_SOCK
  ssh-add -l
fi

El problema del soporte de montaje de socket Unix en Docker para Mac

Desafortunadamente para los usuarios de OS X, Docker para Mac tiene varias deficiencias, una de las cuales es su incapacidad para compartir sockets Unix entre Mac y Linux. Hay un problema abierto en D4M Github. A partir de febrero de 2019 todavía está abierto.

Entonces, ¿es eso un callejón sin salida? No, hay una solución alternativa.

Solución de reenvío de agente SSH

Afortunadamente, este problema no es nuevo. Mucho antes de Docker, había una forma de usar ssh local keys dentro de una sesión ssh remota. Esto se llama reenvío de agente ssh. La idea es simple: te conectas a un servidor remoto a través de ssh y puedes usar todos los mismos servidores remotos allí, compartiendo así tu keys.

Con Docker para Mac podemos usar un truco inteligente: compartir el agente ssh en la máquina virtual docker usando una conexión TCP ssh y montar ese archivo desde la máquina virtual a otro contenedor donde necesitamos esa conexión SSH. Aquí hay una imagen para demostrar la solución:

Reenvío SSH

Primero, creamos una sesión ssh para el servidor ssh dentro de un contenedor dentro de una máquina virtual Linux a través de un puerto TCP. Usamos un calcetín de autenticación ssh real aquí.

A continuación, el servidor ssh reenvía nuestro ssh keys al agente ssh en ese contenedor. El agente SSH tiene un socket de Unix que utiliza una ubicación montada en una máquina virtual de Linux. Es decir, el socket Unix funciona en Linux. El archivo de socket Unix que no funciona en Mac no tiene ningún efecto.

Después de eso, creamos nuestro contenedor útil con un cliente SSH. Compartimos el archivo de socket de Unix que utiliza nuestra sesión SSH local.

Hay un montón de scripts que simplifican ese proceso: https://github.com/avsm/docker-ssh-agent-forward

Conclusión

Lograr que SSH funcione en Docker podría haber sido más fácil. Pero puede hacerse. Y es probable que se mejore en el futuro. Al menos los desarrolladores de Docker son conscientes de este problema. E incluso lo resolvió para Dockerfiles con secretos de tiempo de compilación. Y hay una sugerencia sobre cómo admitir sockets de dominio Unix.

Si te animas, tienes la libertad de dejar un post acerca de qué te ha impresionado de este ensayo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *