Conectarse de forma segura a instancias de máquina virtual


En este documento se describen las prácticas recomendadas para conectarse de forma segura a instancias de máquina virtual (VM) de Compute Engine, como almacenar claves de host habilitando atributos de invitado y evitar que se pueda acceder a las VMs desde Internet público.

Antes de empezar

  • Si aún no lo has hecho, configura la autenticación. La autenticación verifica tu identidad para acceder a Google Cloud servicios y APIs. Para ejecutar código o ejemplos desde un entorno de desarrollo local, puedes autenticarte en Compute Engine seleccionando una de las siguientes opciones:

    Select the tab for how you plan to use the samples on this page:

    Console

    When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.

    gcloud

    1. Instala Google Cloud CLI. Después de la instalación, inicializa la CLI de Google Cloud ejecutando el siguiente comando:

      gcloud init

      Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.

    2. Set a default region and zone.

Almacenar claves de host habilitando atributos de invitado

Una clave de host es un par de claves que identifica un host o una máquina concretos. Cuando te conectas a un host remoto, la clave de host se usa para verificar que te estás conectando al ordenador correcto.

Si usas gcloud compute ssh para conectarte a tus VMs Linux, puedes añadir una capa de seguridad almacenando tus claves de host como atributos de invitado.

Almacenar las claves de host SSH como atributos de invitado mejora la seguridad de tus conexiones, ya que ayuda a protegerte frente a vulnerabilidades como los ataques de intermediario (MITM). En el arranque inicial de una VM, si los atributos de invitado están habilitados, Compute Engine almacena las claves de host generadas como atributos de invitado. Después, Compute Engine usa estas claves de host almacenadas para verificar todas las conexiones posteriores a la VM.

Las claves de host se pueden almacenar como atributos de invitado en las siguientes imágenes públicas de sistemas operativos:

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

Para escribir claves de host en atributos de invitado, debes habilitar los atributos de invitado antes de arrancar la VM por primera vez. Puedes habilitar los atributos de invitado en determinadas VMs durante la creación de la VM o en todo el proyecto.

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

Para almacenar las claves de host como atributos de invitado, sigue estos pasos:

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

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

    1. Asegúrate de que tienes la versión más reciente de la CLI de Google Cloud:

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

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

      Haz los cambios siguientes:

      • PROJECT_ID: el ID del proyecto que contiene la VM
      • ZONE: el nombre de la zona en la que se encuentra la máquina virtual
      • VM_NAME: el nombre de la VM

      Si has definido propiedades predeterminadas para Google Cloud CLI, 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 almacenan como atributos de invitado de esta VM, revisa los valores de las claves de host para verificar que las claves SSH se escriben en los atributos de invitado de la VM (opción 1) o revisa el puerto serie para comprobar si hay claves de host (opción 2):

Opción 1: Revisar los valores de la clave de host

Puedes usar la CLI de Google Cloud para verificar que las claves SSH se escriben en los atributos de invitado:

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

Haz los cambios siguientes:

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

El resultado debería ser 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: Revisar el puerto serie

  1. Consulta la salida del puerto serie.
  2. Selecciona Puerto 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 el ajuste de atributos de invitado no se habilitó antes del primer arranque 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 almacenan como atributos de invitado en esta máquina virtual. Si quieres almacenar claves de host para otras máquinas virtuales que tengas previsto crear, habilita los atributos de invitado antes del primer arranque de la máquina virtual.

Impedir que se pueda acceder a las VMs desde Internet pública

Cuando desarrollas proyectos en Compute Engine, hay varios casos en los que quieres evitar que se pueda acceder a las VMs desde Internet público:

  • Los servicios web aún están en fase de desarrollo y no están listos para exponerse a usuarios externos porque no tienen todas las funciones o aún no se han configurado con HTTPS.
  • Es posible que la máquina virtual proporcione servicios diseñados para que solo los consuman otras máquinas virtuales del proyecto.
  • Solo se debe acceder a las máquinas virtuales a través de opciones de interconexión dedicadas desde las oficinas o los centros de datos de la empresa.

