Conéctate a instancias de VM de forma segura

En este documento, se describen las prácticas recomendadas para conectarse de forma segura a las instancias de máquina virtual (VM) de Compute Engine, incluida el almacenamiento de claves de host mediante la habilitación de atributos de invitado y la evitando que se pueda acceder a las VM desde la Internet pública.

Antes de comenzar

Habilita atributos de invitado para almacenar claves de host

Una clave de host es un par de claves que identifica un host o máquina en particular. Cuando te conectas a un host remoto, la clave de host se usa para verificar que te estás conectando a la máquina deseada.

Si usas gcloud compute ssh con el fin de conectarte a tus VM de Linux, puedes agregar una capa de seguridad si habilitas el almacenamiento de las claves de host como atributos de invitado.

El almacenamiento de claves de host SSH como atributos de invitado mejora la seguridad de tus conexiones, ya que ayuda a protegerlas contra vulnerabilidades como los ataques de intermediarios (MITM). En el primer inicio de una instancia de VM, si los atributos de invitado están habilitados, Compute Engine almacena tus claves de host generadas como atributos de invitado. Luego, Compute Engine usa estas claves de host almacenadas para verificar todas las conexiones posteriores a la instancia de VM.

Las claves de host pueden almacenarse como atributos de invitado en las siguientes imágenes públicas del sistema operativo:

  • Debian
  • Ubuntu
  • Red Hat Enterprise Linux (RHEL)
  • CentOS
  • SUSE Linux Enterprise Server (SLES)

Para escribir las claves de host en los atributos de invitado, debes habilitar los atributos de invitado antes de iniciar la VM por primera vez. Puedes habilitar los atributos de invitado en VM seleccionadas durante la creación de VM o en todo tu proyecto.

Después de habilitar los atributos de invitado para un proyecto o VM, el agente de SO invitado publica la clave de host de forma automática como un atributo de invitado. Si usas gcloud compute ssh en lugar de un cliente SSH sin formato, la herramienta de gcloud leerá de forma automática los atributos y actualizará el archivo known_hosts la próxima vez que te conectes.

Para almacenar claves de host como atributos de invitado, realiza los siguientes pasos:

  1. Antes de iniciar la VM por primera vez, habilita los atributos de invitado en VM seleccionadas durante la creación de VM o en todo tu proyecto.

  2. Conéctate a la VM mediante gcloud compute ssh.

    1. Asegúrate de tener la última versión de la herramienta de línea de comandos de gcloud.

      gcloud components update
      
    2. Conéctate a la VM.

      gcloud compute ssh --project=PROJECT_ID \
       --zone=ZONE \
       VM_NAME
      

      Reemplaza lo siguiente:

      • PROJECT_ID: El ID del proyecto que contiene la VM
      • ZONE: El nombre de la zona en la que se encuentra la VM
      • VM_NAME: El nombre de la VM

      Si estableciste propiedades predeterminadas para la herramienta de línea de comandos gcloud, puedes omitir las marcas --project y --zone de este comando. Por ejemplo:

      gcloud compute ssh VM_NAME
      
    3. Revisa el mensaje de inicio. Por ejemplo, un sistema operativo Debian podría mostrar el siguiente mensaje:

      Writing 3 keys to YOUR_HOME_DIRECTORY/.ssh/google_compute_known_hosts
      Linux host-key-2 4.9.0-9-amd64 #1 SMP Debian 4.9.168-1+deb9u3 (2019-06-16) x86_64
      

Para confirmar que las claves de host se almacenaron como atributos de invitado para esta instancia, revisa los valores de la clave de host a fin de verificar que las claves SSH estén escritas en atributos de invitado en la VM (Opción 1) o revisa el puerto en serie y buscar la presencia de claves de host (opción 2):

Opción 1: revisa los valores de clave de host

Puedes usar la herramienta de línea de comandos de gcloud para verificar que las claves SSH se escriban en los atributos de invitado.

gcloud compute instances get-guest-attributes VM_NAME \
  --query-path="hostkeys/" \
  --zone=ZONE

Reemplaza lo siguiente:

  • VM_NAME: El nombre de la VM
  • ZONE: El nombre de la zona en la que se encuentra la VM

