DEV Community

Cover image for GCP OSLogin: entendendo como funciona!
Marcelo Andrade
Marcelo Andrade

Posted on • Edited on

GCP OSLogin: entendendo como funciona!

Você usa / trabalha com Linux há anos diariamente, e usa SSH para tudo. Provavelmente vai ser difícil apresentar algo que você não conheça, certo?

Então vamos tirar isso à prova fazendo um estudo de caso do recurso OSLogin do Google Cloud. No final, me conte se aprendeu algo diferente ou não!

OS Login

De acordo com a documentação, OS Login é um recurso para melhor gerir o acesso via SSH às suas máquinas virtuais Linux no GCP. Ele faz mais que gerenciar chaves:

  • é um mecanismo completamente integrado ao GCP IAM, o que garante controle de acesso e permissões granulares usando políticas globais da conta e não do Linux;
  • implementa componentes que permitem ao Linux reconhecer identidades externas, que podem estar em um servidor LDAP ou no seu Active Directory.

Eu vejo muitas comparações com o AWS Systems Manager - Session Manager, mas é um recurso muito mais parecido com outro recurso da AWS chamado Instance Connect.

Como acessar VMs

Em uma instância com este recurso ativado (é possível ativá-lo na maioria das instâncias Linux no processo de criação), basta executar um único comando que você consegue o acesso:

$ gcloud compute ssh instancia-publica
...
Last login: Thu Dec 14 02:20:56 2023 from 35.235.244.32
cloud_user_p_0fffe37e_linuxacade@instancia-publica:~$
Enter fullscreen mode Exit fullscreen mode

Se sua máquina não tiver um endereço IP público para acesso direto, o Gcloud é esperto o suficiente para saber que precisa de um passo a mais para viabilizar:

$ gcloud compute ssh instance-2
External IP address was not found; defaulting to using IAP tunneling.
...
Enter fullscreen mode Exit fullscreen mode

Usuários com a role compute.osLogin ou compute.osAdminLogin naquela ainstância poderão acessar a máquina. Pode ser necessário mais permissões caso a máquina use uma ServiceAccount.

Como funciona o OS Login - cliente SSH

Ao tentar usar OS Login a primeira vez, você deverá receber a seguinte mensagem:

$ gcloud compute ssh instance-1
WARNING: The private SSH key file for gcloud does not exist.
WARNING: The public SSH key file for gcloud does not exist.
WARNING: You do not have an SSH key for gcloud.
WARNING: SSH keygen will be executed to generate a key.
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/marcelo/.ssh/google_compute_engine
Your public key has been saved in /home/marcelo/.ssh/google_compute_engine.pub
The key fingerprint is:
SHA256:W0xABfw0HgNyBgsPX6av+co9ZM/JWaa893fcIhM3zL8 marcelo@devsres.com
The key's randomart image is:
+---[RSA 3072]----+
|    o o+X+.      |
|     = O..=      |
|      =  +.+     |
|       . oo      |
|        S o  o   |
|       ooo  + =  |
|      oo.= * o +.|
|     . o. O + . *|
|      o.o..o +.Eo|
+----[SHA256]-----+
...
Enter fullscreen mode Exit fullscreen mode

Ainda que você tenha chaves - mesmo com os nomes padrão id_rsa, id_ecdsa, id_ed25519 -, ele irá gerar uma nova para você:

$ ls -la ~/.ssh/google*
-rw------- 1 marcelo marcelo 2602 Dec 13 23:38 /home/marcelo/.ssh/google_compute_engine
-rw-r--r-- 1 marcelo marcelo  571 Dec 13 23:38 /home/marcelo/.ssh/google_compute_engine.pub
-rw-r--r-- 1 marcelo marcelo  218 Dec 13 23:44 /home/marcelo/.ssh/google_compute_known_hosts
Enter fullscreen mode Exit fullscreen mode

(Observe que eles optam por não poluir o seu arquivo known_hosts com as máquinas do GCP, o comando gcloud adiciona os hosts conhecidos em um arquivo próprio, o .ssh/google_compute_known_hosts)

A chave gerada é uma RSA de 3072 bits:

# O comando executado deve ter sido:
# ssh-keygen -t rsa -b 3072 ~/.ssh/google_compute_engineq
$ ssh-keygen -l -f ~/.ssh/google_compute_engine.pub
3072 SHA256:W0xABfw0HgNyBgsPX6av+co9ZM/JWaa893fcIhM3zL8 marcelo@dominator (RSA)
Enter fullscreen mode Exit fullscreen mode

