Por Diego Patrik
SSH, ou Secure Socket Shell, é um protocolo de rede que permite acesso remoto a usuários, e especialmente administradores de forma segura em redes inseguras. Foi criado para ser uma substituição ao telnet, que diferente do SSH, não permite uma comunicação de forma criptografada. O SSH segue o modelo de cliente-servidor e é amplamente utilizado para a gestão de sistemas e aplicações de forma remota, permitindo se conectar a outro computador pela rede, executar comandos e mover arquivos. Qualquer usuário Linux ou MacOS consegue se conectar a um servidor remoto a partir de uma tela de terminal, sendo possível até usuários Windows, por meio de clientes SSH como o Putty, estabelecer facilmente uma comunicação.
A forma básica de utilização é a conexão por meio de um terminal, tendo como formas de autenticação mais populares a autenticação por usuário e senha e a autenticação por meio de chaves.
Em uma autenticação usando chaves SSH, o cliente consegue se conectar com sucesso ao servidor quando o servidor reconhece a chave pública do cliente e o cliente prova ser o dono da chave.
Utilizar autenticação baseada em chaves SSH pode ser um pouco mais complexo, mas tendo segurança em mente, podemos dizer que é superior ao uso da autenticação por senha, por evitar, por exemplo, a possibilidade do uso de senhas fracas como único fator de acesso ao servidor e ataques de eavesdropping enquanto a senha é digitada e o envio da senha para um servidor desconhecido por erro de digitação. Apesar de resolver esses problemas, esse famoso método de copiar e colar chaves também tem os seus contras.
Primeiro, não há checagem na identidade do servidor. Quando conectamos a um servidor pela primeira vez, é exibida uma mensagem similar a seguinte:
The authenticity of host '111.111.11.111 (111.111.11.111)' can't be established. ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe. Are you sure you want to continue connecting (yes/no)? yes
A mensagem nos indica que o host remoto não é reconhecido e, na prática, o usuário aceita continuar, automaticamente, sem verificar se de fato o host é o servidor no qual deseja conectar. Outros pontos negativos são:
- Flexibilidade: não há possibilidade de dar acesso baseado em tempo
- Transparência: analisar os logs não é tarefa fácil
- Escalabilidade: não é muito gerenciável quando há vários servidores e vários usuários
À medida que cresce a quantidade de servidores e usuários, e passa a ser uma dor de cabeça fazer a gestão das chaves SSH, uma forma central de autenticação como LDAP e/ou Kerberos pode ser utilizada para a gestão de contas, mas, ao mesmo tempo, percebemos que uma autenticação central é um ponto único de falha.
Apesar do uso de um sistema de certificados X.509 de PKI trazer uma solução para esse problema de usar chaves SSH não ser escalável, há um processo de submissão e validação com custos envolvidos, para conseguir ter o certificado assinado. Como alternativa, encontramos o OpenSSH, que suporta a criação de certificados simples com uma infraestrutura de CA associada.
Benefícios em utilizar autenticação por certificado
No universo do SSH, a autenticação por certificados pode ser considerada como um próximo nível a autenticação por chaves. Esse método funciona de forma similar ao SSL, o qual é amplamente conhecido e utilizado pela internet para o tráfego de HTTPS.
Em uma autenticação SSH utilizando certificado, ao confiar na certificate authority (CA), o cliente confia em todos os servidores assinados por essa CA. E um servidor confia em todas as chaves de usuário se a chave tem uma assinatura da CA, e o servidor confia na CA para assinar novas chaves de usuários.
Os principais ganhos em utilizar essa forma de autenticação são:
- Segurança: Emitindo certificados por um curto período de tempo pode-se diminuir o risco de acesso não autorizado a servidores
- Flexibilidade: com certificado é possível configurar diversas opções, podendo assim alcançar flexibilidade
- Transparência: os IDs tornam os logs mais fáceis de debugar
- Escalabilidade: possibilidade de criar um servidor de CA (garantindo a segurança) com uma aplicação web com autenticação que solicita 2FA para emitir certificados
- Verificação do host: a verificação da autenticidade do host é feita de forma automática
Os certificados contêm uma chave pública, informações de identidade e detalhes de validade. São assinados com uma chave pública SSH comum utilizando a ferramenta ssh-keygen. Utilizando essa ferramenta, há dois tipos de certificados: usuário e host. O certificado de usuário serve para autenticar clientes a servidores, enquanto o certificado de host autentica servidores ao cliente. Para ambos os certificados, é necessário configurar o sshd para confiar na chave pública da CA.
Como Implementar?
O primeiro passo da implementação é criar sua própria Autoridade Certificadora ou Certificate Authority (CA), que nesse caso é simplesmente criar um par de chaves normal.
Gerando um par de chaves:
$ ssh-keygen -t rsa -f ca_key
O comando anterior, irá gerar dois arquivos: ca_key (chave privada) e ca_key.pub (chave pública). A chave pública será compartilhada com todos os hosts que deverão ter acesso.
Configurando o host para reconhecer o CA:
1. Copiar a chave pública do CA (pub) para /etc/ssh/ no servidor.
2. Configurar os servidores SSH para confiar na CA adicionando a seguinte linha no final do arquivo /etc/ssh/sshd_config
TrustedUserCAKeys /etc/ssh/ca_key.pub
3. Rodar o comando service sshd reload para recarregar as configurações.
Assinando a chave do host (emitindo o certificado do servidor):
1. Copiar a chave pública do servidor (/etc/ssh/ssh_host_rsa_key.pub) para a máquina do CA
2. Assinar usando o comando:
$ ssh-keygen -s ca_key -I Host -V +52w -h ssh_host_rsa_key.pub
-s = chave privada (CA)
-I = Identificador (Vai aparecer nos logs)
-V = validade
-h = flag para indicar que está assinando chave de host
3. Copiar o arquivo gerado pelo comando anterior (ssh_host_rsa_key-cert.pub) de volta para o servidor, em /etc/ssh/
4. Adicionar a seguinte linha no fim do arquivo /etc/ssh/sshd_config no servidor:
HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub
5. Rodar o comando service sshd reload para recarregar as configurações.
Configurando o Cliente confiar nas assinaturas do CA:
Para isso, é necessário copiar o conteúdo da chave pública (ca_key.pub) e adicionar no arquivo known_hosts no formato:
@cert-authority * ssh-rsa <conteúdo da chave pública>
O valor * nesse caso é um padrão para combinação, que representa o domínio, ou a lista de domínios para o qual esse certificado deve ser confiado. Podendo ser passado como *.exemplo.com ou host1,host2,host3 por exemplo. Para exemplificar, ao definir o valor como *.exemplo.com, e iniciar uma conexão pela primeira vez com host.exemplo.com, a conexão ocorre de forma direta, sem a necessidade de aceitar confiar no host.
Assinando a chave do usuário (Emitindo o certificado de cliente):
- Copiar a chave pública do cliente, que por padrão está localizada em ~/.ssh/id_rsa.pub (caso exista), para a máquina da CA
- Assinar usando o comando:
$ ssh-keygen -s ca_key -I Client -n root,host -V +52w id_rsa.pub
-s = chave privada (CA)
-I = Identificador (Vai aparecer nos logs)
-V = validade
-n = lista de usuários que o cliente tem acesso no servidor
3. Copiar o arquivo gerado pelo comando anterior (id_rsa-cert.pub) de volta para o cliente, em ~/.ssh/
Neste momento, já é possível estabelecer uma conexão entre cliente e servidor utilizando certificado SSH. E para isso, o comando para a conexão não sofre alterações:
$ ssh user@remote_host
Conforme citado, anteriormente, no exemplo abaixo vemos que a conexão SSH utilizando certificado ocorre de forma similar à forma por chaves, mas sem exibir mensagens do tipo “The authenticity of host <host> can’t be established”, ao se conectar pela primeira vez a um host.
Somente ao ativar o modo verboso e analisar a saída que encontramos informações referentes ao uso do certificado:
Configuração aplicada no cliente:
Configuração aplicada no servidor:
Boas práticas
Para melhorar ainda mais a segurança no uso de certificados SSH, podemos listar algumas recomendações como boas práticas:
- Separar o acesso a diferentes hosts.
- Ter chaves de CA distintas para assinar certificados de Cliente/Servidor.
- Em ambiente de produção, uma recomendação seria armazenar a chave privada da CA em uma máquina offline com conta de administrador, utilizando somente quando for necessário emitir novos certificados.
- Como alternativa ao uso de uma máquina dedicada como CA, é possível utilizar uma solução baseada em API como o Vault. Outra possibilidade ainda, seria aproveitar a utilização do Active Directory da Microsoft.
Integração com Active Directory
Como já foi citado, em um cenário de uso real, além de levar em consideração as boas práticas, algo interessante seria utilizar o Active Directory (AD) como plataforma central de autenticação e autoridade certificadora para uma autenticação SSH baseada em certificados.
Um caminho para isso, é utilizar a mesma ferramenta que usamos no Linux, OpenSSH, que está disponível a partir do Windows Server 2019 e pode ser instalado seguindo os passos nesta página da documentação oficial da Microsoft.
Com o OpenSSH instalado, é necessário iniciar o serviço sshd com os seguintes comandos em um prompt elevado do PowerShell no servidor:
# Set the sshd service to be started automatically Get-Service -Name sshd | Set-Service -StartupType Automatic # Now start the sshd service Start-Service sshd
Para gerar a CA, basta utilizar o comando padrão em um prompt do PowerShell
$ ssh-keygen -t rsa -f ca_key
O cliente OpenSSH inclui o scp, que é um utilitário de transferência de arquivo seguro e pode ser utilizado para seguir com os passos descritos anteriormente.
Para um cenário em cloud, utilizando Azure, a Microsoft fornece um guia de como utilizar o Azure AD com autenticação baseada em certificados SSH para logar em VMs Linux na Azure.
Pontos negativos
Assim como a autenticação por senha e autenticação por chaves, também encontramos prós e contras no método de autenticação com certificados. O primeiro ponto negativo que podemos observar é a maior complexidade de implementação e o fato de haver bem menos documentação sobre. Outro ponto a considerar é que, até o momento, ainda não é possível iniciar uma conexão por certificado utilizando clientes como o Putty.
Conclusão
Entendemos como funciona a autenticação SSH por chaves e como o uso de uma autenticação SSH por certificados pode resolver a maioria dos seus problemas. Além de melhorar a segurança da infraestrutura SSH, como vimos, esse método também entrega escalabilidade, flexibilidade e transparência, sendo motivos suficientes para encarar toda a complexidade inicial envolvida.
Referências
BETTER PROGRAMMING. How to Use SSH Certificates for Scalable, Secure, and More Transparent Server Access. Disponível em: https://betterprogramming.pub/how-to-use-ssh-certificates-for-scalable-secure-and-more-transparent-server-access-720a87af6617/. Acesso em: 17 mar 2023.
DIGITALOCEAN. Como configurar a autenticação baseada em chaves SSH em um servidor Linux. Disponível em: https://www.digitalocean.com/community/tutorials/how-to-configure-ssh-key-based-authentication-on-a-linux-server-pt/. Acesso em: 17 mar 2023.
FACEBOOK ENGINEERING. Scalable and secure access with SSH. Disponível em: https://engineering.fb.com/2016/09/12/security/scalable-and-secure-access-with-ssh/. Acesso em: 17 mar 2023.
GO TELEPORT. How to SSH Properly. Disponível em: https://goteleport.com/blog/how-to-ssh-properly/. Acesso em: 17 mar 2023.
IBUG. Managing servers with OpenSSH Certificate Authority. Disponível em: https://ibug.io/blog/2019/12/manage-servers-with-ssh-ca/. Acesso em: 17 mar 2023.
MICROSOFT DOCS. OpenSSH key management. Disponível em: https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement/. Acesso em: 17 mar 2023.
RED HAT. Using OpenSSH Certificate Authentication. Disponível em: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/sec-using_openssh_certificate_authentication/. Acesso em: 17 mar 2023.
TECHTARGET. Secure Shell (SSH). Disponível em: https://www.techtarget.com/searchsecurity/definition/Secure-Shell/. Acesso em: 17 mar 2023.
THORNTECH. Passwords vs. SSH keys – what’s better for authentication? Disponível em: https://www.thorntech.com/passwords-vs-ssh/. Acesso em: 17 mar 2023.