El resultado es similar al siguiente:

NAMESPACE  KEY                  VALUE
hostkeys   ecdsa-sha2-nistp256  AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBJAGpTm
                                V3mFxBTHK1NIu9a7kVQWaHsZVaFUsqF8cLxQRQ+N96/Djiiuz1tucHQ8vBTJI=
hostkeys   ssh-ed25519          AAAAC3NzaC1lZDI1NTE5AAAAIM/WYBn3jIEW5t3BZumx0X/Htm61J6S9FcU8L
hostkeys   ssh-rsa              AAAAB3NzaC1yc2EAAAADAQABAAABAQDU3jReR/MoSttlWYfauW6qEqS2dhe5
                                Zdd3guYk2H7ZyxblNuP56nOl/IMuniVmsFa9v8W6MExViu6G5Cy4iIesot09
                                1hsgkG0U7sbWrXM10PQ8pnpI3B5arplCiEMhRtXy64rlW3Nx156bLdcxv5l+
                                7Unu4IviKlY43uqqwSyTv+V8q4ThpQ9dNbk1Gg838+KzazljzHahtbIaE1rm
                                I0L1lUqKiKLSLKuBgrI2Y/WSuqvqGEz+bMH7Ri4ht+7sAwykph6FbOgKqoBI
                                hVWBo38/Na/gEuvtmgULUwK+xy9zWg9k8k/Qtihc6El9GD9y

Opción 2: revisa el puerto en serie

  1. Visualiza la salida del puerto en serie.
  2. Selecciona el puerto en serie 1.
  3. Busca el siguiente mensaje:

    INFO Wrote ssh-rsa host key to guest attributes

    Si tu imagen usa un sistema operativo compatible, pero la configuración de los atributos de invitado no estaba habilitada antes del primer inicio de la VM, es posible que veas el siguiente mensaje:

    Unable to write ssh-rsa host key to guest attributes

    Esto significa que las claves de host no se almacenaron como atributos de invitado para esta VM. Si deseas almacenar claves de host para VM adicionales que planeas crear, habilita los atributos de invitado antes del primer inicio de la VM.

Impide que se pueda acceder a las VM desde la Internet pública

Cuando se desarrollan proyectos en Compute Engine, existe una variedad de situaciones en las que querrás evitar que se pueda acceder a las VM desde la Internet pública:

  • Los servicios web, aún en desarrollo, no están listos para ser expuestos a usuarios externos porque sus características no están completas o todavía no se configuraron con HTTPS.
  • Es posible que la VM proporcione servicios diseñados para que solo los consuman otras VM del proyecto.
  • Solo se debe acceder a las VM a través de opciones de interconexión dedicadas desde las oficinas de la empresa o los centros de datos.

Incluso cuando un servicio está orientado a Internet de forma intencional, es importante que la comunicación con el servicio esté restringida a los grupos de usuarios de destino y que se produzca a través de canales seguros, como SSH o HTTPS, para proteger la información sensible.

En este artículo, se muestran varios métodos para proteger las comunicaciones con VM con direcciones IP externas y VM sin direcciones IP externas.

Protege servicios en máquinas con direcciones IP externas

Cuando las VM tienen una dirección IP pública, es importante que solo se pueda acceder a los servicios y el tráfico que pretendes exponer, y que para aquellos que están expuestos, toda la información sensible esté protegida durante el tránsito. Existen varios métodos para proteger los servicios en VM con direcciones IP externas que se explican en este documento, incluidos firewalls, HTTPS y SSL, redirección de puertos mediante SSH y proxy de SOCKS mediante SSH.

Firewalls

La primera línea de defensa es restringir quién puede acceder a la VM con firewalls. Mediante la creación de reglas de firewall, puedes restringir todo el tráfico a una red o puedes orientar máquinas en un conjunto dado de puertos a direcciones IP de origen específicas.

Los firewalls no son una solución independiente. La restricción del tráfico a direcciones IP de origen específicas no protege la información sensible como las credenciales de acceso, los comandos que crean o destruyen recursos y archivos o los registros. Cuando ejecutas un servicio web en una máquina de acceso público, como una VM de Compute Engine con una IP externa, debes encriptar toda la comunicación entre el host y la VM implementada para garantizar una seguridad adecuada.