Após gerar a chave, o gcloud "sobe" a chave pública para o GCP sem você ver:

$ gcloud compute os-login ssh-keys list
FINGERPRINT                                                       EXPIRY
eee442d8830969ce8109c1c62a8d1aed1c188c11e87c7beebdb8610269724138
Enter fullscreen mode Exit fullscreen mode

É possível ver informações sobre a chave executando o comando:

$ gcloud compute os-login ssh-keys describe --key eee442d8830969ce8109c1c62a8d1aed1c188c11e87c7beebdb8610269724138
fingerprint: eee442d8830969ce8109c1c62a8d1aed1c188c11e87c7beebdb8610269724138
key: ssh-rsa ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCsPAqzEGyyz5ltlhJd1wxSyde2WOkDz4baJkDyB90dXstaVLkrw64LfYTIu0W2gpJOLkzOsUNjhTJl/3Feda+GvTIpNpom7EboCYbNd9ExTWnw2W1d6Y/Inn1vydOHoi1qt7X97QOfg7avDkYHoXhHMxumRetUWxte1FBKZ8se3KAPUH/GCBEB28EO6OOqs89c9MmjxWq9d1l0iMioGzGRkM2DvowhmVe5NwrYZMeSXBd7x0bGkDTpdaT5RFJf1nvBy8a68SQbTGO6d9KsqsGmTyUrUPhylkG+yzG+DW4p+KRsC8M6bXX0J3DCiHA9evLT6MyuTpOJDpxJAb+UAdXNwNn6T154HJZ1s1w4u5ruenAepaXBqI8EzGKBy0VUBObupQZuEMNj7XkKTlF3hgjwDvnMQr0AbDsz7da/uMhcVjoUCGZPRmeYRtCpUaEG453W9ZgNlQYALy18D4NEaJ85XiQQUQWDbBoEUcdl6R0JCIJK6pe4HxTyJT05I/QYNus=
  marcelo@devsres.com
name: users/cloud_user_p_0fffe37e@linuxacademygclabs.com/sshPublicKeys/eee442d8830969ce8109c1c62a8d1aed1c188c11e87c7beebdb8610269724138
Enter fullscreen mode Exit fullscreen mode

É possível reusar suas chaves sem dificuldade:

$ gcloud compute os-login ssh-keys add --key-file ~/.ssh/id_rsa.pub --ttl 30
...
$ gcloud compute os-login ssh-keys list
FINGERPRINT                                                       EXPIRY
ca30c038ede7cc7ed7bee957d7778988b540f8204beabe2cdccf00ae78031a30  2023-12-14T03:19:19Z
eee442d8830969ce8109c1c62a8d1aed1c188c11e87c7beebdb8610269724138
...
Enter fullscreen mode Exit fullscreen mode

Executar o "gcloud compute ssh" especificando uma chave privada sem subir a chave pública faz o auto upload da chave com TTL 0 (ou seja, não expira).

Como funciona o OS Login no servidor

No Linux: NSS

Agora sim, a parte interessante!

Primeiramente, vamos observar com que usuário você autentica no servidor remoto:

$ gcloud compute ssh instancia-publica --project=playground-s-11-b0bd65c9 --zone=us-central1-a
...
cloud_user_p_0fffe37e_linuxacade@instance-1:~$ whoami
cloud_user_p_0fffe37e_linuxacade
Enter fullscreen mode Exit fullscreen mode

O usuário está associado ao meu usuário do Google Cloud - que é meio grande e não coube: cloud_user_p_0fffe37e@linuxacademygclabs.com.

Aqui a primeira diferença deste recurso para o SSM Session Manager e o Instance Connect: esse usuário não foi criado localmente na máquina:

[instancia-publica] $ grep cloud_user /etc/passwd | echo nao achei nada
nao achei nada
Enter fullscreen mode Exit fullscreen mode

Isso acontece porque o OS Login integra com uma velha conhecida no mundo Linux, a libnss, por meio de um módulo específico (na verdade, dois):

[instancia-publica] $ head -n 13 /etc/nsswitch.conf
# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd:         files cache_oslogin oslogin
group:          files cache_oslogin oslogin
shadow:         files
gshadow:        files

hosts:          files dns
networks:       files
Enter fullscreen mode Exit fullscreen mode

O arquivo nsswitch.conf é onde, tradicionalmente, mapeamos essa integração. A resolução de nomes, por exemplo, ocorre na ordem files -> dns (ou seja, /etc/host, depois linux client resolver). Para entradas no /etc/passwd ou /etc/group, a libnss orienta buscar, após destes arquivos, primeiramente no provider cache_oslogin, e posteriormente no próprio oslogin.

