domingo, 19 de dezembro de 2010

Previna ataques de BruteForce em servidores Debian


Olá,

Hoje eu venho compartilhar um pouco de conhecimento.

Meu objetivo com essa postagem é mostar como evitar ataques de Brute Force (força bruta) em serviços como SSH e FTP que usam os arquivos
contidos em
/etc/hosts.allow ou /etc/hosts.deny e serviços que nao usam TCP_WRAPPERS, como o pacote ProFTPd do Debian.
Os demais serviços que nao usam /etc/hosts.allow ou /etc/hosts.deny nao serao tratados pois podem ser bloqueados com o iptables.

Presumo que o OpenSSH e o ProFTPd estao devidamente instalados e rodando no seu sistema.

=> PRIMEIRO PASSO
Instalar o Pyton, pois o BlockHosts é escrito nessa linguagem.

aptitude install python

Depois de instalar o Pyton, vamos baixar com os seguintes comandos:

wget http://www.aczoom.com/tools/blockhosts/BlockHosts-2.5.0.tar.gz tar xvfz BlockHosts-2.5.0.tar.gz cd BlockHosts-2.5.0
Para instalar o BlockHosts, use:

python setup.py install --force

Depois de instalado, edite o /etc/clockhosts.cfg e modifique como o exemplo a seguir:

nano /etc/blockhosts.cfg

[...]
HOSTS_BLOCKFILE = "/etc/hosts.allow"
[...]
HOST_BLOCKLINE = ["ALL: ", " : deny"]
[...]
COUNT_THRESHOLD = 3
[...]
AGE_THRESHOLD = 12
[...]
LOGFILES = [ "/var/log/auth.log", "/var/log/proftpd/proftpd.log", ]
[...]
MAIL = True
[...]
NOTIFY_ADDRESS = 'root@localhost.localdomain'
[...]
SMTP_SERVER = "localhost"
SENDER_ADDRESS = 'BlockHosts '
[...]
IPBLOCK = "iptables"
[...]



No HOSTS_BLOCKFILE podemos expecificar /etc/hosts.allow ou /etc/hosts.deny. No meu caso eu escolhi o /etc/hosts.allow, mas fique a vontade para escolher entre ambos. Na linha LOGFILES, indicamos o arquivo de log que o BlockHosts deve buscar. No caso do OpenSSH, os logs de falha de Login ficam em /var/log/auth.log e os logs do ProFTPd ficam em /var/log/proftpd/proftpd.log. O COUNT_THRESHOLD seta o numero de tentativas erradas durante o login vindas de um mesmo host e que o BlockHosts deve bloquea-los. Em AGE_THRESHOLD configuramos quanto tempo depois de bloqueados os hosts serao liberados. IPBLOCK especifica se usaremos o iptables (usado nesse tutorial) ou o iproute e adicionando estes hosts em /etc/hosts.allow ou em /etc/hosts.deny, dependendo da sua escolha. Lembre-se, eu utilizei o /etc/hosts.allow. Para editar o nosso /etc/hosts.allow ou /etc/hosts.deny, dependendo da sua escolha, faça um backup do mesmo. Edite apenas o arquivo que escolheu no inicio das configuraçoes. No meu caso copiei o /etc/hosts.allow.
mv /etc/hosts.allow /etc/hosts.allow_orig
Crie um novoo /etc/hosts.allow com o comando abaixo:
nano /etc/hosts.allow
Copiar o conteudo abaixo para o novo arquivo /etc/hosts.allow
# # hosts.allow This file describes the names of the hosts which are # allowed to use the local INET services, as decided # by the '/usr/sbin/tcpd' server. # # ---- # see "man 5 hosts_access" for details of the format of IP addresses, #services, allow/deny options. Also see "man hosts_options" # # permanent whitelist addresses - this should always be allowed access ALL: 127.0.0.1 : allow # ALL: 192.168.0. : allow # permanent blacklist addresses - this should always be denied access # ALL: 10. : deny # ---------------------------------------- # next section is the blockhosts section - it will add/delete entries in # between the two marker lines (#---- BlockHosts Additions) #---- BlockHosts Additions #---- BlockHosts Additions # ---------------------------------------- # finally, the command to execute the blockhosts script, based on # connection to particular service or services: sshd: ALL: spawn /usr/bin/blockhosts.py --verbose --mail --iptables \ --echo "%c-%s" --check-ip "%h" >> /var/log/blockhosts.log 2>&1 & \ : allow #--- # add --iproute to enable null-routing, or add --iptables to enable packet # filtering, which blocks all network communication from blocked hosts #--- # remove >> /var/log/blockhosts.log 2>&1 if no logging to blockhosts.log # is needed - without this, it will still log to syslog (minimally) #sshd: ALL: spawn /usr/bin/blockhosts.py --verbose --echo "%c-%s" & : allow #--- # above commands will use default config file - /etc/blockhosts.cfg, edit # it as needed to specify local configuration options # See "man hosts.allow" for info on %c and %s identifiers # for non-verbose, with identification, to syslog only (/var/log/messages), # triggered on any service (using ALL as first word): #ALL: ALL: spawn /usr/bin/blockhosts.py --echo "%c-%s" & : allow #---- # To test hosts.allow, and to find out exact names of SSH/FTP services, # add this line to the beginning of hosts.allow, use ssh/ftp to connect # to your server, and then look at the log (/var/log/messages or # blockhosts.log) to see the name of the invoked service. # IMPORTANT: after your test is done, remove this line from hosts.allow! # Otherwise everyone will always have access. #ALL : ALL: spawn (/usr/bin/blockhosts.py --verbose --echo "%c-%s" >> /var/log/blockhosts.log 2>&1 )& : allow # -------------------------------------------------------------------------