Además, los firewalls no son siempre la mejor solución. Por ejemplo, los firewalls no son la opción ideal para los entornos de desarrollo que no tienen direcciones IP estáticas, como las laptops que cambian de lugar constantemente.

HTTPS y SSL

En los sistemas web de producción, debes configurar HTTPS/SSL. Puedes hacerlo mediante la configuración de una instancia para que finalice con HTTPS o del balanceo de cargas de HTTPS. HTTPS/SSL posee cierta complejidad inicial, lo que requiere que realices las siguientes tareas:

Redirección de puertos mediante SSH

Puedes usar la herramienta de línea de comandos de gcloud para iniciar un servidor en un puerto local determinado que redireccione todo el tráfico a un host remoto a través de una conexión SSH.

Primero, toma nota de la VM y el puerto que proporcionan el servicio con el que deseas establecer una conexión segura. A continuación, ejecuta el siguiente comando:

gcloud compute ssh VM_NAME \
    --project PROJECT_ID \
    --zone ZONE \
    -- -NL LOCAL_PORT:localhost:REMOTE_PORT

Reemplaza lo siguiente:

  • VM_NAME es el nombre de la VM a la que deseas conectarte.
  • PROJECT_ID es el ID del proyecto de Google Cloud.
  • ZONE es la zona en la que se ejecuta la VM, por ejemplo, us-central1-a.
  • LOCAL_PORT es el puerto local que escuchas, por ejemplo, 2222.
  • REMOTE_PORT es el puerto remoto al que te conectas, por ejemplo, 8888.

Por ejemplo, si especificas un puerto local de “2222” y un puerto remoto de “8888”, y abres http://localhost:2222/ en el navegador, la conexión HTTP usa el túnel SSH que creaste para el host remoto a fin de conectarte a la VM especificada mediante SSH. La conexión HTTP usará el túnel SSH para conectarse al puerto 8888 en la misma máquina, pero a través de una conexión SSH encriptada y segura.

El comando de gcloud crea y mantiene una conexión SSH mientras la sesión SSH está activa. En cuanto salgas de la sesión SSH, la redirección de puertos mediante http://VM_NAME:LOCAL_PORT dejará de funcionar.

Para crear más de una regla de redirección de puertos, puedes especificar varias reglas en una sola línea de comandos mediante la repetición de las siguientes marcas:

gcloud compute ssh VM_NAME \
    --project PROJECT_ID \
    --zone ZONE \
    -- -NL LOCAL_PORT:localhost:REMOTE_PORT \
    -- -NL LOCAL_PORT:localhost:REMOTE_PORT

Como alternativa, puedes ejecutar un comando de gcloud nuevo cada vez para crear un túnel independiente. Ten en cuenta que no puedes agregar o quitar la redirección de puertos de una conexión existente sin salir y restablecer la conexión desde cero.

Proxy de SOCKS mediante SSH

Si deseas conectarte a una serie de hosts diferentes en tu implementación en la nube, la forma más sencilla de hacerlo es cambiar tu navegador para realizar las búsquedas directamente desde tu red. Mediante este método, puedes usar el nombre corto de los hosts en lugar de buscar la dirección IP de cada uno, abrir puertos en cada servicio o crear un túnel SSH para cada par host-puerto.

El enfoque que debes usar es el siguiente:

  1. Configura un único túnel SSH para uno de los hosts en la red y crea un proxy de SOCKS en ese host.
  2. Cambia la configuración del navegador para realizar todas las búsquedas a través de ese host del proxy de SOCKS.

Ten en cuenta que, como usas túneles para todo el tráfico mediante ese host, debes evitar usar ese navegador o ese perfil específico cuando navegues por la Web, ya que debes dedicar ese ancho de banda al servicio en la nube. En general, es posible que quieras usar un perfil de navegador independiente cuando sea necesario.

Inicia el proxy de SOCKS

Para iniciar tu proxy de SOCKS, ejecuta el siguiente comando:

gcloud compute ssh VM_NAME \
    --project PROJECT_ID \
    --zone ZONE
    --ssh-flag="-D" \
    --ssh-flag="LOCAL_PORT" \
    --ssh-flag="-N"