Aunque un servicio esté orientado a Internet de forma intencionada, es importante que la comunicación con el servicio se limite a los grupos de usuarios objetivo 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 VMs con direcciones IP externas y VMs sin direcciones IP externas. Tanto si proteges las comunicaciones con estos métodos como si no, Google Cloud siempre permite la comunicación entre una instancia de VM y su servidor de metadatos correspondiente. Para obtener más información, consulta Tráfico siempre permitido.

Proteger servicios en máquinas con direcciones IP externas

Cuando las máquinas virtuales tienen una dirección IP pública, es importante que solo se pueda acceder a los servicios y al tráfico que quieras exponer, y que, en el caso de los que estén expuestos, la información sensible se proteja durante la transmisión. En este documento se explican varios métodos para proteger los servicios de las VMs con direcciones IP externas, como los firewalls, HTTPS y SSL, el reenvío de puertos a través de SSH y el proxy SOCKS a través de SSH.

Cortafuegos

Tu primera línea de defensa es restringir quién puede acceder a la VM mediante cortafuegos. Al crear reglas de cortafuegos, puedes restringir todo el tráfico a una red o a máquinas de destino en un conjunto determinado de puertos a direcciones IP de origen específicas.

Los cortafuegos no son una solución independiente. Restringir el tráfico a IPs de origen específicas no protege la información sensible, como las credenciales de inicio de sesión, los comandos que crean o destruyen recursos o archivos, o los registros. Cuando ejecutes un servicio web en una máquina accesible públicamente, como una máquina virtual de Compute Engine con una IP externa, debes cifrar todas las comunicaciones entre tu host y la máquina virtual implementada para garantizar la seguridad.

Además, los cortafuegos no siempre son la solución adecuada. Por ejemplo, los firewalls no son ideales para entornos de desarrollo que no tienen direcciones IP estáticas, como los portátiles itinerantes.

HTTPS y SSL

En los sistemas web de producción, debes configurar HTTPS/SSL. HTTPS/SSL se puede configurar de dos formas: configurando una VM para que finalice HTTPS o configurando el balanceo de carga de HTTPS. HTTPS/SSL implica cierta complejidad inicial, ya que debes realizar las siguientes tareas:

  • Registra un nombre de dominio.
  • Obtén un certificado SSL de una autoridad de certificación.
  • Registra el certificado en tu balanceador de carga HTTPS y en sus máquinas virtuales conectadas, o configura un servidor web o un proxy con terminación SSL en una o varias máquinas virtuales de Compute Engine.

Redirección de puertos a través de SSH

Puedes usar la CLI de Google Cloud para iniciar un servidor en un puerto local determinado que reenvíe todo el tráfico a un host remoto a través de una conexión SSH.

Primero, anota la VM y el puerto que proporcionan el servicio al que quieres 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

Haz los cambios siguientes:

  • VM_NAME es el nombre de la VM a la que quieres conectarte.
  • PROJECT_ID es el Google Cloud ID de tu proyecto.
  • ZONE: la zona en la que se ejecuta tu VM. Por ejemplo, us-central1-a.
  • LOCAL_PORT: el puerto local en el que estás escuchando. Por ejemplo, 2222.
  • REMOTE_PORT: el puerto remoto al que te vas a conectar. Por ejemplo, 8888.

Por ejemplo, si especificas el puerto local "2222" y el puerto remoto "8888" y abres http://localhost:2222/ en tu navegador, la conexión HTTP usará el túnel SSH que has creado en tu host remoto para conectarse a la VM especificada mediante SSH. La conexión HTTP usará el túnel SSH para conectarse al puerto 8888 de la misma máquina, pero a través de una conexión SSH cifrada y segura.

El comando gcloud crea y mantiene una conexión SSH mientras la sesión SSH está activa. En cuanto cierres 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 reenvío de puertos, puede especificar varias reglas en una sola línea de comandos repitiendo las marcas:

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

También puedes ejecutar un nuevo comando gcloud cada vez para crear un túnel independiente. Ten en cuenta que no puedes añadir ni quitar el reenvío de puertos de una conexión existente sin salir y volver a establecer la conexión desde cero.

Proxy SOCKS a través de SSH