Entendendo o arquivo e editando as regras: Na primeira seçao, insira o IP dos hosts que vc quer liberar (whitelist), 127.0.0.1 por exemplo. Podemos liberar os ips de uma sub-rede, para isso, devemos descomentar a linha # ALL: 192.168.0. : allow e adicionar duas linhas, onde serao adicionados os os hosts ou ips bloqueados:

#---- BlockHosts Additions #---- BlockHosts Additions

A seguir mostrarei uma etapa muito importante, com ela, sempre que alguém tenta fazer login usando o SSH, /usr/bin/blockhosts.py é iniciado, verifica os arquivos de log do /etc/blockhosts.cfg, e bloqueia todos os hosts com tentativas de login exedidas no COUNT_THRESHOLD , adicionando o arquivo /etc/hosts.allow e usando o resultado com o iptables que impedem esses ips ou hosts acessarem o sistema). Todas as ações serão registradas em /var/log/blockhosts.log. Nessa etapa, iniciaremos o BlockHosts com a opçao dry-run, com isso podemos analizar se aconteceu algum erro na configuraçao. Usa-se o seguinte comando:
blockhosts.py --dry-run --verbose
O sistema deve retornar um resultado como o que se segue:
server1:/tmp/BlockHosts-2.5.0# blockhosts.py --dry-run --verbose
blockhosts 2.5.0 started: 2010-08-18 14:16:56 CEST
... loaded /etc/hosts.allow, starting counts: blocked 0, watched 0
no logoffsets found, will read from beginning in logfile: /var/log/auth.log
... loading log file /var/log/auth.log, offset: 0
no logoffsets found, will read from beginning in logfile: /var/log/proftpd/proftpd.log
... loading log file /var/log/proftpd/proftpd.log, offset: 0
... discarding all host entries older than 2010-08-18 02:16:56 CEST
... final counts: blocked 0, watched 1
#---- BlockHosts Additions
#bh: ip: 192.168.0.2 : 1 : 2010-08-18 14:16:56 CEST

#bh: logfile: /var/log/auth.log
#bh: offset: 6763
#bh: first line:Feb 16 13:22:10 server1 login[1992]: pam_unix(login:session): session opened for user root by (uid=0)

#bh: logfile: /var/log/proftpd/proftpd.log
#bh: offset: 884
#bh: first line:Feb 16 14:59:18 server1.example.com proftpd[13157] server1.example.com:
ProFTPD 1.3.1 (stable) (built Fri Feb 6 12:26:25 GMT 2009) standalone mode STARTUP

#---- BlockHosts Additions

# ----------------------------------------
# finally, the command to execute the blockhosts script, based on
# connection to particular service or services:

sshd: ALL: spawn /usr/bin/blockhosts.py --verbose --mail --iptables \
--echo "%c-%s" --check-ip "%h" >> /var/log/blockhosts.log 2>&1 & \
: allow

#---
# add --iproute to enable null-routing, or add --iptables to enable packet
# filtering, which blocks all network communication from blocked hosts
#---
# remove >> /var/log/blockhosts.log 2>&1 if no logging to blockhosts.log
# is needed - without this, it will still log to syslog (minimally)
#sshd: ALL: spawn /usr/bin/blockhosts.py --verbose --echo "%c-%s" & : allow
#---
# above commands will use default config file - /etc/blockhosts.cfg, edit
# it as needed to specify local configuration options

# See "man hosts.allow" for info on %c and %s identifiers

# for non-verbose, with identification, to syslog only (/var/log/messages),
# triggered on any service (using ALL as first word):
#ALL: ALL: spawn /usr/bin/blockhosts.py --echo "%c-%s" & : allow
#----
# To test hosts.allow, and to find out exact names of SSH/FTP services,
# add this line to the beginning of hosts.allow, use ssh/ftp to connect
# to your server, and then look at the log (/var/log/messages or
# blockhosts.log) to see the name of the invoked service.
# IMPORTANT: after your test is done, remove this line from hosts.allow!
# Otherwise everyone will always have access.
#ALL : ALL: spawn (/usr/bin/blockhosts.py --verbose --echo "%c-%s" >> /var/log/blockhosts.log 2>&1 )& : allow

# -------------------------------------------------------------------------
Commands (tentative) to run for IPTables filtering:
... created user-defined chain blockhosts
... creating jump from INPUT to blockhosts chain
... creating jump from FORWARD to blockhosts chain
... no email to send.
server1:/tmp/BlockHosts-2.5.0#