Reemplaza lo siguiente:

  • VM_NAME: El nombre de la VM a la que deseas conectarte.
  • PROJECT_ID es el ID de tu proyecto de Google Cloud.
  • ZONE es la zona en la que se ejecuta la VM, por ejemplo, us-central1-a.
  • LOCAL_PORT es el puerto local que escuchas, por ejemplo, 1080.

Ten en cuenta que, en este caso, no necesitas especificar un puerto remoto. Debido a que un proxy de SOCKS no se vincula a ningún puerto remoto específico, cualquier conexión que hagas mediante el proxy de SOCKS se resolverá según el host al que te conectes.

Mediante un proxy de SOCKS, puedes conectarte a cualquier VM que comparta una red de Compute Engine con tu VM de proxy mediante el nombre corto de la VM. Además, te puedes conectar a cualquier puerto en una VM determinada.

Este enfoque es mucho más flexible que el método simple de redirección de puertos, pero también deberás cambiar la configuración en tu navegador web para usar el proxy.

Luego, configura Chrome o Firefox para usar el proxy.

Chrome

Chrome usa la configuración del proxy en todo el sistema de forma predeterminada, por lo que debes especificar un proxy diferente mediante las marcas de la línea de comandos. Cuando inicias Chrome de forma predeterminada, se crea una VM de un perfil en ejecución, por lo que, para poder ejecutar varias copias de Chrome de forma simultánea, una que usa el proxy y otras que no, necesitas una nueva perfil

Inicia Chrome con un perfil nuevo. Si no existe, se creará de forma automática.

Linux:

/usr/bin/google-chrome \
    --user-data-dir="$HOME/chrome-proxy-profile" \
    --proxy-server="socks5://localhost:1080"

macOS:

"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
    --user-data-dir="$HOME/chrome-proxy-profile" \
    --proxy-server="socks5://localhost:1080"

Windows:

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" ^
    --user-data-dir="%USERPROFILE%\chrome-proxy-profile" ^
    --proxy-server="socks5://localhost:1080"

Configura el puerto localhost con el mismo valor que usaste en el comando de gcloud antes (1080 en nuestro ejemplo).

Firefox

Antes de cambiar esta configuración, puedes crear un perfil de Firefox nuevo. De lo contrario, usar ese host como un proxy afectará a todas las VM de Firefox, lo que no es muy conveniente.

Después de configurar Firefox para que se ejecute con un perfil independiente, puedes configurar el proxy de SOCKS:

  1. Abre Preferencias.
  2. Haz clic en Avanzado > Redes > Configuración para abrir el cuadro de diálogo Configuración de conexión.
  3. Selecciona la opción Manual proxy configuration.
    1. En la sección SOCKS Host, ingresa localhost como el host y el puerto que seleccionaste cuando ejecutaste el comando de gcloud con anterioridad.
    2. Selecciona SOCKS v5.
    3. Marca la casilla DNS remoto.
    4. Deja todas las demás entradas en blanco.
  4. Haz clic en Aceptar y cierra el cuadro de diálogo Preferencias.

Conéctate a VM sin direcciones IP externas

Cuando las VM no tienen direcciones IP externas (incluidas las VM que son backends para balanceadores de cargas de proxy HTTPS y SSL), solo se puede acceder a ellas mediante otras VM de la red, función de redireccionamiento de TCP de Identity-Aware Proxy o mediante la puerta de enlace de VPN administrada. Puedes aprovisionar VM en tu red, de modo que actúen como retransmisiones de confianza para las conexiones entrantes, también conocidas como hosts de bastión. Además, puedes configurar Cloud NAT para la salida de red o configurar la consola en serie interactiva a fin de mantener o solucionar problemas de las VM sin direcciones IP externas.

Hosts de bastión

Los hosts de bastión proporcionan un punto de entrada externo a una red que contiene instancias de red privadas, como se ilustra en el siguiente diagrama.

Arquitectura de hosts de bastión que actúan como el punto de entrada externo de una red de instancias privadas.

