(Parte 1 de 5)

Dominando o SSH

O SSH é a minha ferramenta preferida. Ele permite administrar máquinas remotamente, executando inclusive aplicativos gráficos, permite transferir arquivos de várias formas diferentes e, como se não bastasse, permite também encapsular outros protocolos, permitindo, por exemplo, acessar uma sessão do VNC através de um túnel seguro.

A grande vantagem do SSH sobre outras ferramentas de acesso remoto é a grande ênfase na segurança. Um servidor SSH bem configurado é virtualmente impenetrável e você pode acessá-lo de forma segura, mesmo que a sua rede local esteja comprometida. Ele utiliza um conjunto de técnicas de criptografia para assegurar que apenas as pessoas autorizadas terão acesso ao servidor, que todos os dados transmitidos sejam impossíveis de decifrar e que a integridade da conexão seja mantida.

São previstas respostas para diversos tipos de ataques conhecidos. O SSH detecta casos em que o servidor tenha sido substituído por outra máquina, situações nas quais se tenta injetar dados na conexão, ou seja, tirar proveito de uma conexão aberta para incluir pacotes com comandos adicionais e inclui até mesmo técnicas de "despiste", que tornam muito mais complicado descobrir em qual pacote encriptado foi transmitida a senha de acesso, por exemplo, dificultando a vida de quem pretende descobrir a senha usando um ataque de força-bruta.

A idéia central é que, mesmo em situações onde seja fácil interceptar a transmissão (como no caso de uma rede wireless pública), seja impossível descobrir o conteúdo dos pacotes, devido à encriptação. É possível, ainda, utilizar um par de chaves ao invés de uma simples senha como forma de autenticação. Nesse caso, além da chave (um arquivo salvo no HD, pendrive ou smartcard), é preciso saber a passphrase, que pode ser uma senha especialmente longa e difícil de adivinhar.

Qualquer algoritmo de encriptação pode ser quebrado via força bruta, onde simplesmente são testadas todas as possibilidades possíveis, até encontrar a combinação correta. Porém, isso só é realmente possível para chaves de 40 ou no máximo 64 bits; acima disso é inviável, pois a cada bit adicionado, o processo torna-se exponencialmente mais demorado.

O WEP de 64 bits (que na verdade utiliza uma chave de 40 bits), usado em redes wireless pouco protegidas, pode ser quebrado em pouco tempo, caso você consiga capturar um volume considerável de transmissões usando um sniffer. O DES, um dos algoritmos mais tradicionais, que usa chaves de 64 bits (reais), pode ser quebrado em alguns dias, caso você tenha acesso a um cluster de 100 máquinas Athlon 64.

Uma chave de 64 bits é cerca de 16 milhões de vezes mais difícil de quebrar via força bruta do que uma de 40 bits, como as que eram utilizadas no SSL dos navegadores a até poucos anos atrás. Uma chave de 128 bits por sua vez, é (arredondando) 18.447.0.0.0.0.0 vezes mais demorada de quebrar que uma de 64 bits, de forma que, uma chave de 64 bits pode ser quebrada caso você tenha o tempo e os recursos necessários à disposição, mas uma de 128 (sem brechas conhecidas) é impossível de quebrar com tecnologia atual.

O perigo no caso dos algoritmos de encriptação é quando são descobertas falhas que permitam descobrir a chave usada em menos tempo. As versões originais do WEP, por exemplo, podiam ser quebradas rapidamente devido a um conjunto de falhas no algoritmo usado, o que levou os fabricantes a atualizarem rapidamente todos os seus produtos. Outro exemplo é o sistema usado na encriptação dos DVDs, que é quebrado em poucos segundos por uma máquina atual, utilizando um algoritmo de poucas linhas.

Felizmente, este não é o caso dos algoritmos usados no SSH. Por serem abertos, qualquer falha similar que pudesse eventualmente existir já teria sido descoberta e corrigida. O SSH é usado em tantos servidores importantes que uma brecha grave poderia (literalmente) parar o mundo. Por isso, todo o código é exaustivamente auditado por uma variedade de empresas e órgãos governamentais.

O SSH utiliza chaves assimétricas para fazer a autenticação. As chaves assimétricas são um sistema muito interessante, onde temos um par de chaves. Uma (a chave pública), permite apenas encriptar dados, enquanto a segunda (a chave privada) permite desencriptar as informações embaralhadas pela primeira.

Quando você se conecta a um servidor SSH, seu micro e o servidor trocam suas chaves públicas, permitindo que um envie informações para o outro de forma segura. Através deste canal inicial é feita a autenticação, seja utilizando login e senha, seja utilizando chave e passphrase (como veremos a seguir).

Até aqui, tudo é feito utilizando chaves de 512 bits ou mais (de acordo com a configuração). O problema é que, embora impossível de quebrar, este nível de encriptação demanda uma quantidade muito grande de processamento. Se todas as informações fossem transmitidas desta forma, o SSH seria muito lento.