Essas libs são instaladas pelo pacote:

[instancia-publica] $ dpkg -L google-compute-engine-oslogin | fgrep libnss
/lib/x86_64-linux-gnu/libnss_cache_oslogin-20231004.00.so
/lib/x86_64-linux-gnu/libnss_oslogin-20231004.00.so
/lib/x86_64-linux-gnu/libnss_cache_oslogin.so.2
/lib/x86_64-linux-gnu/libnss_oslogin.so.2
Enter fullscreen mode Exit fullscreen mode

Também há units do systemd ativas com estes programas:

[instancia-publica] $ systemctl list-units 'google*'
  UNIT                            LOAD   ACTIVE SUB     DESCRIPTION
  google-guest-agent.service      loaded active running Google Compute Engine Guest Agent
  google-osconfig-agent.service   loaded active running Google OSConfig Agent
  google-shutdown-scripts.service loaded active exited  Google Compute Engine Shutdown Scripts
  google-oslogin-cache.timer      loaded active waiting NSS cache refresh timer
Enter fullscreen mode Exit fullscreen mode

Dependendo do provider, é possível ver as entradas usando o comando abaixo:

[instancia-publica] $ getent passwd | tail -n5
systemd-timesync:x:999:999:systemd Time Synchronization:/:/usr/sbin/nologin
systemd-coredump:x:998:998:systemd Core Dumper:/:/usr/sbin/nologin
cloud_user_p_0fffe37e_linuxacade:*:1862762045:1862762045::/home/cloud_user_p_0fffe37e_linuxacade:/bin/bash
sa_112203697991872690750:*:3661484281:3661484281::/home/sa_112203697991872690750:/bin/bash
sa_109344113766727672345:*:3686152525:3686152525::/home/sa_109344113766727672345:/bin/bash
Enter fullscreen mode Exit fullscreen mode

Nem sempre o comando getent traz todas as entradas. Isso não quer dizer que o sistema operacional não seja capaz de enxergá-lo, apenas indica que a biblioteca usada não necessariamente suporta enumeração.

Se seu usuário não fosse visível para o SO, você não conseguiria nem logar!

Se ele não surgir na saída do comando acima, é possível fazer uma query direta sobre ele especificando o nome:

[instancia-publica] $ id
uid=1862762045(cloud_user_p_0fffe37e_linuxacade) gid=1862762045(cloud_user_p_0fffe37e_linuxacade) groups=1862762045(cloud_user_p_0fffe37e_linuxacade),44(video)

[instancia-publica] $ getent passwd cloud_user_p_0fffe37e_linuxacade
cloud_user_p_0fffe37e_linuxacade:*:1862762045:1862762045::/home/cloud_user_p_0fffe37e_linuxacade:/bin/bash
Enter fullscreen mode Exit fullscreen mode

Nem todo mundo conhece estas funcionalidades do mundo Linux! Elas vêm desde lá atrás com o NIS/Yellow Pages, e geralmente só quem administra servidores integrados com LDAP ou Active Directory conhece esses recursos!

Agora, uma outra consideração: as conexões realmente ocorrem via ssh a partir do endereço da sua máquina!

[instancia-publica] $ ss -nt '( sport = :22 )'
State              Recv-Q              Send-Q                           Local Address:Port                            Peer Address:Port              Process
ESTAB              0                   140                                 10.128.0.2:22                             XXX.42.69.YYY:59660
Enter fullscreen mode Exit fullscreen mode

No caso, o IP XXX.42.69.YYY representa o meu endereço IP.

Se você executar o comando a partir de um tunel IAP, o endereço vai ser outro:

[instancia-publica] $ ss -nt '( sport = :22 )'
State              Recv-Q              Send-Q                           Local Address:Port                           Peer Address:Port               Process
ESTAB              0                   0                                   10.128.0.2:22                             35.235.240.4:46519
Enter fullscreen mode Exit fullscreen mode

Ou seja, é necessário garantir que haja conectividade a partir dos recursos de Identity Aware Proxy (IAP) do Google Cloud para que isso funcione (i.e., abrir regras para o range 35.235.240.0/20, como descrito na documentação).

Como os acessos ocorrem realmente via SSH (diferentemente do AWS SSM Session Manager), é necessário configurar um outro componente para viabilizar o login no Linux: o PAM!

No Linux: PAM

O diretório /etc/pam.d conta com a configuração de como vários programas do Linux realizam seu processo de autenticação e estabelecimento de sessões!

