Como se conectar a instâncias de VMs com segurança


Neste documento, descrevemos as práticas recomendadas para se conectar com segurança a instâncias de máquina virtual (VM) do Compute Engine, incluindo o armazenamento de chaves de host ao ativar atributos de convidado e impedindo que VMs sejam acessadas pela Internet pública.

Antes de começar

  • Configure a autenticação, caso ainda não tenha feito isso. A autenticação é o processo de verificação da sua identidade para acesso a serviços e APIs do Google Cloud. Para executar códigos ou amostras de um ambiente de desenvolvimento local, autentique-se no Compute Engine da seguinte maneira.

    Selecione a guia para como planeja usar as amostras nesta página:

    Console

    Quando você usa o console do Google Cloud para acessar os serviços e as APIs do Google Cloud, não é necessário configurar a autenticação.

    gcloud

    1. Instale a Google Cloud CLI e inicialize-a executando o seguinte comando:

      gcloud init
    2. Defina uma região e uma zona padrão.

Como armazenar chaves de host ativando atributos de convidado

Uma chave de host é um par de chaves que identifica um host ou máquina específicos. Quando você se conecta a um host remoto, a chave do host é usada para verificar se você está se conectando à máquina pretendida.

Se você usa gcloud compute ssh para se conectar às suas VMs Linux, pode adicionar uma camada de segurança armazenando suas chaves de host como atributos de convidado.

O armazenamento de chaves de host SSH como atributos de convidado melhora a segurança de suas conexões, visto que ajuda a proteger contra vulnerabilidades, como ataques "man-in-the-middle" (MITM, na sigla em inglês). Na primeira inicialização de uma VM, se os atributos de convidado estiverem ativados, o Compute Engine armazenará as chaves de host geradas como atributos de convidado. Depois disso, o Compute Engine usará essas chaves de host armazenadas para verificar todas as conexões subsequentes à VM.

As chaves de host podem ser armazenadas como atributos de convidado nas seguintes imagens públicas do sistema operacional:

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

Para gravar chaves de host em atributos de convidado, ative os atributos de convidado antes de inicializar a VM pela primeira vez. É possível ativar atributos de convidado em algumas VMs durante a criação da VM ou em todo o projeto.

Depois de ativar os atributos de convidado para um projeto ou VM, o agente do SO convidado publica automaticamente a chave de host como um atributo de convidado. Se você usar gcloud compute ssh em vez de um cliente SSH simples, a CLI gcloud lerá automaticamente os atributos e atualizará o arquivo known_hosts na próxima vez que você se conectar.

Para armazenar chaves de host como atributos de convidado, execute as seguintes etapas:

  1. Antes de inicializar a VM pela primeira vez, ative os atributos de convidado em VMs selecionadas durante a criação da VM ou em todo o projeto.

  2. Conecte-se à VM usando gcloud compute ssh.

    1. Verifique se você tem a versão mais recente da Google Cloud CLI:

      gcloud components update
      
    2. Conecte-se à VM:

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

      Substitua:

      • PROJECT_ID: o ID do projeto que contém a VM.
      • ZONE: o nome da zona em que a VM está localizada
      • VM_NAME: O nome da VM.

      Se você tiver definido as propriedades padrão para a Google Cloud CLI, poderá omitir as sinalizações --project e --zone desse comando. Exemplo:

      gcloud compute ssh VM_NAME
      
    3. Analise a mensagem de inicialização. Por exemplo, um sistema operacional Debian pode exibir a seguinte mensagem:

      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 as chaves de host estão armazenadas como atributos de convidado para essa VM, analise os valores de chave de host para confirmar se as chaves SSH são gravadas nos atributos de convidado para a VM (Opção 1) ou revise a porta serial da presença de chaves de host (Opção 2):

Opção 1: revisar os valores de chave de host

Use a Google Cloud CLI para verificar se as chaves SSH estão gravadas nos atributos de convidado:

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

Substitua:

  • VM_NAME: O nome da VM.
  • ZONE: o nome da zona em que a VM está localizada

A resposta será semelhante a:

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

Opção 2: analisar a porta serial

  1. Veja a saída da porta serial.
  2. Selecione a porta serial 1.
  3. Procure a seguinte mensagem:

    INFO Wrote ssh-rsa host key to guest attributes

    Se a imagem usar um sistema operacional compatível, mas a configuração de atributos de convidado não tiver sido ativada antes da primeira inicialização da VM, talvez apareça a seguinte mensagem:

    Unable to write ssh-rsa host key to guest attributes

    Isso significa que as chaves de host não estão armazenadas como atributos de convidado nessa VM. Se quiser armazenar chaves de host em outras VMs que você planeja criar, ative os atributos de convidado antes da primeira inicialização da VM.

