Servidor SSH – Usando chaves de autenticação


Comandos intermediários do GNU/Linux

Usando chaves de autenticação

Por mais seguras que sejam minhas senhas, sempre existe uma pequena possibilidade de que um atacante descubra alguma delas, observando enquanto eu digito no teclado, ou que simplesmente consiga adivinhá-la a partir de informações pessoais ou de senhas antigas. Se por algum acaso eu tenho o hábito de usar as mesmas senhas em vários locais, a possibilidade cresce, pois muitos serviços armazenam ou transmitem senhas de formas não seguras. Com isso, as senhas acabam sendo o ponto fraco da segurança.

Como de praxe, o SSH oferece uma resposta para o problema. Em vez de depender unicamente da senha como forma de autenticação, eu posso utilizar um par de chaves de autenticação, onde a chave pública é instalada nos servidores que serão acessados e a chave privada (que nunca sai da máquina) é protegida por uma passphrase, sem a qual a chave se torna inútil.

Nesse caso, terei uma segurança de dois níveis, em que é preciso saber a passphrase e, além dela, ter a chave privada, um arquivo salvo no HD ou em um pendrive, algo similar ao sistema bancário, onde eu preciso ter o cartão e saber a senha.

Para gerar o par de chaves, use (no cliente) o comando:

$ ssh-keygen -t rsa

Ele deve ser executado usando o login de usuário, não como root:

Generating public/private rsa key pair.
Enter file in which to save the key (/home/morimoto/.ssh/id_rsa):
Created directory ‘/home/morimoto/.ssh’.
Enter passphrase (empty for no passphrase): ********
Enter same passphrase again: ********
Your identification has been saved in /home/morimoto/.ssh/id_rsa.
Your public key has been saved in /home/morimoto/.ssh/id_rsa.pub.
The key fingerprint is:
ff:28:26:f6:87:67:9f:4c:9a:c8:0a:3b:21:81:88:b4 morimoto@athenas

A passphrase pode ser desde uma senha “normal”, com 8 ou 12 caracteres, até uma frase complexa, sem limite de tamanho; o importante é que não seja algo fácil de adivinhar. A passphrase é, na verdade, um componente da chave de encriptação; sem ela é impossível usar a chave.

O comando gerará os arquivos “.ssh/id_rsa” e “.ssh/id_rsa.pub” dentro do diretório home, que são, respectivamente, sua chave privada e sua chave pública. O “.ssh/id_rsa” é um arquivo secreto, que deve usar obrigatoriamente o modo de acesso “600” (que define usando o chmod), para evitar que outros usuários da máquina possam lê-lo. Muitos servidores recusam a conexão caso os arquivos estejam com as permissões abertas.

Depois de gerar o par de chaves, falta o comando final, que instala a chave pública no servidor, permitindo que ela seja usada para autenticação:

$ ssh-copy-id -i ~/.ssh/id_rsa.pub login@servidor

Como o nome sugere, o comando “ssh-copy-id” copia minha chave pública, instalando-a no servidor. Ao usá-lo, substitua o “login” pelo login de usuário e o “servidor” pelo endereço IP ou o domínio do servidor.

Ao ser executado, ele abrirá uma conexão via SFTP (ainda utilizando login e senha de acesso), que é usada para instalar a chave pública (o arquivo “.ssh/id_rsa.pub”, dentro do meu home) no diretório correspondente do servidor. Naturalmente, para que a transferência funcione, é necessário que o SFTP esteja ativo na configuração do servidor.

Caso eu utilize o mesmo login de usuário nas duas máquinas (usa o usuário “ecouto” em ambas, por exemplo), pode omitir o login no comando, digitando apenas “ssh-copy-id servidor”, como em:

$ ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.0.1

A partir daí, ao invés de pedir a senha, o servidor envia um “desafio” encriptado usando a chave pública. Para respondê-lo, o cliente SSH na máquina precisa usar a chave privada, que por sua vez precisa ser destravada usando a passphrase. Mesmo que alguém consiga roubar sua chave privada, não conseguirá conectar sem saber a passphrase e vice-versa.

Em resumo, o que o ssh-copy-id faz nada mais é do que copiar o conteúdo do arquivo “.ssh/id_rsa.pub”, dentro do diretório home, para o arquivo “.ssh/authorized_keys” dentro do diretório home do servidor remoto, uma operação que também pode ser realizada manualmente em caso de problemas.