Este host puede proporcionar un único punto de fortificación o auditoría y puede iniciarse y detenerse para habilitar o inhabilitar la conexión SSH entrante. Mediante un host de bastión, puedes conectarte a una VM que no tenga una dirección IP externa. Con este enfoque, puedes conectarte a un entorno de desarrollo o administrar la instancia de base de datos de tu aplicación externa, por ejemplo, sin configurar reglas de firewall adicionales.

Aunque el endurecimiento completo de un host de bastión está por fuera del alcance de este artículo, te presentamos algunos pasos iniciales que se pueden tomar:

  • Limitar el rango CIDR de las IP de origen que se pueden comunicar con el bastión
  • Configurar las reglas de firewall para permitir el tráfico SSH a VM privadas solo desde el Host de bastión.

De forma predeterminada, el SSH en VM está configurado de modo que use claves privadas para la autenticación. Cuando usas un host de bastión, primero debes acceder a él y, luego, a tu VM privada de destino. Debido a este acceso en dos pasos, que es la razón por la que los hosts de bastión se denominan “servidores de salto”, debes usar la redirección de ssh en lugar de almacenar la clave privada de la máquina de destino en el host de bastión como forma de llegar a la máquina de destino. Debes hacer esto incluso si usas el mismo par de claves para las VM de bastión y de destino porque el bastión tiene acceso directo solo a la mitad pública del par de claves.

Si deseas obtener información sobre cómo usar una instancia de host de bastión para conectarte a otras VM en tu red de Google Cloud, consulta Conéctate a través de un host de bastión.

Para aprender a usar ssh reenvío y otros métodos para conectarte a VM que no tienen una dirección IP externa, consulta Conéctate a VM que no tienen direcciones IP externas.

IAP para la redirección de TCP

Mediante el uso de SSH con la función de redireccionamiento de TCP de IAP, se establece una conexión SSH dentro de HTTPS. La función de redireccionamiento de TCP de IAP la envía a la VM remota.

A fin de obtener información sobre cómo conectarse a una VM remota con IAP, consulta Usa IAP para la redirección de TCP.

VPN

Cloud VPN te permite conectar la red existente a la red de Google Cloud mediante una conexión IPsec a un dispositivo de puerta de enlace de VPN. Esto permite el enrutamiento directo del tráfico desde tus instalaciones a las interfaces de IP privadas de las VM de Compute Engine. El tráfico se encripta a medida que pasa por los vínculos públicos hasta Google.

Para obtener detalles sobre la configuración y el uso de VPN con Compute Engine, consulta la documentación de Cloud VPN.

Si quieres aprender a conectarte a las VM en tu red de Google Cloud a través de una VPN existente en lugar de mediante direcciones IP externas de VM, lee Conéctate a VM que no tienen direcciones IP externas.

Salida de tráfico con Cloud NAT

Cuando una VM no tiene una dirección IP externa asignada, no puede hacer conexiones directas a servicios externos, incluidos otros servicios de Google Cloud. Para permitir que estas VM alcancen servicios en la Internet pública, puedes configurar Cloud NAT, que puede enrutar el tráfico en nombre de cualquier VM en la red. Una única VM no debe considerarse con alta disponibilidad y no puede admitir una capacidad de procesamiento de tráfico elevada para varias VM.

Acceso interactivo a la consola en serie

Cuando una VM no tiene una dirección IP externa, puede que aún debas interactuar con la VM para solucionar problemas o con fines de mantenimiento. La configuración de un host de bastión, como se explicó con anterioridad, es una opción, pero es posible que requiera más configuración de la que merece la pena en tu caso. Si deseas solucionar los problemas de una VM sin una dirección IP externa, considera habilitar el acceso interactivo en la consola en serie, lo que te permite interactuar con la consola en serie de una VM mediante SSH y ejecutar comandos en la consola en serie.

Para obtener más información, consulta Interactúa con la consola en serie.

Balanceadores de cargas de proxy HTTPS y SSL

Las VM que son backends de balanceadores de cargas de proxy SSL y HTTPS no necesitan tener direcciones IP externas a las que se pueda acceder a través del balanceador de cargas. Para acceder a estos recursos directamente, se requiere el uso de los métodos mencionados en la sección Conéctate a VM sin direcciones IP externas.

Si quieres obtener más información, consulta la documentación sobre balanceo de cargas para esos balanceadores de cargas.