Como impedir que as VMs sejam acessadas pela Internet pública

Ao desenvolver projetos no Compute Engine, existem diversos cenários em que você quer evitar que as VMs sejam acessadas pela Internet pública:

  • Por serem recursos incompletos ou que ainda não foram configurados com o HTTPS, os serviços da Web ainda estão em desenvolvimento e não estão prontos para serem expostos a usuários externos.
  • Talvez a VM esteja fornecendo serviços projetados para serem consumidos apenas por outras VMs no projeto.
  • As VMs só podem ser alcançadas por meio de opções de interconexão dedicada de data centers ou escritórios da empresa.

Mesmo quando um serviço é intencionalmente orientado para a Internet, é importante que a comunicação com o serviço seja restrita aos grupos de usuários de destino e ocorra por canais seguros, como SSH ou HTTPS, para proteger informações confidenciais.

Neste artigo, demonstramos vários métodos para proteger as comunicações com as VMs com endereços IP externos e VMs sem endereços IP externos. Mesmo que você não proteja as comunicações com esses métodos, o Google Cloud sempre permite a comunicação entre uma instância de VM e o servidor de metadados correspondente. Para mais informações, consulte a seção Tráfego sempre permitido.

Proteger serviços em máquinas com endereços IP externos

Quando as VMs têm um endereço IP público, é importante que somente os serviços e o tráfego a serem expostos fiquem acessíveis. Para aqueles que estão expostos, toda informação confidencial é protegida em trânsito. Há vários métodos para proteger serviços em VMs com endereços IP externos explicados neste documento, incluindo firewalls, HTTPS e SSL, encaminhamento de portas por SSH e proxy SOCKS por SSH.

Firewalls

A primeira linha de defesa é restringir quem pode chegar à VM usando firewalls. Ao criar regras de firewall, você pode restringir todo o tráfego a uma rede ou máquinas de destino em um determinado conjunto de portas para endereços IP de origem específicos.

Os firewalls não são uma solução autônoma. Restringir o tráfego para IPs de origem específicos não protege informações confidenciais, como credenciais de login, comandos que criam ou destroem recursos, ou arquivos ou registros. Ao executar um serviço da Web em uma máquina acessível publicamente, como uma VM do Compute Engine com um IP externo, é necessário criptografar toda a comunicação entre o host e a VM implantada para garantir a segurança adequada.

Além disso, os firewalls nem sempre são a solução apropriada. Por exemplo, eles não são ideais para ambientes de desenvolvimento que não têm endereços IP estáticos, como laptops em roaming.

HTTPS e SSL

Para sistemas da Web de produção, configure o HTTPS/SSL. O HTTPS/SSL pode ser configurado ao definir uma VM para encerrar o HTTPS ou ao ajustar o balanceamento de carga HTTPS. O HTTPS/SSL envolve uma certa complexidade inicial, exigindo que você execute as seguintes tarefas:

Encaminhamento de porta por SSH

É possível usar a Google Cloud CLI para iniciar um servidor em uma determinada porta local que encaminhe todo o tráfego para um host remoto por uma conexão SSH.

Primeiro, anote a VM e a porta que fornecem o serviço a que você gostaria de estabelecer uma conexão segura. Em seguida, execute o seguinte comando:

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

Substitua:

  • VM_NAME é o nome da VM a que você quer se conectar.
  • PROJECT_ID é o ID do projeto do Google Cloud.
  • ZONE: a zona em que a VM está sendo executada, por exemplo us-central1-a.
  • LOCAL_PORT: a porta local em que você está ouvindo, como 2222.
  • REMOTE_PORT: a porta remota a que você está se conectando, por exemplo, 8888.

Por exemplo, se você especificar uma porta local "2222" e uma porta remota "8888" e abrir http://localhost:2222/ no navegador, a conexão HTTP usa o túnel SSH criado para seu host remoto para se conectar à VM especificada usando SSH. A partir daí, a conexão HTTP usará o túnel SSH para se conectar à porta 8888 na mesma máquina, mas por meio de uma conexão SSH criptografada e segura.

O comando gcloud cria e mantém uma conexão SSH enquanto a sessão SSH está ativa. Assim que você sai da sessão SSH, o encaminhamento de porta que usa http://VM_NAME:LOCAL_PORT para de funcionar.

