Introdução
Acredito que o SSH não precise ser apresentado e tampouco detalhes de sua instalação. Até porque em praticamente todas as instalações ele já vem instalado por padrão, seja o cliente ssh ou o servidor. Em algumas o servidor precisa ser explicitamente instalado, como é o caso do Ubuntu. Mas não se apresse, é provável que você não precise de um servidor SSH em seu console, já que este é um recurso desejável justamente em servidores.
O SSH funciona sobre o protocolo SSL, da mesma forma que o HTTPS. Como o uso do SSH é feita por administradores e não por usuários leigos, é extremamente incomum o uso de certificados digitais neste caso. Afinal um administrador de redes experiente não irá cair na pegadinha do ataque do homem do meio (onde uma outra máquina se faz passar pelo teu servidor). Durante o primeiro acesso seria prudente que o cliente verificasse se realmente é o servidor. Observe no exemplo a seguir as mensagens gerados pelo servidor no primeiro acesso: $ ssh [email protected] RSA key fingerprint is ff:7b:35:74:cd:4c:59:0b:4b:b5:cf:fe:eb:f4:ec:7a. Are you sure you want to continue connecting (yes/no)? yes Observe que ele lhe pede que confirme que este é mesmo o servidor. Neste ponto, se tiver certeza (e pode verificar o fingerprint), ao digitar “yes” a chave do servidor será armazenada em ~/.ssh/know_hosts. A partir deste momento, nenhuma outra mensagem de aviso ocorrerá, salvo se o servidor for reinstalado ou se estiver mesmo sobre um ataque do homem do meio. Mas aí a mensagem será de recusar a conexão. Meu objetivo não é exatamente descrever o SSH em si, mas sim alguns recursos pouco usados do mesmo. Um deles é o login por desafio/resposta usando uma chave pública e privada. |
|
Como funciona o desafio resposta
Basicamente consiste em o servidor enviar um desafio para você que somente você poderia resolver. Se você acertar o desafio, passou no teste e pode autenticar-se.
Para explicar melhor o que é o desafio resposta, costumo usar um exemplo didático, porém extremamente fraco. Serve para explicar a ideia, mas não deve jamais ser usado por ser frágil. Suponha que o cliente possua um segredo que é um número inteiro. Podemos chamá-lo de senha. O servidor conhece este segredo e permitirá login para qualquer um que provar conhecê-lo. A autenticação poderia ser da forma clássica:
Porém o método anterior possui um problema: a senha é enviada pela rede e alguém poderá capturar ela e se logar no futuro como sendo o cliente. A mesma solução anterior, porém baseada em desafio e resposta, poderia ser:
Pode parecer a mesma coisa, mas a ideia é que a expressão matemática mude aleatoriamente a cada solicitação. Se alguém estiver capturando o tráfego não poderá usar a resposta em um login futuro, pois o servidor irá solicitar outra expressão matemática. Esta expressão pode ser uma simples multiplicação, como demonstra a figura: O exemplo da figura anterior ilustra como é a técnica, mas não deve ser usado. Isto porque um atacante conseguirá descobrir muito facilmente a chave, bastando dividir 4305 por 123, pois ele viu o desafio e viu a resposta. Operações matemáticas que possam ser revertidas não devem ser usadas (divisão reverte a multiplicação, soma reverte a subtração). Se usar outra operação mais complexa que não possa ser desfeita e com números realmente muito grandes a técnica poderá ser usada. Um exemplo de uma operação matemática irreversível é a de módulo, usada no RSA. Apesar de fugir um pouco do foco deste artigo, pois ainda está na minha gaveta um artigo sobre RSA, vale o exemplo: O exemplo anterior ainda não pode ser usado. Poderia se os números fossem realmente grandes, com um X em torno de 512 bits de tamanho e o desafio também. Com números pequenos um ataque de força bruta seria possível, isto é, o atacante tentaria todos os possíveis valores de X até achar um que encaixe na expressão. Já me estendi demais neste conceito, já que o objetivo era apenas explicar o princípio do desafio e resposta. No que diz respeito ao ssh, o desafio e resposta é baseado em chaves públicas e privadas. |
|
Desafio e resposta no ssh
O ssh é suficientemente seguro se bem usado. Se você tem certeza da idoneidade do servidor e se tem certeza de que realmente é o servidor, tudo bem. Não há qualquer problema você digitar sua senha de acesso. Ela não poderá ser lida por mais ninguém.
Isto porque toda a sessão ssh é protegida por um forte algoritmo de criptografia simétrico. Quando você digita sua senha ela é cifrada com este algoritmo e transmitida pela Internet. Alguém, em posição de capturar o tráfego, não conseguirá obter esta senha. Porém existe ainda uma forma de executar o login sem precisar enviar a senha. E uma forma segura. Mas porque não enviar a senha? Vários motivos. Primeiro uma segurança a mais, pois agora a senha sequer viaja pela Internet, nem mesmo cifrada. Na hipótese, mesmo remota, de alguém estar aplicando um ataque do homem do meio ou de que o servidor estar corrompido, o atacante realmente não terá sua senha, de forma alguma. Um segundo motivo pode ser a facilidade de manutenção. As vezes é chato ter que ficar colocando várias vezes a senha, principalmente se todos fizerem a coisa certa, de não usar a mesma senha em todos os servidores (por experiência pessoal, sou cético quanto a isto!). Para resolver este problema o ssh possui o login por desafio e resposta através do uso de um par de chaves pública e privada. Você primeiro deve criar um par de chaves para si, uma chave pública e privada. A chave privada você mantém em segredo, guarda-a em segurança. Já a chave pública você deposita no servidor e diz para o ssh aceitar conexões de qualquer um que prove ser o conhecedor da chave privada. O conceito dos algoritmos assimétricos garante que tudo que foi cifrado com a chave pública, apenas a chave privada poderá abrir. Assim o desafio gerado pelo servidor passa a ser o seguinte:
Este método é ainda melhor que o descrito antes, pois não envolve a senha do usuário em nenhum momento, apenas a chave privada dele. Esta chave passará a ser a parte sensível e deve ser protegida. Como ninguém conseguirá decorar uma chave de milhares de bits, ela precisa ser armazenada. Armazenar é um problema, pois pode-se supor até o roubo do HD onde um atacante teria a chave e se logaria em seus servidores. Para evitar isto, o ssh permite que você proteja sua chave com uma frase de passagem, que você poderá lembrar-se. Pode ser qualquer sequência de caracteres que será solicitada pelo seu programa cliente quando você fizer o login. |
|
Configuração do ssh para autenticação por desafio e resposta
A autenticação por desafio resposta no ssh deve estar habilitada no ssh server. Por minha experiência, todos os servidores ssh já vem com isto habilitado, mas convém verificar. Apenas verifique se a informação PubkeyAuthentication no /etc/ssh/sshd_config não está em “no”. Normalmente ela está comentada no arquivo, o que significa que está ativa (o padrão é permitir):
# grep Pubkey /etc/ssh/sshd_config Se ela estiver comentada ou com “yes”, tudo bem. Mas se estiver com “no”, comente a regra ou mude para “yes” e reinicie o ssh server. Com o servidor configurado para aceitar esta forma de autenticação, deve-se ainda realizar os seguintes passos:
Usarei o usuário fulano como teste neste artigo. Criação do par de chavesUsuário fulano tem um login e senha no servidor 10.2.3.4. O cliente é a máquina didaké (nome do meu notebook). Primeiro ele se logou com seu usuário e senha, só para testar: $ ssh 10.2.3.4 Voltando a máquina cliente, a didaké, ele cria seu par de chaves com o ssh-keygen. Os parâmetros indicam criar chaves usando o algoritmo dsa e com 1024 bits de tamanho. Se você não especificar o DSA, o algoritmo RSA será usado. O protocolo RSA não é usado por padrão no ssh e não funcionará a menos que você coloque o parâmetro RSAAuthentication yes no /etc/ssh/sshd_config. Este é desabilitado por padrão. $ ssh-keygen -b 1024 -t dsa +--[ DSA 1024]----+ | o+..o.. | | ooo+. . | | .ooo.. . .| | o. . . o | | S o .| | o o o . | | + . . | | . o . | | o E | +-----------------+ Quando ele perguntar “Enter file in which to save the key (/home/fulano/.ssh/id_dsa): ” simplesmente dê um enter aceitando esta sugestão. Como frase de passagem eu coloquei “Viva o Linux 2009″. Pode ser qualquer coisa, mas tome cuidado pois você deve digitar exatamente a mesma coisa quando solicitado. Se digitar “Viva o LINUX 2009” já não será a mesma frase, pois Linux está tudo em caixa alta. Desaconselha-se deixar sem frase de passagem, mas é uma configuração possível. Instalação da chave pública no servidorA instalação da chave pública no servidor consiste em simplesmente colocar ela dentro do arquivo ~/.ssh/authorized_keys. Este arquivo pode ter várias chaves públicas, não apenas uma. Para realizar esta tarefa o usuário fulano precisará logar-se no servidor, usando ainda sua senha. A chave pública criada está em ~/.ssh/id_dsa.pub no cliente e home do fulano. Ela é texto puro (base64) logo pode-se até dar um cat nela: $ cat id_dsa.pub Não faça o mesmo para a chave privada, pois ela não é em formato texto, é binário. Então, basta pegar esta sequência esquisita de caracteres e copiá-la, assim como está, para o servidor. No Gnome pode-se até mesmo usar o recurso de copiar e colar do sistema, como demonstra a sequência de imagens. Selecionando a chave pública no cliente, arquivo ~/.ssh/id_dsa.pub e usando o “Copy” do próprio Gnome. Após, loga-se no servidor 10.2.3.4 ainda usando sua senha, e coloca-se a chave dentro do arquivo authorized_keys em ~/.ssh. No caso eu usei o simples cat com redirecionamento (cat >> authorized_keys). Ao final, após colar, deve-se pressionar Control+D e o arquivo está com a chave pública. Na imagem, após o término, executei um cat para verificar. Outras tantas formas podem ser usadas para obter-se o mesmo resultado, como simplesmente editar o arquivo authorized-keys com algum editor qualquer. O fato é que ele deve ter a chave pública. Por fim, após a instalação, pode-se verificar se está funcionando. fulano sai do servidor e tenta-se logar novamente: $ ssh 10.2.3.4 Agora ele pediu a frase de passagem que protege a chave pública. No caso eu tive que digitar o “Viva o Linux 2009” para poder me logar. |
|
Conclusão
O uso desta forma de autenticação é considerado mais seguro que com usuário e senha. Porém a maior vantagem, na minha opinião, é ser bem mais prático.
Prático porque você pode colocar senhas diferentes em seus servidores e logar-se neles apenas por desafio e resposta, decorando apenas a sua frase de passagem. Pode colocar sua chave pública em todas as máquinas Linux que você deseja acessar. Mais prático também porque hoje muitos chaveiros permitem armazenar a frase de passagem, solicitando-a apenas uma única vez por sessão e fazendo realmente um login sem senha nas conexões posteriores. É o caso do Gnome (e não uso KDE para testar). Muitas coisas fantásticas podem ser realizadas com esta técnica, algumas com bastante cuidado, evidente. Eu, por exemplo, em um curso de Linux, criei um par de chaves e o coloquei no /root/.ssh/authorized_keys de todas as máquinas dos alunos. Assim, a partir do meu notebook, eu podia executar remotamente qualquer comando nas máquinas e sem senha, pois usava o lembrete de senhas do Gnome. Para desligar uma máquina, bastou um: $ ssh [email protected] “/sbin/shutdown -h now” Isto dentro de um for, permite executar em todas as máquinas. Um exemplo mais interessante foi quando precisei que os alunos tivessem poderes de root as vezes, mas não sempre. Quando eu queria lhes dar esta permissão para todas as 20 máquinas, executava do meu notebook: $ for IP in `cat ubuntu.txt`; do E dentro do arquivo ubuntu.txt tinha os IPs dos clientes, um por linha (nota: no ubuntu o adduser pode ser usado para inserir um usuário já existente em um grupo). Se, depois, não quero mais que o usuário aluno tenha poderes de root, então: $ for IP in `cat ubuntu.txt`; do Isto porque no Ubuntu para poder usar o sudo basta estar no grupo admin (e no ubuntu o deluser pode ser usado para remover um usuário de um grupo. Nesta forma de uso, o usuário em si não é removido, apenas sai do grupo). Se você gerencia dezenas de máquinas pode ser extremamente criativo e deixar os scripts trabalharem por você. |