Tradicionalmente, sistemas cujo acesso é restrito autenticam seus usuários por uma combinação de nome de usuário (mais conhecido como login) e senha.
Um ataque de força bruta (do inglês brute force attack) é um tipo de ataque que consiste em tentar adivinhar uma combinação de login e senha que libere o acesso ao sistema. Se o invasor souber pelo menos um login, já tem meio caminho andado, porque aí só precisa descobrir a senha. Normalmente, isso é feito na base da tentativa e erro, testando todas as combinações de senhas possíveis (por exemplo, aaaa
, aaab
, aaac
… 1234
, 1235
, etc).
É um dos tipos de ataque mais simples e antigos, mas que ainda acontece e — pasme — por vezes funciona, uma vez que muitos usuários criam senhas curtas, fracas, fáceis de adivinhar ou mesmo óbvias. Dependendo do tamanho e da complexidade da senha, um ataque de força bruta pode levar segundos ou séculos para descobri-la.
Administradores de sistemas Linux devem proteger os servidores contra tentativas de ataque e acessos não autorizados. Já falamos do firewall iptables, que atua nas camadas de rede e transporte do modelo TCP/IP. Ele é capaz de impedir ataques de força bruta, que ocorrem na camada de aplicação, com o auxílio de uma ferramenta chamada fail2ban.
O que é o fail2ban?
O fail2ban é um IPS (Intrusion Prevention System, sistema de prevenção de intrusos) na forma de um daemon (processo que fica executando ao fundo) que monitora as tentativas de acesso aos serviços do sistema e age proativamente quando detecta um endereço IP que aparenta comportamento suspeito — várias tentativas de fazer login malsucedidas, exploração de brechas, etc.
O fail2ban fica o tempo todo escaneando os registros (logs) do sistema (por exemplo: /var/log/messages
, /var/log/apache2/access_log
, /var/log/apache2/error_log
, etc.) e “de fábrica” já é capaz de monitorar diversos serviços (por exemplo: SSH, Apache, FTP, SMTP, MySQL, etc). Geralmente, a ação adotada pelo fail2ban quando detecta um endereço IP suspeito é adicionar uma regra no iptables para rejeitar esse endereço, embora qualquer outra ação possa ser configurada (por exemplo, enviar um e-mail para o administrador).
Note que o fail2ban reduz a taxa de tentativas incorretas de autenticação, mas não elimina o risco inerente a uma autenticação fraca (por exemplo, se a senha de um usuário é 123456
, e um invasor iniciar seu ataque testando essa senha, conseguirá acessar o sistema em sua primeira tentativa). Para aumentar a segurança dos serviços, configure-os para usar mecanismos de autenticação mais seguros, como autenticação de dois fatores ou autenticação usando par de chaves pública e privada.
Instalando o fail2ban
Repetindo a recomendação do tutorial sobre iptables, para acompanhar este tutorial, sugiro que você use uma máquina virtual. Com isso, você não precisa modificar as configurações do seu servidor ou desktop até que esteja familiarizado com o fail2ban.
Para mais informações, leia:
Para instalar o fail2ban no openSUSE e em distribuições derivadas (como é o caso do Linux Kamarada), execute o comando:
1
# zypper in fail2ban
Configurando o fail2ban
Por padrão, o fail2ban mantém seus arquivos de configuração na pasta /etc/fail2ban/
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# cd /etc/fail2ban
# ls -lah
total 40K
drwxr-xr-x 6 root root 220 dez 14 20:05 .
drwxr-xr-x 1 root root 760 dez 14 20:05 ..
drwxr-xr-x 2 root root 1,3K dez 14 20:05 action.d
-rw-r--r-- 1 root root 2,3K out 4 2018 fail2ban.conf
drwxr-xr-x 2 root root 40 mar 27 2019 fail2ban.d
drwxr-xr-x 3 root root 1,7K dez 14 20:05 filter.d
-rw-r--r-- 1 root root 23K mar 27 2019 jail.conf
drwxr-xr-x 2 root root 40 mar 27 2019 jail.d
-rw-r--r-- 1 root root 71 mar 27 2019 jail.local
-rw-r--r-- 1 root root 2,8K mar 27 2019 paths-common.conf
-rw-r--r-- 1 root root 975 mar 27 2019 paths-opensuse.conf
Os principais arquivos de configuração são o fail2ban.conf
e o jail.conf
. Não é recomendado editá-los diretamente, porque eles pertencem ao pacote RPM fail2ban e podem ser sobrescritos pelo sistema durante atualizações, ocasionando a perda de personalizações. Em vez de editá-los, crie cópias chamadas fail2ban.local
e jail.local
:
1
2
# cp fail2ban.conf fail2ban.local
# cp jail.conf jail.local
O fail2ban lê primeiro os arquivos com extensão .conf
e depois os .local
. As configurações nos .local
sobrescrevem as configurações nos .conf
. Portanto, um arquivo .local
não precisa ter todas as configurações que já estão no seu correspondente .conf
. Uma alternativa à cópia seria criar novos arquivos de texto chamados fail2ban.local
e jail.local
para adicionar a eles apenas as configurações que devem diferir dos padrões.
Se você possui conhecimento ao menos técnico de inglês, esses arquivos possuem comentários que documentam as configurações do fail2ban e são uma mão na roda.
A seguir, veremos as principais configurações do fail2ban.
Configurações gerais (fail2ban.local)
O arquivo fail2ban.conf
(e seu correspondente fail2ban.local
) contém configurações gerais do fail2ban, como o nível de log e onde o log deve ser gravado.
Vejamos os trechos mais relevantes desse arquivo:
1
2
3
4
5
6
7
8
9
10
11
12
13
[Definition]
# Option: loglevel
# Notes.: Set the log level output.
# CRITICAL
# ERROR
# WARNING
# NOTICE
# INFO
# DEBUG
# Values: [ LEVEL ] Default: ERROR
#
loglevel = INFO
A opção loglevel
define o nível de detalhamento do log. Por padrão, esse nível é INFO
, ou seja, o fail2ban registra simples informações, assim como erros ou mensagens mais críticas. Já fornece um bom nível de detalhamento.
1
2
3
4
5
6
7
8
9
10
# Option: logtarget
# Notes.: Set the log target. This could be a file, SYSLOG, STDERR or STDOUT.
# Only one log target can be specified.
# If you change logtarget from the default value and you are
# using logrotate -- also adjust or disable rotation in the
# corresponding configuration file
# (e.g. /etc/logrotate.d/fail2ban on Debian systems)
# Values: [ STDOUT | STDERR | SYSLOG | SYSOUT | FILE ] Default: STDERR
#
logtarget = /var/log/fail2ban.log
A opção logtarget
define onde o log deve ser gravado. Por padrão, o fail2ban faz log no arquivo /var/log/fail2ban.log
. Você pode consultar esse arquivo quando precisar conferir se tudo está funcionando.
Normalmente, não é necessário alterar o fail2ban.conf
(ou o fail2ban.local
).
Configurações gerais das jaulas (jail.local)
O arquivo jail.conf
(e seu correspondente jail.local
) provavelmente é o arquivo mais importante. Ele contém a declaração e configuração das jaulas (jails), que correspondem aos serviços monitorados pelo fail2ban. Por padrão, todas as jaulas vem desabilitadas. Você deve habilitar as que precisa e adaptar suas configurações à realidade do seu servidor.
O arquivo jail.local
é dividido em seções. Cada jaula possui sua própria seção. No início do arquivo, antes das seções da jaulas, há uma seção [DEFAULT]
(padrão). As configurações nessa seção são aplicadas a todas as jaulas. Configurações específicas podem ser sobrescritas por jaulas específicas, se necessário.
Vejamos os trechos mais relevantes da seção [DEFAULT]
:
1
2
3
4
5
6
7
8
9
10
11
# The DEFAULT allows a global definition of the options. They can be overridden
# in each jail afterwards.
[DEFAULT]
...
# "ignoreip" can be a list of IP addresses, CIDR masks or DNS hosts. Fail2ban
# will not ban a host which matches an address in this list. Several addresses
# can be defined using space (and/or comma) separator.
#ignoreip = 127.0.0.1/8 ::1
A opção ignoreip
nos permite definir exceções ao monitoramento do fail2ban. O valor dessa opção é uma lista que pode conter:
- endereços IP de computadores (por exemplo,
127.0.0.1
); - endereços IP de redes/sub-redes, com máscaras em notação CIDR (
192.168.0.1/24
); e/ou - nomes de computadores, inclusive com domínio (FQDN,
kamarada.github.io
).
As exceções da lista devem estar separadas por espaço e/ou vírgula. O fail2ban não banirá endereços IP que se enquadrem nessa lista.
1
2
3
4
5
6
7
8
9
# "bantime" is the number of seconds that a host is banned.
bantime = 10m
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime = 10m
# "maxretry" is the number of failures before a host get banned.
maxretry = 5
Na minha humilde opinião, essas opções fariam mais sentido listadas ao contrário. Vejamos.
A opção maxretry
define quantas tentativas de acesso podem ser feitas antes que ocorra o bloqueio.
A opção findtime
define durante quanto tempo as tentativas de acesso são contabilizadas.
A opção bantime
define durante quanto tempo ficará bloqueado o host que excedeu a quantidade limite de tentativas de acesso.
Podemos ler a configuração padrão assim: uma pessoa que erre a senha 5 vezes (maxretry
) em 10 minutos (findtime
) terá seu host bloqueado por 10 minutos (bantime
), ou seja, da última tentativa de acesso, ela terá que aguardar 10 minutos para poder tentar de novo.
Parece uma boa configuração padrão, mas você pode mudar conforme ache necessário.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#
# ACTIONS
#
# Some options used for actions
# Destination email address used solely for the interpolations in
# jail.{conf,local,d/*} configuration files.
destemail = root@localhost
# Sender email address used solely for some actions
sender = root@<fq-hostname>
# E-mail action. Since 0.8.1 Fail2Ban uses sendmail MTA for the
# mailing. Change mta configuration parameter to mail if you want to
# revert to conventional 'mail'.
mta = sendmail
A opção destemail
define o e-mail para o qual o fail2ban deve enviar notificações de bloqueios, para as jaulas em que as notificações por e-mail estejam ativadas. De forma análoga, a opção sender
define o e-mail que deve ser informado como remetente.
A opção mta
define o programa que deve ser usado para enviar as notificações por e-mail, por padrão o Sendmail. Observe que as notificações só são enviadas de fato se esse programa estiver instalado e configurado no servidor.
1
2
3
4
# Choose default action. To change, just override value of 'action' with the
# interpolation to the chosen action shortcut (e.g. action_mw, action_mwl, etc) in jail.local
# globally (section [DEFAULT]) or per specific section
action = %(action_)s
A opção action
define a ação que o fail2ban deve tomar ao perceber um comportamento suspeito de um host. Na seção [DEFAULT]
, essa opção define a ação padrão para todas as jaulas. No arquivo jail.local
, acima da opção action
, são definidas algumas opções de ações (action_
, action_mw
, action_mwl
, etc). O valor padrão é action_
, que corresponde à ação mais básica (apenas bloquear). Se você configurou o envio de e-mail, talvez queira mudar esse valor para action_mw
, que corresponde a bloquear e notificar por e-mail.
Configuração da jaula SSH
O fail2ban é capaz de monitorar vários serviços. Como exemplo, vejamos como configurá-lo para monitorar tentativas de acesso via SSH. Para isso, vamos à seção [sshd]
do arquivo jail.local
.
1
2
3
4
5
6
7
8
9
[sshd]
# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
# normal (default), ddos, extra or aggressive (combines all).
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
#mode = normal
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
Comece adicionando enabled = true
para habilitar essa jaula.
A opção port
define a porta na qual o serviço escuta. Se o serviço escuta na porta padrão (no caso do SSH, a porta 22), deixe o valor padrão, que é o nome do serviço (ssh
). Se o serviço escuta em uma porta diferente da padrão, informe aqui o número da porta.
A opção logpath
define o caminho para o arquivo de log do serviço. De forma análoga, só mude o valor dessa opção se o serviço registra seu log em um arquivo diferente do padrão.
Iniciando o fail2ban
Feita a configuração inicial, é hora de iniciar o fail2ban. Para isso, execute:
1
# systemctl start fail2ban
Para se certificar de que o fail2ban está em execução, verifique o estado (status) do serviço:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# systemctl status fail2ban
● fail2ban.service - Fail2Ban Service
Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; disabled; vendor preset: disabled)
Active: active (running) since Fri 2019-12-13 23:07:09 -03; 1s ago
Docs: man:fail2ban(1)
Process: 5931 ExecStartPre=/bin/mkdir -p /var/run/fail2ban (code=exited, status=0/SUCCESS)
Main PID: 5932 (fail2ban-server)
Tasks: 3 (limit: 4915)
CGroup: /system.slice/fail2ban.service
└─5932 /usr/bin/python /usr/bin/fail2ban-server -xf start
dez 13 23:07:09 kamarada-pc systemd[1]: Starting Fail2Ban Service...
dez 13 23:07:09 kamarada-pc systemd[1]: Started Fail2Ban Service.
dez 13 23:07:09 kamarada-pc fail2ban-server[5932]: Server ready
Habilite o serviço do fail2ban para que ele seja iniciado automaticamente durante o boot:
1
# systemctl enable fail2ban
Testando o fail2ban
Vejamos o fail2ban agindo na prática.
Não teste os comandos desse tutorial em um servidor que você acessa remotamente via SSH: você corre o risco de perder o acesso ao servidor.
Usando um computador diferente daquele no qual você instalou o fail2ban, tente estabelecer um acesso remoto via SSH, mas erre a senha propositalmente algumas vezes:
1
2
3
4
5
6
7
8
9
$ ssh kamarada@10.0.0.250
Password:
Password:
Password:
kamarada@10.0.0.250's password:
Permission denied, please try again.
kamarada@10.0.0.250's password:
Received disconnect from 10.0.0.250 port 22:2: Too many authentication failures
Disconnected from 10.0.0.250 port 22
Se você esgotar o limite de tentativas configurado, será desconectado do servidor.
Perceba que novas tentativas de acesso são recusadas de imediato:
1
2
$ ssh kamarada@10.0.0.250
ssh: connect to host 10.0.0.250 port 22: Connection refused
Consultando o log do fail2ban
Como vimos, por padrão, o fail2ban guarda seu log no arquivo /var/log/fail2ban.log
.
Para abrir esse arquivo, você pode usar comandos como cat, less ou tail:
1
# less /var/log/fail2ban.log
O log do fail2ban mostra nossas tentativas frustradas de acesso e o efetivo bloqueio:
1
2
3
4
5
6
2019-12-13 23:24:01,169 fail2ban.filter [6803]: INFO [sshd] Found 10.0.0.10 - 2019-12-13 23:24:00
2019-12-13 23:24:04,638 fail2ban.filter [6803]: INFO [sshd] Found 10.0.0.10 - 2019-12-13 23:24:04
2019-12-13 23:24:07,919 fail2ban.filter [6803]: INFO [sshd] Found 10.0.0.10 - 2019-12-13 23:24:07
2019-12-13 23:24:12,335 fail2ban.filter [6803]: INFO [sshd] Found 10.0.0.10 - 2019-12-13 23:24:12
2019-12-13 23:24:12,361 fail2ban.filter [6803]: INFO [sshd] Found 10.0.0.10 - 2019-12-13 23:24:12
2019-12-13 23:24:12,896 fail2ban.actions [6803]: NOTICE [sshd] Ban 10.0.0.10
Verificando as regras do iptables
Para bloquear hosts com comportamento suspeito, o fail2ban adiciona regras ao iptables.
Se você listar as regras em uso pelo iptables, verá a regra adicionada pelo fail2ban:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
f2b-sshd tcp -- anywhere anywhere multiport dports ssh
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain f2b-sshd (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
Perceba que o fail2ban cria suas próprias chains para gerenciar suas regras.
Desfazendo um bloqueio do fail2ban
Pode acontecer de um usuário legítimo do servidor ter esquecido sua senha e ter sido bloqueado pelo fail2ban após sucessivas tentativas de acesso. Nesse caso, você precisa desfazer o bloqueio feito pelo fail2ban para que o usuário possa voltar a acessar o servidor.
Para desfazer um bloqueio a um host feito anteriormente pelo fail2ban, execute:
1
# fail2ban-client set JAULA unbanip ENDERECO_IP
Por exemplo:
1
# fail2ban-client set sshd unbanip 10.0.0.10
Se você tentar novo acesso remoto via SSH, dessa vez informando a senha certa, conseguirá conectar ao servidor.
Interrompendo o fail2ban
Se por qualquer motivo você precisar interromper o monitoramento do fail2ban, execute:
1
$ systemctl stop fail2ban
Note que isso também exclui as regras adicionadas ao iptables pelo fail2ban, permitindo que hosts que antes estavam bloqueados façam novas tentativas de acesso ao servidor.
Incrementando o script do iptables
No post anterior sobre o iptables, fizemos um script para iniciá-lo e configurá-lo durante o boot. Agora podemos incrementar aquele script interrompendo o fail2ban antes da limpeza das regras e iniciando-o novamente ao final:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/bin/bash
set -ex
# Interromper o fail2ban
systemctl stop fail2ban
# Limpar as regras
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -t raw -F
iptables -t raw -X
# Politica padrao: bloquear todas as conexoes de entrada
iptables -P FORWARD DROP
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
# Aceitar conexoes estabelecidas previamente
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Aceitar tudo vindo da interface de loopback
iptables -A INPUT -i lo -j ACCEPT
# SSH (porta 22/TCP,UDP)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p udp --dport 22 -j ACCEPT
# HTTP (porta 80/TCP)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# Iniciar o fail2ban
systemctl start fail2ban
Referências
Espero que esse texto tenha sido útil. Oportunamente, conforme estudemos diversos servidores (servidor web, banco de dados, servidor de FTP, servidor de e-mail, etc), veremos como podemos protegê-los usando a dupla iptables e fail2ban.
Se tiver alguma dúvida ou informação útil a acrescentar, por favor, deixe um comentário.
Até mais!
- O que é e como funciona um ataque de força bruta - Artigo - Viva o Linux
- What’s a Brute Force Attack? - Kaspersky
- How To Protect Server Against Brute Force Attacks With Fail2ban On Linux - 2daygeek.com
- Manual - Fail2ban
- Proteção utilizando fail2ban contra ataques do tipo - Artigo - Viva o Linux
- Fail2ban - Aprendendo a instalar e configurar - Dica - Viva o Linux
- firewall - How to Unban an IP properly with Fail2Ban - Server Fault