Para criar mais de uma regra de encaminhamento de portas, é possível especificar várias regras em uma única linha de comando repetindo estas sinalizações:

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

Como alternativa, é possível executar um novo comando gcloud sempre que criar um túnel separado. Observe que não é possível adicionar ou remover um encaminhamento de porta de uma conexão existente sem sair e restabelecer a conexão a partir do zero.

Proxy SOCKS por SSH

A maneira mais fácil de se conectar a vários hosts diferentes na implantação na nuvem é alterar o navegador para fazer as pesquisas diretamente da rede. Essa abordagem permite usar o nome abreviado dos hosts em vez de procurar o endereço IP de cada um deles, abrir portas para cada serviço ou criar um túnel SSH para cada par de host/porta.

A abordagem usada aqui é a seguinte:

  1. Configure um único túnel SSH para um dos hosts na rede e crie um proxy SOCKS nesse host.
  2. Mude a configuração do navegador para fazer todas as pesquisas por meio do host do proxy SOCKS.

Como você está fazendo o tunelamento de todo o tráfego usando esse host, evite usar esse navegador ou esse perfil específico para navegar na Web, porque você precisa dedicar a largura de banda ao serviço de nuvem. Em geral, talvez seja necessário usar um perfil de navegador separado e alternar para ele quando necessário.

Iniciar o proxy SOCKS

Para iniciar o proxy SOCKS, execute o seguinte comando:

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

Substitua:

  • VM_NAME: o nome da VM a que você quer se conectar.
  • PROJECT_ID: é o ID do projeto do Google Cloud.
  • ZONE: a zona em que a VM está sendo executada, por exemplo us-central1-a.
  • LOCAL_PORT: a porta local em que você está ouvindo, como 1080.

Neste caso, você não precisa especificar uma porta remota. Como um proxy SOCKS não se vincula a nenhuma porta remota específica, qualquer conexão feita por meio dele será resolvida em relação ao host ao qual você se conecta.

Ao usar um proxy SOCKS, é possível se conectar a qualquer VM que compartilhe uma rede do Compute Engine com a VM de proxy usando o nome curto da VM. Além disso, é possível se conectar a qualquer porta em uma determinada VM.

Essa abordagem é muito mais flexível do que o método de encaminhamento de porta simples, mas também exigirá que você altere as configurações no navegador para utilizar o proxy.

Em seguida, configure o Chrome ou o Firefox para usar o proxy.

Chrome

Por padrão, o Chrome usa configurações de proxy de todo o sistema. Sendo assim, é necessário especificar um proxy diferente usando sinalizações de linha de comando. Iniciar o Chrome cria uma VM de um perfil já em execução. Assim, para permitir que você execute várias cópias do Chrome simultaneamente, uma que esteja usando o proxy e outras que não estejam, você precisará de um novo perfil.

Inicie o Chrome usando um novo perfil. Ele será criado automaticamente, se ainda não existir.

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"

No Windows:

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

Defina a porta localhost com o mesmo valor que você usou no comando gcloud anteriormente (1080, no nosso exemplo).

Firefox

Antes de alterar essas configurações, talvez convenha criar um novo perfil do Firefox. Caso contrário, o uso desse host como proxy afetará todas as VMs do Firefox, o que provavelmente não é o que você quer.

Depois de executar o Firefox com um perfil separado, configure o proxy SOCKS:

  1. Abra Preferences.
  2. Clique em Advanced > Networks > Settings para abrir a caixa de diálogo Connection Settings.
  3. Escolha a opção Manual proxy configuration.
    1. Na seção Host SOCKS, preencha localhost como o host e a porta que você selecionou ao executar o comando gcloud anteriormente.
    2. Escolha SOCKS v5.
    3. Marque a caixa Remote DNS.
    4. Deixe todas as outras entradas em branco.
  4. Clique em OK e feche a caixa de diálogo Preferências.

Como se conectar a VMs sem endereços IP externos

Quando as VMs não têm endereços IP externos (incluindo VMs que são back-ends para balanceadores de carga de proxy HTTPS e SSL), elas só podem ser acessadas mediante as seguintes condições:

É possível provisionar VMs na rede para atuarem como redirecionamentos confiáveis para conexões de entrada, também conhecidas como Bastion Hosts. Além disso, é possível configurar um Cloud NAT para tráfego de rede de saída ou configurar o console serial interativo para manter ou solucionar problemas de VMs sem endereços de IP externo.

Bastion Hosts