Si quieres conectarte a varios hosts diferentes en tu implementación en la nube, la forma más sencilla de hacerlo es cambiar tu navegador para que haga las búsquedas directamente desde tu red. Con este método, puedes usar el nombre abreviado de los hosts en lugar de buscar la dirección IP de cada host, abrir puertos para cada servicio o crear un túnel SSH para cada par de host y puerto.

El enfoque que debes seguir es el siguiente:

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

Ten en cuenta que, como vas a tunelizar todo el tráfico mediante ese host, no debes usar ese navegador ni ese perfil específico para navegar por la Web, ya que necesitas dedicar ese ancho de banda a tu servicio en la nube. Por lo general, te recomendamos que uses un perfil de navegador independiente y que cambies a él cuando sea necesario.

Iniciar el proxy SOCKS

Para iniciar tu proxy 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"

Haz los cambios siguientes:

  • VM_NAME: nombre de la VM a la que quieras conectarte.
  • PROJECT_ID: tu Google Cloud ID de proyecto.
  • ZONE: la zona en la que se ejecuta tu VM. Por ejemplo, us-central1-a.
  • LOCAL_PORT: el puerto local en el que estás escuchando. Por ejemplo, 1080.

Ten en cuenta que, en este caso, no es necesario que especifiques un puerto remoto. Como un proxy SOCKS no se vincula a ningún puerto remoto específico, cualquier conexión que hagas mediante el proxy SOCKS se resolverá en relación con el host al que te conectes.

Si usas un proxy SOCKS, puedes conectarte a cualquier VM que comparta una red de Compute Engine con tu VM proxy mediante el nombre abreviado de la VM. Además, puedes conectarte a cualquier puerto de una máquina virtual determinada.

Este enfoque es mucho más flexible que el método de reenvío de puertos simple, pero también requiere que cambies la configuración de tu navegador web para utilizar el proxy.

A continuación, configura Chrome o Firefox para que usen el proxy.

Chrome

Chrome usa la configuración de proxy de todo el sistema de forma predeterminada, por lo que debes especificar un proxy diferente mediante marcas de línea de comandos. Al iniciar Chrome de forma predeterminada, se crea una máquina virtual de un perfil que ya está en ejecución, por lo que, para poder ejecutar varias copias de Chrome simultáneamente (una que use el proxy y otras que no), necesitas un nuevo perfil.

Inicia Chrome con un nuevo perfil. Se creará automáticamente si no existe.

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"

Asigna al puerto localhost el mismo valor que has usado en el comando gcloud anterior (1080 en nuestro ejemplo).

Firefox

Antes de cambiar estos ajustes, te recomendamos que crees un nuevo perfil de Firefox. De lo contrario, afectará a todas las máquinas virtuales de Firefox para que usen ese host como proxy, lo que probablemente no sea lo que quieres.

Una vez que Firefox se esté ejecutando con un perfil independiente, puedes configurar el proxy 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. Elige la opción Configuración manual del proxy.
    1. En la sección Host SOCKS, introduce localhost como host y el puerto que has seleccionado al ejecutar el comando gcloud anteriormente.
    2. Elige SOCKS v5.
    3. Marca la casilla DNS remoto.
    4. Deja el resto de las entradas en blanco.
  4. Haz clic en Aceptar y cierra el cuadro de diálogo Preferencias.

Conectarse a máquinas virtuales sin direcciones IP externas

Cuando las VMs no tienen direcciones IP externas (incluidas las VMs que son back-ends de balanceadores de carga de proxy HTTPS y SSL), solo se puede acceder a ellas de las siguientes formas:

Puedes aprovisionar máquinas virtuales en tu red para que actúen como repetidores de confianza para las conexiones entrantes, también conocidas como bastion hosts (pasarelas de aplicaciones). Además, puedes configurar Cloud NAT para el tráfico de red saliente o configurar la consola serie interactiva para mantener o solucionar problemas de las VMs sin direcciones IP externas.

Hosts bastión

Los hosts bastion 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 bastion que actúan como punto de entrada orientado al exterior de una red de instancias privadas.