[instancia-publica] $ ls /etc/pam.d
chfn      chsh            common-auth      common-session                 cron   newusers  passwd   runuser-l  su    sudo
chpasswd  common-account  common-password  common-session-noninteractive  login  other     runuser  sshd       su-l
Enter fullscreen mode Exit fullscreen mode

O PAM oculta diversas camadas de complexidade por trás de sua aparente simplicidade, e é imprescindível que um administrador Linux entenda do que se trata e saiba ler o que dizem as configurações.

Esta é a configuração PAM do comando sudo:

[instancia-publica] $ egrep -v '^$|^#'  /etc/pam.d/sudo
@include common-auth
@include common-account
@include common-session-noninteractive
Enter fullscreen mode Exit fullscreen mode

Esta, a do su:

[instancia-publica] $ egrep -v '^$|^#'  /etc/pam.d/su
auth          sufficient pam_rootok.so
session       required   pam_env.so readenv=1
session       required   pam_env.so readenv=1 envfile=/etc/default/locale
session       optional   pam_mail.so nopen
session       required   pam_limits.so
@include common-auth
@include common-account
@include common-session
Enter fullscreen mode Exit fullscreen mode

E esta a do ssh (se a diretiva UsePAM estiver configurada!):

[instancia-publica] $ sudo fgrep -i 'UsePAM'  /etc/ssh/sshd_config
UsePAM yes

[instancia-publica] $ egrep -v '^$|^#'  /etc/pam.d/sshd
auth       [default=ignore] pam_group.so
@include common-auth
account    required     pam_nologin.so
@include common-account
session [success=ok ignore=ignore module_unknown=ignore default=bad]        pam_selinux.so close
session    required     pam_loginuid.so
session    optional     pam_keyinit.so force revoke
@include common-session
session    optional     pam_motd.so  motd=/run/motd.dynamic
session    optional     pam_motd.so noupdate
session    optional     pam_mail.so standard noenv # [1]
session    required     pam_limits.so
session    required     pam_env.so # [1]
session    required     pam_env.so user_readenv=1 envfile=/etc/default/locale
session [success=ok ignore=ignore module_unknown=ignore default=bad]        pam_selinux.so open
@include common-password
session    [success=ok default=ignore] pam_mkhomedir.so
Enter fullscreen mode Exit fullscreen mode

Achou complicado? Note que em todos há includes de outros arquivos, o que 'empilha' as diretivas com as descritas nesses arquivos! Isso existe para evitar que você precise reconfigurar cada programa separadamente com as mesmas diretivas!

O Google OS Login pode modificar o PAM e usar dois módulos, o pam_oslogin_login.so para determinar se o usuário pode autenticar, e o pam_oslogin_admin.so que determina se o usuário vai poder usar o comando sudo.

Em vez de criar as entradas em /etc/sudoers.d, o OS Login deixa um arquivo com um include para outro diretório:

[instancia-publica] $ cat /etc/sudoers.d/google-oslogin
#includedir /var/google-sudoers.d