O arquivo “.ssh/id_rsa.pub” é composto por uma única (e longa) linha, que contém sua chave pública de encriptação. Ela segue este padrão:

ssh-rsa AAAA(muitos caracteres)6lYzxBpu6M3Moe4HXaTs=

login@nomedamaquina”

Eu também posso instalar a chave manualmente simplesmente logando-se na máquina remota via SSH e copiando a linha para dentro do arquivo “.ssh/authorized_keys”, o que pode ser feito copiando e colando o texto através de qualquer editor que suporte esta função, como o joe ou o vi. No final, o arquivo “.ssh/authorized_keys” da máquina remota (dentro do home) terá o mesmo conteúdo do arquivo “.ssh/id_rsa.pub” da sua máquina, o que orienta o servidor remoto a passar a checar sua chave privada e a passphrase, ao invés de pedir senha.

Concluindo, depois de gerar a chave e conseguir se conectar através dela, eu também posso desativar a possibilidade de fazer logins normais, usando senha. Nesse caso, apenas eu, que possuo a chave gerada, conseguirá se conectar ao servidor.

Outras pessoas, mesmo que descubram a senha de alguma das contas, não terão como se conectar e nem como instalar uma nova chave para fazê-lo, a menos que tenham acesso físico ao servidor, a fim de copiar a chave manualmente. Isso significa que, mesmo alguém com a senha de root do meu servidor em mãos não conseguirá fazer nada remotamente. Isso pode ser usado para incrementar a segurança.

Para isso, mudei as opções “PasswordAuthentication” e “UsePAM” para “no” no arquivo “/etc/ssh/sshd_config” do servidor:

PasswordAuthentication no
UsePAM no

A opção “PasswordAutentication no” permite desativar o uso das senhas, como esperado, enquanto a “UsePAM no” reforça a configuração, desativando qualquer outra forma de autenticação com exceção das chaves.

Para que as alterações entrem em vigor, eu reiniciei o servidor SSH:

# /etc/init.d/ssh restart

ou:

# service sshd restart

Usando o ForwardAgent

Ao usar o ssh-agent para guardar suas passphrases, eu poderei ativar a opção ForwardAgent (no cliente) para permitir que o agente disponível na minha máquina possa ser usado para abrir novas sessões SSH quando estiver logado em outras máquinas.

Imagine que eu administro dois servidores remotos: servidor A e servidor B. Onde eu instalei a chave pública em ambos e armazenei na minha passphrase no ssh-agent, de forma que eu posso logar em ambos a partir da minha máquina, sem digitar senha. Porém, se eu estiver logado no servidor A, e precisar copiar um arquivo via sftp para o servidor B, eu irei precisar fornecer a senha ou passphrase, já que o servidor A não tem acesso à minha chave privada, que está no meu micro.

O ForwardAgent resolve isso, permitindo que a partir da sessão aberta no servidor A, eu possa se conectar no servidor B diretamente, sem precisar fornecer nem a senha nem a passphrase. Isso é feito de forma segura, criando um túnel temporário, diretamente entre a sua máquina e o servidor B, fazendo a verificação da chave através dele, sem passar pelo servidor A. Desta forma, não existe a possibilidade de um keytrap, ou qualquer armadilha instalada no servidor A, ser usada para capturar minha chave ou meu passphrase. Veja só:

$ ssh gnulinuxbr.com.br

ecouto@gnulinuxbr:~$ sftp gnulinuxbr.wordpress.com.br
Connecting to gnulinuxbr.wordpress.com.br…
sftp>

Nesse exemplo, me conectei ao servidor “gnulinuxbr.wordpress.com” e, a partir dele, abri uma conexão via sftp com o “gnulinuxbr.wordpress.com”, que poderia utilizar para transferir arquivos diretamente entre os dois. Veja, que graças ao trabalho do ForwardAgent, a segunda conexão foi aberta diretamente, sem que precisasse digitar nenhuma informação adicional.

Para ativar este recurso, abra o arquivo “/etc/ssh/ssh_config” (no cliente) e adicione a opção:

ForwardAgent yes

Práticas dirigidas

1

1

2

2

3

3

4

4