Este host puede proporcionar un único punto de fortificación o auditoría, y se puede iniciar y detener para habilitar o inhabilitar SSH entrante. Si usas un host bastion, puedes conectarte a una VM que no tenga una dirección IP externa. Este enfoque te permite conectarte a un entorno de desarrollo o gestionar la instancia de base de datos de tu aplicación externa, por ejemplo, sin configurar reglas de firewall adicionales.

La protección completa de un host bastión queda fuera del ámbito de este artículo, pero se pueden seguir algunos pasos iniciales, como los siguientes:

  • Limita el intervalo CIDR de las IPs de origen que pueden comunicarse con el bastion.
  • Configura reglas de cortafuegos para permitir el tráfico SSH a las VMs privadas solo desde el host bastion.

De forma predeterminada, SSH en las VMs está configurado para usar claves privadas para la autenticación. Cuando usas una pasarela de aplicaciones, primero inicias sesión en ella y, después, en tu máquina virtual privada de destino. Por este motivo, los hosts bastion se denominan a veces "servidores de salto". Por eso, debes usar el reenvío ssh en lugar de almacenar la clave privada de la máquina de destino en el host bastion para acceder a la máquina de destino. Debes hacerlo aunque utilices el mismo par de claves para las máquinas virtuales bastion y de destino, ya que la máquina virtual bastion solo tiene acceso directo a la mitad pública del par de claves.

Para saber cómo usar una instancia de pasarela de aplicaciones para conectarte a otras VMs de tu red Google Cloud , consulta el artículo Conectarse a VMs Linux mediante una pasarela de aplicaciones.

Para saber cómo usar el reenvío y otros métodos para conectarte a VMs que no tienen una dirección IP externa, consulta el artículo Conectarse a VMs que no tienen direcciones IP externas.ssh

IAP para el reenvío de TCP

Si usas SSH con la función de reenvío de TCP de IAP, se encapsula una conexión SSH en HTTPS. La función de reenvío de TCP de IAP la envía a la VM remota.

Para saber cómo conectarte a una VM remota con IAP, consulta el artículo Conectarse a máquinas virtuales Linux con Identity-Aware Proxy.

VPN

Cloud VPN te permite conectar tu red a tu red deGoogle Cloud mediante una conexión IPsec a un dispositivo de pasarela VPN. De esta forma, se puede enrutar directamente el tráfico desde tus instalaciones a las interfaces de IP privada de las VMs de Compute Engine. El tráfico se cifra cuando se transmite a través de enlaces públicos a Google.

Para obtener información sobre cómo configurar y usar una VPN con Compute Engine, consulta la documentación de Cloud VPN.

Para saber cómo conectarte a las VMs de tu Google Cloud red a través de una VPN en lugar de hacerlo mediante las direcciones IP externas de las VMs, consulta el artículo Conectarse a VMs Linux mediante Cloud VPN o Cloud Interconnect.

Tráfico saliente con Cloud NAT

Si no se asigna una dirección IP externa a una VM, esta no podrá establecer conexiones directas con servicios externos, incluidos otros servicios de Google Cloud. Para permitir que estas VMs accedan a servicios en Internet público, puedes configurar Cloud NAT, que puede enrutar el tráfico en nombre de cualquier VM de la red. No considere que una sola máquina virtual tenga alta disponibilidad ni que pueda admitir un alto rendimiento de tráfico para varias máquinas virtuales.

Acceso a la consola en serie interactiva

Aunque una máquina virtual no tenga una dirección IP externa, es posible que tengas que interactuar con ella para solucionar problemas o realizar tareas de mantenimiento. Configurar un host bastion, como hemos comentado antes, es una opción, pero puede requerir más configuración de la que te conviene. Si quieres solucionar problemas de una VM sin una dirección IP externa, puedes 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 ella.

Para obtener más información, consulta el artículo Interactuar con la consola en serie.

Balanceadores de carga HTTPS y de proxy SSL

Las VMs que son backends de balanceadores de carga de proxy HTTPS y SSL no tienen que tener direcciones IP externas para acceder a ellas a través del balanceador de carga. Para acceder directamente a estos recursos, es necesario usar los métodos que se indican en la sección Conectarse a VMs sin direcciones IP externas.

Para obtener más información, consulta la documentación sobre el balanceo de carga de esos balanceadores.