Se tudo estiver Ok, sem erros e nada pendente, estamos prontos para executar o BlockHosts sem a opçao --dry-run.
blockhosts.py --verbose

O resultado sera parecido com o que se segue:

server1:/tmp/BlockHosts-2.5.0# blockhosts.py --verbose
blockhosts 2.5.0 started: 2010-08-18 14:20:20 CEST
... loaded /etc/hosts.allow, starting counts: blocked 0, watched 0
no logoffsets found, will read from beginning in logfile: /var/log/auth.log
... loading log file /var/log/auth.log, offset: 0
no logoffsets found, will read from beginning in logfile: /var/log/proftpd/proftpd.log
... loading log file /var/log/proftpd/proftpd.log, offset: 0
... discarding all host entries older than 2010-08-18 02:20:20 CEST
... final counts: blocked 0, watched 1
... created user-defined chain blockhosts
... creating jump from INPUT to blockhosts chain
... creating jump from FORWARD to blockhosts chain
... no email to send.
server1:/tmp/BlockHosts-2.5.0#

Nesse ponto, o sistema ja esta parcialmente protegido, uma vez que o BlockHosts nao esta configurado para analizar logins falhos no ProFTPd pois o mesmo não é um serviço TCP_WRAPPERS. Resolvemos esse problemas usando uma rotina no cron, que starta o BlockHosts a cada 5 minutos, por exemplo.

=> SEGUNDO PASSO
Criando um job no Cron para serviços não TCP_WRAPPERS. Para bloquear os ips ou hosts qua nao usam serviços TCP_WRAPPERS como o ProFTPd no Debian, use o seguinte comando:
blockhosts.py --ipblock=iptables --verbose

Deve-se criar um script para automatizar essa tarefa em /usr/bin/blockhosts.py.
nano /usr/bin/blockhosts.py
Adicione o conteudo abaixo:

#!/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin /usr/bin/blockhosts.py --ipblock=iptables --verbose >> /var/log/blockhosts.log 2>&1

Esse script tem o proposito de passar o PATH (caminho) correto para o script /usr/bin/blockhosts.py, pois se usa-lo diretamente no cron job, nos deparamos com erros como iptables nao encontrado. Adicione privilegio de execuçao ao script:
chmod 700 /usr/local/sbin/blockhosts

Criando uma tarefa no cron com o cmando a seguir:

crontab -e

Adicione a tarefa a abaixo:
*/5 * * * * /usr/local/sbin/blockhosts &> /dev/null

=> TERCEIRO PASSO
Testando Para ver se esta tudo ok e o BlockHosts esta funcionando, tente logar no servidor usando SSH e FTP com um usuario e senha errados. Depois de algumas tentativas erradas, o servidor devera refugar, o que significa que seu ip foi bloqueado. Para acessar o servidor, deve-se alterar o ip do cliente e tentar acessar o servidor novamente, com login correto e executar iptables -L observar que o . Voce poderaip do possivel atacante foi "dropado" (rejeitado)
server1:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
blockhosts all -- anywhere anywhere

Chain FORWARD (policy ACCEPT)
target prot opt source destination
blockhosts all -- anywhere anywhere

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Chain blockhosts (2 references)
target prot opt source destination
DROP all -- IP DO POSSIVEL ATACANTE anywhere
server1:~#

Agora observe em /etc/hosts.allow que o mesmo endereço ip esta listado na seçao #---- BlockHosts Additions:
nano /etc/hosts.allow
o resultado...

[...]
#---- BlockHosts Additions
ALL: 192.168.0.199 : deny
#bh: ip: 192.168.0.199 : 24 : 2010-08-18 14:37:53 CEST
#bh: ip: 192.168.0.2 : 1 : 2010-08-18 14:20:20 CEST
#bh: logfile: /var/log/auth.log
#bh: offset: 7619
#bh: first line:Feb 16 13:22:10 server1 login[1992]: pam_unix(login:session): session opened for user root byuid=0)
#bh: logfile: /var/log/proftpd/proftpd.log
#bh: offset: 8588
#bh: first line:Feb 16 14:59:18 server1.example.com proftpd[13157] server1.example.com: ProFTPD 1.3.1 (stable) (built Fri Feb 6 12:26:25 GMT 2009) standalone mode STARTUP
#---- BlockHosts Additions
[...]
(


Para finalizar, podemos observar tambem /var/log/blockhosts.log:

tail /var/log/blockhosts.log

server1:~# tail /var/log/blockhosts.log
... discarding all host entries older than 2010-08-18 02:40:02 CEST
... final counts: blocked 1, watched 2
... no email to send.
blockhosts 2.5.0 started: 2010-08-18 14:45:01 CEST
... loaded /etc/hosts.allow, starting counts: blocked 1, watched 2
... loading log file /var/log/auth.log, offset: 7619
... loading log file /var/log/proftpd/proftpd.log, offset: 8588
... discarding all host entries older than 2010-08-18 02:45:01 CEST
... final counts: blocked 1, watched 2
... no email to send.
server1:~#


Ok, tudo pronto e funcionando... considere-se com uma proteço anti-BruteForce

Referencial:

Nenhum comentário:

Postar um comentário