Introdução
Praticamente todos os servidores baseados em UNIX possuem um servidor SSH para permitir a administração remota pela internet. De tempos em tempos, pode-se notar um grande número de falhas de logins. Geralmente, essas falhas são ataques do tipo força-bruta contra o seu servidor SSH. Mostrarei aqui algumas dicas para a proteção de máquinas rodando SSH daemons contra ataques desse tipo.
Mudar a porta padrão
Configure seu SSH daemon para escutar em uma porta que não seja comum. Servidores SSH não apresentam nenhum problema ao fazer isso. Apenas esteja certo de que seu firewall permita conexões para a nova porta. Por exemplo, para que seu SSH daemon aceite conexões na porta 2222, edite o aqruivo sshd_config e modifique o valor de Port para 2222 e reinicie-o.
Esse método impede o sucesso de hackers que só procuram por servidores SSH na porta padrão, mas qualquer “scanner” de portas mais avançado pode descobrir a porta. De qualquer maneira, isso deve reduzir dramaticamente o número de ataques do tipo SSH força-bruta.
Senhas fortes
Certifique-se que todos os usuários possuam senhas fortes, ou seja, que não haja nenhuma senha de dicionário ou suas variações. Um método simples é utilizando as iniciais de uma frase qualquer, por exemplo: Denise e Paulo foram viajar para Buenos Aires (DePfvpBA). Uma vantagem é que esse método é fácil de implementar, porém requer a checagem da senha de todos os usuários regularmente (utilizando por exemplo o “John the Ripper”). Além disso, essa solução não diminui a carga causada pelos ataques.
Desabilitar acesso de root
Se o acesso de root em seus servidores for permitido, você deve desabilitá-lo. Ainda será possível entrar como um usuário sem privilégios e se tornar super-usuário.
Autenticação RSA
Se você não usa senhas, apenas chaves RSA para autenticação, um ataque do tipo força-bruta por senhas válidas é obviamente inútil. Para fazer isso, siga os passos abaixo:
(1) Gere uma chave RSA com ssh-keygen -t rsa. Isso irá criar os arquivos /home/nome_do_usuário/.ssh/id_rsa (a chave privada) e /home/nome_do_usuário/.ssh/id_rsa.pub (a chave pública).
sh$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/username/.ssh/id_rsa.
Your public key has been saved in /home/username/.ssh/id_rsa.pub.
The key fingerprint is: 32-digit_hexadecimal_fingerprint username@hostname
(2) Em cada máquina para qual você quiser logar, coloque /home/nome_do_usuario/.ssh/id_rsa.pub em /home/nome_do_usuario/.ssh/authorized_keys. Esse arquivo pode conter mais de uma chave, podendo ser concatenada a chave que acabou de ser gerada.
sh$ cat /home/username/.ssh/id_rsa.pub >> /home/username/.ssh/authorized_keys
(3) Em cada máquina de onde você quiser logar, coloque o arquivo /home/nome_do_usuario/.ssh/id_rsa no diretório /home/nome_do_usuario/.ssh/.
(4) Desabilite o login baseado em senhas setando 'PasswordAuthentication no' em /etc/ssh/sshd_config, e reinicie o sshd daemon com /etc/init.d/sshd restart.
Se feito corretamente, essa é uma alternativa bem segura. Algumas desvantagens:
- Usuários podem usar chaves privadas sem setar uma senha para protegê-la. Isso implica que tendo acesso à chave privada, seria possível fazer o login em qualquer máquina que tiver a chave pública correspondente instalada.
- Usuários menos experientes precisariam de ajuda para gerar e usar a sua chave RSA.
- É necessário ter sempre a chave privada consigo para fazer o login de um outro host.
Usando iptables
É possível alterar regras do iptables para bloquear ataques ssh. A regra abaixo (encontrada no blog do Andrew Pollock) permite no máximo 3 conexões por minuto por qualquer host, e bloqueia o host por um minuto se essa taxa é excedida.
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set \
--name SSH -j ACCEPT iptables -A INPUT -p tcp --dport 22 -m recent --update --seconds 60 --hitcount 4 --rttl \
--name SSH -j LOG --log-prefix "SSH_brute_force "
iptables -A INPUT -p tcp --dport 22 -m recent --update --seconds 60 \
--hitcount 4 --rttl --name SSH -j DROP
Para utilizar uma whitelist, uma possível variação poderia ser feita:
(1) Criar uma cadeia personalizada para a whitelisting
iptables -N SSH_WHITELIST
(2) Adicione qualquer host que desejar
iptables -A SSH_WHITELIST -s HOST_CONFIAVEL -m recent --remove --name SSH -j ACCEPT
(3) Adicione as regras para bloqueio
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set \
--name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSH_WHITELIST
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update \
--seconds 60 --hitcount 4 --rttl --name SSH -j ULOG --ulog-prefix SSH_brute_force
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update \
--seconds 60 --hitcount 4 --rttl --name SSH -j DROP
Usando ferramentas anti-força-bruta
É possível procurar nos logs do sshd daemon por possíveis ataques, e bloqueá-los. Há vários programas/scripts disponíveis para isso:
ssdfilter
Utiliza iptables para o bloqueio (adicionando regras personalizadas para bloquear um atacante específico). Você deve executar o sshdfilter ao invés do sshd. Sshdfilter irá então iniciar o sshd e monitorar o seu log.
http://www.csc.liv.ac.uk/~greg/sshdfilter/
Fail2Ban
É um script feito em Python que adiciona regras de firewall para bloquear um ataque. Ele pode usar iptables, ipfwadm, ou ipfw.
http://fail2ban.sourceforge.net/
DenyHosts
DenyHosts é um script feito para administradores de sistemas Linux para proteger contra ataques do tipo SSH força-bruta. Ele observa as tentativas de login para o servidor, e se for detectado um possível ataque, adiciona o IP em /etc/hosts.deny. O DenyHosts requer um sshd daemon compilado com suporte para tcp_wrappers (padrão na maioria das distribuições Linux). Como Fail2Ban, DenyHosts é feito em python.
http://denyhosts.sourceforge.net/
pam_abl
É um módulo PAM (Pluggable Authentication Module) que oferece blacklist automático de hosts e usuários responsáveis por repetidas falhas em tentativas de autenticação. É geralmente configurado para que os usuários que estão na blacklist vejam a requisição de login, mas que não consigam autenticar.
http://sourceforge.net/projects/pam-abl
IPTables Recent Module
Esse módulo do kernel do Linux é extremamente útil para construir uma lista temporária de endereços IP que atacam seu servidor SSH por força-bruta, e banir tudo o que vier deles por determinada quantidade de tempo.
http://snowman.net/projects/ipt_recent/
Brute-Force Detection
BFD é um shell script para analisar logs e checar por falhas de autenticação. Ele bloqueia o endereço IP usando regras de firewall.
http://www.rfxnetworks.com/bfd.php
sshd_sentry
SSH Sentry é um script feito em Perl que monitora logs de servidores SSH, detecta falhas de login repetidas e adiciona o host em uma lista negra.
http://linuxmafia.com/pub/linux/secu...ry/sshd_sentry
SSHGuard
Protege redes contra ataques do tipo força-bruta contra servidores SSH. Ele detecta os ataques e bloqueia o endereço do host utilizando regras de firewall.
http://sshguard.sourceforge.net/
Usando TCP_Wrappers para bloquear
Na seção anterior, foi apresentado o script DenyHosts, que escaneia os logs do sshd para detectar um ataque, e então o bloqueia com uma regra em /etc/hosts.deny. Todavia, não é necessário escanear os logs. É possível fazer com que a biblioteca tcp_wrappers inicie um script sempre que uma conexão é feita, e deixar o script adicionar regras no /etc/hosts.deny ou /etc/hosts.allow.
(1) Faça o download do shell script sshblock.sh, e copie-o para /usr/local/bin/sshblock.sh (ou onde desejar). http://la-samhna.de/misc/sshblock.sh
(2) Torne-o executável com o comando chmod 755 /usr/local/bin/sshblock.sh
(3) Adicione as próximas três linhas no final do /etc/hosts.allow
#__START_SSHBLOCK__
#__END_SSHBLOCK__
sshd : ALL : spawn (/usr/local/bin/sshblock.sh %a)&
Isso irá chamar o script /usr/local/bin/sshblock.sh para cada conexão ssh. O script recebe o endereço IP remoto como primeiro e único argumento. Ele, então, escreve em um arquivo temporário /root/hosts.allow, e o copia para /etc/hosts.allow se houver alguma diferença entre eles.
Configuração: No topo do script, há quatro variáveis que podem ser setadas: DONTBLOCK é o prefixo de um bloco endereços que nunca deverão ser bloqueados (seu próprio domínio). O padrão é 192.168, o qual você pode manter se você não tiver seu próprio domínio, pois é um bloco “privado”. BURST_MAX é o número máximo de conexões de um host em BURST_TIM segudos que são permitidas (padrão: 5 em 60 segundos). Os bloqueios são removidos depois de PURGE_TIM segundos. No script é assim:
# your own domain
DONTBLOCK=192.168
# block host if more than BURST_MAX connections within BURST_TIM seconds
BURST_MAX=5
BURST_TIM=60
# remove block after PURGE_TIM seconds
PURGE_TIM=3600
Desvantagens:
- Não diferencia entre tentativas de login com sucesso e sem sucesso.
- Para desbloquear um host, o script deve ser executado, o que requer uma conexão de um host não-bloqueado. (Ou crie uma entrada no cron que chame o script com o parâmetro 127.0.0.0 uma vez a cada hora).
Port Knocking
Como anunciado por Imre Veres, outra solução para o problema, é usando o knockd, que elimina a necessidade de ter o ssh escutando em uma porta aberta.
Knockd procura padrões pré-definidos no log do iptables, por exemplo, uma tentativa na porta 6356, outra na porta 9356, e duas na porta 3356 seriam equivalentes a bater em uma porta fechada com um código que é reconhecido pelo knockd. Knockd, então, usa iptables para abrir uma porta pré-definida (ex: tcp/22 para sshd) por um tempo pré-definido (ex: um minuto). Se uma sessão ssh é aberta dentro daquele intervalo de tempo, ela continuará aberta, embora a porta do ssh fechará depois que o tempo pré-definido expirar.
Kevin Hilton recomenda fwknop baseando-se no fato de que é muito mais sofisticado, muito fácil de instalar, permite criptografia, aleatoriza a porta de origem, e tem suporte.
Micheal Rash enfatiza que fwknop suporta “Single Packet Authorization”, que não sofre de ataques que monitoram o tráfego, mencionado abaixo em “Desvantagens”.
Vantagem:
- É bastante seguro, se o atacante não puder monitorar seu tráfego.
Desvantagens:
- É um pouco complicado, não sendo muito adequado para “meros mortais”.
- Requer o programa adequado (ex: knockd-client) para o “port knocking” no cliente (assim como knockd no servidor).
- É muito fácil detectar padrões no tráfego de 'portknocks seguidos de conexões ssh', quando um atacante pode monitorar seu tráfego. Simples “portknocking” não oferece segurança contra atacantes que podem espiar na rede interna. Esse problema é resolvido pelo “Single Packet Authorization” no fwknop.
Referências
link1
Autor: Felipe Martim Fernandes Vieira


Responder com Citação