Para solucionar este problema, depois de fazer a autenticação, o SSH passa a utilizar um algoritmo mais simples, que demanda muito menos processamento, para transmitir os dados. Por padrão é utilizado o 3DES (triple-DES), que utiliza uma combinação de três chaves DES, de 64 bits cada. As chaves são trocadas periodicamente durante a conexão, o que torna o sistema quase impossível de quebrar. Na configuração do servidor e/ou cliente, é possível especificar outro algoritmo, como o Blowfish. Isso garante uma boa relação entre segurança e desempenho.

O SSH é dividido em dois módulos. O sshd é o módulo servidor, um serviço que fica residente na máquina que será acessada, enquanto ossh é o módulo cliente, um utilitário que você utiliza para acessá-lo.

Nas distribuições derivadas do Red Hat, o servidor SSH é instalado através do pacote "openssh-server" e o cliente, através do "openssh-clients". No Debian, ambos são instalados através do pacote "ssh". Com o pacote instalado, você inicia o servidor usando o comando "service sshd start" (nos derivados do Red Hat), ou "/etc/init.d/ssh start", no caso do Debian. Para que ele seja inicializado durante o boot, use respectivamente o "chkconfig sshd on" ou "update-rc.d -f ssh defaults".

A partir daí as coisas se unificam. A configuração do servidor, independentemente da distribuição usada, vai no arquivo "/etc/ssh/sshd_config", enquanto a configuração do cliente vai no "/etc/ssh/ssh_config". Note que muda apenas um "d" entre os dois, cuidado para não confundir cará com inhame ;).