Os Bastion Hosts fornecem um ponto de entrada externo em uma rede que contém instâncias de rede particular, conforme ilustrado no diagrama a seguir.

Arquitetura de Bastion Hosts atuando como ponto de entrada externo para uma rede de instâncias particulares.

Além de fornecer um ponto único de fortalecimento ou auditoria, esse host pode ser iniciado e interrompido para ativar ou desativar o SSH de entrada. Ao usar um Bastion Host, é possível se conectar a uma VM que não tenha um endereço IP externo. Essa abordagem permite que você se conecte a um ambiente de desenvolvimento ou gerencie a instância do banco de dados para o aplicativo externo, por exemplo, sem configurar regras de firewall adicionais.

Uma proteção completa de um Bastion Host está fora do escopo deste artigo, mas algumas etapas iniciais tomadas podem incluir as seguintes ações:

  • Limite o intervalo CIDR de IPs de origem que podem se comunicar com o Bastion.
  • configurar as regras de firewall a fim de permitir o tráfego SSH para VMs particulares apenas do Bastion Host.

Por padrão, o SSH em VMs é configurado para usar chaves privadas para autenticação. Ao usar um Bastion Host, primeiro faça login no Bastion Host e, depois, na VM particular de destino. Devido a esse login de duas etapas, razão pela qual os Bastion Hosts são às vezes são chamados de "servidores jump", use o encaminhamento ssh em vez de armazenar a chave privada da máquina de destino no Bastion Host como uma maneira de alcançar essa máquina. Você precisa fazer isso mesmo se estiver usando o mesmo par de chaves para VMs de destino e Bastion, porque o Bastion tem acesso direto apenas à metade pública do par de chaves.

Para saber como usar uma instância do Bastion Host para se conectar a outras VMs na rede do Google Cloud, consulte Conectar-se a VMs do Linux usando um Bastion Host.

Para saber como usar o encaminhamento de ssh e outros métodos para se conectar a VMs que não têm um endereço IP externo, consulte Como se conectar a VMs que não têm endereços IP externos.

IAP para encaminhamento de TCP

O uso do SSH com o recurso de encaminhamento de TCP do IAP inclui uma conexão SSH dentro do HTTPS, que é enviada para a VM remota.

Para saber como se conectar a uma VM remota com IAP, consulte Conectar-se a VMs do Linux usando o Identity-Aware Proxy.

VPN

O Cloud VPN permite conectar sua rede atual à rede do Google Cloud usando uma conexão de IPsec com um dispositivo de gateway de VPN. Isso permite o roteamento direto do tráfego do local às interfaces IP particulares das VMs do Compute Engine. O tráfego é criptografado enquanto transita por links públicos para o Google.

Para mais detalhes sobre como definir, configurar e usar a VPN com o Compute Engine, consulte a documentação do Cloud VPN.

Para saber como se conectar a VMs na rede do Google Cloud por meio de uma VPN atual em vez de endereços IP externos de VMs, leia Conectar-se a VMs do Linux usando o Cloud VPN ou o Cloud Interconnect.

Tráfego de saída usando o Cloud NAT

Quando uma VM não tem um endereço IP externo atribuído, ela não pode se conectar diretamente aos serviços externos, incluindo outros serviços do Google Cloud. Para permitir que essas VMs tenham acesso a serviços na Internet pública, configure o Cloud NAT, que pode rotear o tráfego em nome de qualquer VM na rede. Não suponha que uma única VM seja altamente disponível ou capaz de suportar uma alta capacidade de tráfego para várias VMs..

Acesso do console serial interativo

Quando uma VM não tem um endereço IP externo, talvez ainda seja necessário interagir com ela para solucionar problemas ou fazer manutenção. A configuração de um Bastion Host, como discutido anteriormente, é uma opção, mas pode exigir mais configuração do que é útil para suas necessidades. Se você quiser resolver problemas de uma VM sem um endereço IP externo, considere ativar o acesso interativo no console serial. Isso permite interagir com o console serial de uma VM usando o SSH e executar comandos nesse console.

Para saber mais, leia Interagir com o console serial.

Balanceadores de carga de proxy SSL e HTTPS

As VMs que são back-ends para balanceadores de carga de proxy HTTPS e SSL não precisam ter endereços IP externos para serem acessadas por meio do balanceador de carga. Para acessar esses recursos diretamente, é necessário usar os métodos listados em Como conectar-se a VMs sem endereços IP externos.

Para saber mais, leia a documentação sobre balanceamento de carga.