[instancia-publica] $ cat /var/google-sudoers.d/*
cloud_user_p_0fffe37e_linuxacade ALL=(ALL) NOPASSWD: ALL
Enter fullscreen mode Exit fullscreen mode

No SSH

A parte mais interessante, entretanto, vem nas modificações do SSH. O programa faz as seguintes modificações no arquivo /etc/sshd:

[instancia-publica] $ head -n7 /etc/ssh/sshd_config
#### Google OS Login control. Do not edit this section. ####
TrustedUserCAKeys /etc/ssh/oslogin_trustedca.pub
AuthorizedPrincipalsCommand /usr/bin/google_authorized_principals %u %k
AuthorizedPrincipalsCommandUser root
AuthorizedKeysCommand /usr/bin/google_authorized_keys
AuthorizedKeysCommandUser root
#### End Google OS Login control section. ####
Enter fullscreen mode Exit fullscreen mode

As três primeiras diretivas estão relacionadas ao uso de certificados SSH, o que, a princípio, não é a funcionalidade usada para as conexões do usuário - mas que vale a leitura a respeito se você nunca ouviu falar!

A diretiva mais importante para o uso desta funcionalidade é AuthorizedKeysCommand: ela permite que o SSH invoque um comando adicional para recuperar quais chaves estão associadas ao usuário tentando logar.

As chaves estão salvas no GCP (como mostramos na sessão do cliente!); logo, basta que a instância seja capaz de acessar a API do GCP e listar as chaves públicas cadastradas para o usuário!

[instancia-publica] $ /usr/bin/google_authorized_keys cloud_user_p_0fffe37e_linuxacade
ssh-rsa ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCsPAqzEGyyz5ltlhJd1wxSyde2WOkDz4baJkDyB90dXstaVLkrw64LfYTIu0W2gpJOLkzOsUNjhTJl/3Feda+GvTIpNpom7EboCYbNd9ExTWnw2W1d6Y/Inn1vydOHoi1qt7X97QOfg7avDkYHoXhHMxumRetUWxte1FBKZ8se3KAPUH/GCBEB28EO6OOqs89c9MmjxWq9d1l0iMioGzGRkM2DvowhmVe5NwrYZMeSXBd7x0bGkDTpdaT5RFJf1nvBy8a68SQbTGO6d9KsqsGmTyUrUPhylkG+yzG+DW4p+KRsC8M6bXX0J3DCiHA9evLT6MyuTpOJDpxJAb+UAdXNwNn6T154HJZ1s1w4u5ruenAepaXBqI8EzGKBy0VUBObupQZuEMNj7XkKTlF3hgjwDvnMQr0AbDsz7da/uMhcVjoUCGZPRmeYRtCpUaEG453W9ZgNlQYALy18D4NEaJ85XiQQUQWDbBoEUcdl6R0JCIJK6pe4HxTyJT05I/QYNus= marcelo@devsres.com
Enter fullscreen mode Exit fullscreen mode

Caso mais uma chave seja adicionada do lado do cliente:

$ gcloud compute os-login ssh-keys add --key-file ~/.ssh/id_ecdsa.pub --ttl 30
...

$ gcloud compute os-login ssh-keys list
FINGERPRINT                                                       EXPIRY
68dc496cf5293b7fa094a05b0f0acc92d2382e7bb983a70bacae1ea06cbfaeed  2023-12-14T05:27:22Z
eee442d8830969ce8109c1c62a8d1aed1c188c11e87c7beebdb8610269724138
Enter fullscreen mode Exit fullscreen mode

A saída do outro comando irá mostrar todas as chaves disponíveis!

[instancia-publica] $ /usr/bin/google_authorized_keys cloud_user_p_0fffe37e_linuxacade
fiXhlbf7uTxcmcYKSrFRakfPRyVtpUVaBLoTJHh70OvITNBXyCiUxwBGM6kKwqSWGX6uD3Bk8nal6cG4eZFHGFy8mfCK3Cx7wNShvXfXEVOqALXJI5W8NPl3eIOMQhx+S1mrK+45K4qTqfaUuq9W8MdrzUEfB4y/DbsgcY4p6GAqTBURuMU0Ym3d+H7DAo4rJCTpy1d/qTvCTkN14Y3slIshmzORmuo2caPpPMsX7iJtpLZkmMJ872gTKU3P5sx7efEv1D89i1WMHFpWAqhIRsKNsJCB53r0Dtt6dK2iKeonWgZYMYfKd+3Px8eDgYyOetNVFhaGXv9w/bDDj60pchENCEDTB59CdAU71tiI/U7738DITq1ZZVzCSWpu0= cloud_user_p_0fffe37e@cs-380498931324-default
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCsPAqzEGyyz5ltlhJd1wxSyde2WOkDz4baJkDyB90dXstaVLkrw64LfYTIu0W2gpJOLkzOsUNjhTJl/3Feda+GvTIpNpom7EboCYbNd9ExTWnw2W1d6Y/Inn1vydOHoi1qt7X97QOfg7avDkYHoXhHMxumRetUWxte1FBKZ8se3KAPUH/GCBEB28EO6OOqs89c9MmjxWq9d1l0iMioGzGRkM2DvowhmVe5NwrYZMeSXBd7x0bGkDTpdaT5RFJf1nvBy8a68SQbTGO6d9KsqsGmTyUrUPhylkG+yzG+DW4p+KRsC8M6bXX0J3DCiHA9evLT6MyuTpOJDpxJAb+UAdXNwNn6T154HJZ1s1w4u5ruenAepaXBqI8EzGKBy0VUBObupQZuEMNj7XkKTlF3hgjwDvnMQr0AbDsz7da/uMhcVjoUCGZPRmeYRtCpUaEG453W9ZgNlQYALy18D4NEaJ85XiQQUQWDbBoEUcdl6R0JCIJK6pe4HxTyJT05I/QYNus= marcelo@devsres.com
Enter fullscreen mode Exit fullscreen mode

É ou não é um recurso interessante?

Isso porque eu ainda não mostrei a funcionalidade de usar SSH com MFA também disponível!

Top comments (0)