Note que além do OpenSSH, que abordo aqui, existem outras versões do SSH, como o Tectia (uma versão comercial, disponível no http://ssh.com) e o SunSSH que, embora conservem diferenças no funcionamento e na configuração, são compatíveis entre si. O SSH é, na verdade, um protocolo aberto e não o nome de uma solução específica.

Configuração do cliente

Ao ser habilitado, o padrão do servidor SSH é permitir acesso usando qualquer uma das contas de usuário cadastradas no sistema, pedindo apenas a senha de acesso. Para acessar o servidor "192.168.0.2", usando o login "morimoto", por exemplo, o comando seria:

Ao invés de usar a arroba, você pode também especificar o login usando o parâmetro "- l" (de login), como em:

$ ssh -l morimoto 192.168.0.2 Você pode também acessar o servidor usando o nome ou domínio, como em: $ ssh morimoto@web.kurumin.com.br

Caso você omita o nome do usuário, o SSH presume que você quer acessar usando o mesmo nome de usuário que está usando na máquina local. Se você está logado como "tux", ele tentará fazer login usando uma conta "tux" no servidor remoto. Naturalmente, só funciona caso você use o mesmo login em ambas as máquinas.

Ao acessar micros dentro da rede local, você pode também chamá-los pelo nome, como em "ssh morimoto@servidor". Neste caso, você precisará primeiro editar o arquivo /etc/hosts (no cliente), incluindo os números de IP das máquinas e os nomes correspondentes. O formato deste arquivo é bem simples, basta fornecer o IP e o nome da máquina correspondente, um por linha, como em:

- Verificação do servidor: Como parte das verificações de segurança, o SSH utiliza também um sistema baseado em chaves assimétricas para verificar a identidade do servidor. O servidor tem uma chave pública, que envia ao cliente na primeira conexão. As identificações de todos os servidores conhecidos ficam armazenadas no arquivo

".ssh/known_hosts" dentro do seu diretório home. Sempre que você se conecta daí em diante, o cliente SSH envia um "desafio" ao servidor, uma frase encriptada usando a chave pública, que só pode ser descoberta usando a chave privada.

Isso previne um tipo de ataque muito comum chamado "man in the middle" (que poderia ser traduzido para "intermediário", ou "impostor"), em que alguém simplesmente substitui o servidor por outra máquina, usando o mesmo IP, ou sabota o servidor DNS da rede (ou do provedor) de forma que ele entregue um IP forjado quando você tenta acessar seu servidor baseado no domínio.

O servidor falso pode ser configurado para gravar sua senha e responder com uma mensagem do tipo "O servidor está em manutenção, tente novamente daqui a algumas horas". Dessa forma, ele vai ter não apenas acesso à sua senha, mas tempo para usá-la para acessar o servidor verdadeiro sem que você desconfie. Por sorte, o SSH percebe que a identificação do servidor mudou e lhe avisa do problema:

Para continuar é preciso que você edite manualmente o arquivo ".ssh/known_hosts", dentro do home e remova a linha com a antiga identificação do servidor, deixando as demais. Da próxima vez que tentar se conectar, o SSH exibe uma mensagem mais simpática, perguntando se você quer adicionar a nova chave:

Não existe forma de fazer com que o cliente SSH adicione as novas chaves automaticamente, isso seria uma brecha de segurança. É sempre preciso primeiro remover a chave antiga no arquivo "~/known_hosts" manualmente.

As chaves são geradas durante a instalação do SSH e salvas nos arquivos "/etc/ssh/ssh_host_rsa_key" e "/etc/ssh/ssh_host_dsa_key" (no servidor). Para não disparar o alarme nos clientes quando precisar reinstalar o servidor, salve os dois arquivos em um pendrive e restaure-os depois da instalação. Você pode fazer isso mesmo ao migrar para outra distribuição, pois as localizações dos dois arquivos não mudam.

Uma opção, seria desabilitar a checagem das chaves, adicionando a linha "StrictHostKeyChecking no" na configuração dos clientes. Contudo, isso não é recomendável, pois desabilita completamente a checagem, abrindo brechas para ataques.

- Compressão: No caso de servidores acessíveis via internet, você pode reduzir um pouco o consumo de banda ativando a compressão de dados via gzip, o que é feito adicionado a linha:

Compression = yes

Você pode também ativar a compressão adicionando a opção "-p" na hora de se conectar. Quase todas as opções do cliente SSH podem ser especificadas tanto no arquivo, quanto via linha de comando.

- Aplicativos gráficos: Além de oferecer acesso via linha de comando, o SSH permite rodar aplicativos gráficos remotamente (X11 forwarding). Algumas distribuições, como o Slackware, trazem o recurso desabilitado por padrão. Nestes casos, edite o arquivo "/etc/ssh/ssh_config" (a configuração do cliente) e substitua a linha "ForwardX11 no" por:

ForwardX11 yes

Outra opção é adicionar o parâmetro "-X" ao se conectar, como em "ssh -X tux@192.168.0.1". A partir daí, você pode chamar os aplicativos gráficos normalmente, como se estivesse num terminal local.

O maior problema com o uso de aplicativos remotos via SSH é que ele só funciona satisfatoriamente via rede local. Via internet os aplicativos gráficos ficam realmente muito lentos (mesmo em uma conexão de 1 ou 2 megabits), pois o protocolo do X é otimizado para uso local, com uso intensivo de pacotes de retorno e sem nenhum tipo de cache. Isso faz com que muitos administradores desabilitem o X11 forwarding no próprio servidor.

Para rodar aplicativos gráficos de forma segura via internet, a melhor solução é usar o NX Server. Ele é um sistema de acesso remoto baseado no SSH, que utiliza um protocolo bastante otimizado. Nele você tem um desktop completo (similar ao VNC), mas com um desempenho muito superior, mesmo em conexões via modem.

- Keep Alive: Concluindo a configuração do cliente, outro problema comum é a conexão ser fechada pelo servidor depois de alguns minutos de inatividade. Em muitas situações você quer manter a conexão aberta por longos períodos, sem precisar ficar dando um "ls" a cada dois minutos para manter a conexão aberta. Você pode evitar o problema fazendo com que o próprio cliente mande pacotes periodicamente a fim de manter a conexão aberta. Para ativar isso, adicione a linha abaixo no "/etc/ssh/ssh_config":

ServerAliveInterval 120

Este é um exemplo de arquivo "/etc/ssh/ssh_config" configurado com as opções que vimos até aqui (excluindo os comentários):

ForwardX11 yes Compression = yes Port 2 ServerAliveInterval 120

Configuração do servidor

Você pode configurar várias opções relacionadas ao servidor SSH, incluindo a porta TCP a ser usada editando o arquivo "/etc/ssh/sshd_config". A maior parte das opções dentro do arquivo podem ser omitidas, pois o servidor simplesmente utiliza valores defaults para as opções que não constarem no arquivo. Mas, de qualquer forma, é saudável especificar todas as opções que conhece: além de evitar enganos, é uma forma de praticar e memorizar as opções.

- Porta: Uma das primeiras linhas é a: Port 2

Esta é a porta que será usada pelo servidor SSH. O padrão é usar a porta 2. Ao mudar a porta do servidor aqui, você deverá usar a opção "-p" ao conectar a partir dos clientes, para indicar a porta usada, como em:

Outra opção é editar o arquivo "/etc/ssh/ssh_config" (nos clientes) e alterar a porta padrão usada também por eles. Mudar a porta padrão do SSH é uma boa idéia se você está preocupado com a segurança. Muitos dos ataques "casuais", quando não existe um alvo definido, começam com um portscan genérico, onde é feita uma varredura em faixas inteiras de endereços IP, porém apenas em algumas portas conhecidas, como a 21, 2 e 80 (a fim de tornar o teste mais rápido, embora menos preciso).

A partir daí, os ataques vão sendo refinados e direcionados apenas para os servidores vulneráveis encontrados na primeira varredura. Colocar seu servidor para escutar uma porta mais escondida, algo improvável como a porta 32456 ou 54232, já dificulta um pouco as coisas.

(Parte 1 de 5)

Comentários