Learning Fail2Ban
Introdução ao Fail2Ban
O Fail2Ban é uma ferramenta de segurança que tem como objetivo mitigar ataques de força bruta e outras formas de abuso dos serviços de rede. Sua principal função é monitorar os registros de Logs de vários serviços, como: SSH, Apache, Nginx e outros, com o propósito de identificar tentativas de login malsucedidas e outras atividades suspeitas.
O Fail2Ban opera detectando o número de tentativas malsucedidas e, em resposta, adiciona uma regra ao firewall para bloquear temporariamente o endereço IP de onde essas tentativas originaram. Tanto a duração desse bloqueio temporário quanto a quantidade de tentativas falhas pode ser configurada para atender a uma configuração específica, proporcionando flexibilidade na gestão das medidas de segurança.
O Fail2Ban é uma ferramenta útil para proteger sistemas contra ataques de força bruta e outras formas de abuso de serviços de rede. No entanto, é importante lembrar que o Fail2Ban não é uma solução completa de segurança e deve ser usado em conjunto com outras medidas de segurança, como senhas fortes e atualizações regulares do sistema. Novamente para que fique bem fixado na mente, O Fail2Ban é capaz de reduzir a taxa de tentativas incorretas de autenticação, porém não consegue eliminar o risco que a autenticação fraca representa.
O uso de um software de bloqueio de IP pode deter ataques simples, mas ele depende de um programa adicional e do registro bem-sucedido dessas tentativas de invasão.
Geralmente, não faz sentido utilizar o Fail2Ban com o serviço SSH, por exemplo; Quando apenas autenticação por chave pública ou métodos similares estão/podem ser habilitados. O Fail2Ban também não substitui uma VPN. Evite expor seus serviços à internet, a menos que seja estritamente necessário.
Além disso, se o invasor conhecer o seu endereço IP, eles podem enviar pacotes com um cabeçalho de origem falsificado e fazer com que seu endereço IP seja bloqueado. Certifique-se de colocar o seu próprio endereço IP na lista de IPs ignorados (whitelist).
Entendendo o Fail2Ban
Antes de continuar, vamos entender como o Fail2Ban funciona e como fazer algumas configurações customizadas. As explicações abaixo foram retiradas e traduzidas do manual oficial do Fail2Ban.
O Fail2Ban possui quatro arquivos de configurações distintas (em partes):
Arquivo | Descrição |
---|---|
fail2ban.conf | Arquivo de configuração global do Fail2Ban (destinado para o daemon). |
filter.d/*.conf | Filtros que informam ao Fail2Ban como detectar falhas de autenticação. |
action.d/*.conf | Ações que devem ser tomadas para banir ou anular o banimento. |
jail.conf | Jails com combinações de Filtros e Ações. Devido à possibilidade de sobrescrita no arquivos jail.conf durante uma atualização, o man recomenda que os usuários criem um arquivo chamado jail.local para não quebrar instalações. |
jail.local | O mesmo que jail.conf , mas com foi dito acima, é usado para ter Jails customizadas e que não serão sobrescritas numa atualização de software. |
Os arquivos de configuração têm seções, que são especificadas com [nome da seção]
, e pares nome = valor
. Para itens de nome que podem aceitar múltiplos valores, especifique os valores separados por espaços ou em linhas separadas com um recuo de espaço no início da linha antes do segundo valor, exemplo:
# Cada uma das linhas abaixo é um determinado filtro que é atribuído a opção 'failregex':
failregex=^.*: connect from .*\[<HOST>\]
^.*: NOQUEUE: reject: RCPT from unknown\[<HOST>\]
^.*: lost connection after .*from unknown\[<HOST>\]
Arquivos de configuração podem incluir outros arquivos de configuração (definindo variáveis comuns), o que é frequentemente usado em Filtros e Ações. Tais inclusões são definidas em uma seção chamada [INCLUDES]
:
- before indica que o arquivo especificado deve ser analisado antes do arquivo atual.
- after indica que o arquivo especificado deve ser analisado após o arquivo atual.
O Fail2ban possui uma sintaxe mais avançada (semelhante à interpolação estendida em Python). Essa interpolação estendida utiliza a sintaxe %(seção/parâmetro)s
para denotar um valor de uma seção externa. Além da interpolação entre seções, o valor do parâmetro na seção [DEFAULT]
pode ser recuperado com %(default/parâmetro)s
.
O Fail2ban também suporta outro recurso chamado %(known/parâmetro)s
; significa a última opção conhecida com o nome "parâmetro". Essa interpolação torna possível estender uma expressão regular de filtro ou jail padrão em um arquivo .local
, por exemplo.
baduseragents = IE|wget|%(my-settings/baduseragents)s
failregex = %(known/failregex)s
useragent=%(baduseragents)s
Além da interpolação %(known/parameter)s
, que não funciona para parâmetros de inicialização de filtros/ações, você pode usar a tag de interpolação <known/parameter>
(significa a última definição conhecida de inicialização de filtros ou ações com o nome "parâmetro").
Essa interpolação torna possível estender parâmetros de um filtro ou ação padrão diretamente em uma configuração de jail dentro do arquivo jail.conf/jail.local
, sem a necessidade de criar um arquivo separado para filter.d/*.local
, por exemplo.
# filter.d/test.conf:
[Init]
test.method = GET
baduseragents = IE|wget
[Definition]
failregex = ^%(__prefix_line)\s+"<test.method>"\s+test\s+regexp\s+-\s+useragent=(?:<baduseragents>)
# jail.local:
[test]
# use filter "test", overwrite method to "POST" and extend known bad agents with "badagent":
filter = test[test.method=POST, baduseragents="badagent|<known/baduseragents>"]
Instalação
- CentOS 6
- Ubuntu 20.04
# Instale o repositório abaixo para ter pacotes extras:
$ yum install epel-release
# Para instalar o Fail2Ban, rode o comando abaixo:
$ yum install fail2ban
# Para instalar o Fail2Ban, rode o comando abaixo:
$ sudo apt install -y fail2ban
A partir desse ponto, estou usando o Ubuntu para me basear em configurações e afins.
fail2ban-client
O utilitário fail2ban-client
é usado para configurar e controlar o servidor Fail2Ban, contudo, eu vou explicar apenas a parte de controle.
Opção | Descrição |
---|---|
status | Mostra a quantidade de Jails e o nome de cada uma. |
unban --all | Remove todos os IP, de todas as Jail que estão banidos. |
banned | Retorna as Jail com IP banido em forma de dicionário. |
ping | Testa se o server esta respondendo. |
set <option> | Usado para setar alguma configuração. |
get <option> | Usado para obter alguma configuração. |
As opções abaixo são usadas com set ou get. | |
ignoreip | Usado para mostrar ou configurar os IPs que são ignorados em determinada Jail. |
bantime | Usado para mostrar ou configurar o tempo de banimento em determinada Jail. |
unbanip | Usado apenas com set para tirar um IP do banimento. |
banip | Usado para obter os IP banidos ou para banir um determinado IP. |
Vejamos alguns exemplos, para isso, faça todos os testes com usuário root:
# Ver todas as Jails:
fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshd
# Exibir o status de uma Jail específica:
fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 8
| |- Total failed: 1585
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 3
|- Total banned: 127
`- Banned IP list: 179.209.45.226 2804:431:cff7:c8a4:810c:eaf9:ea94:d164 88.2.196.145
# Ver os IPs ignorados numa Jail:
fail2ban-client get sshd ignoreip
No IP address/network is ignored
# Obter o tempo de banimento da Jail:
fail2ban-client get sshd bantime
600
# Ver os IPs banidos:
fail2ban-client get sshd banip
179.209.45.226 2804:431:cff7:c8a4:810c:eaf9:ea94:d164 88.2.196.145
# Banir um IP:
fail2ban-client set sshd banip 192.168.10.40
1
# Remover esse IP desse banimento:
fail2ban-client set sshd unbanip 192.168.10.40
1
Solução de problemas
Caso seja removido um IP manualmente, que tenha sido bloqueado pelo Fail2Ban, pode ser que ele passe a operar de forma errada, para corrigir faça:
systemctl stop fail2ban
systemctl start fail2ban
Customização de regras
Vamos criar uma regra para bloquear IP com algum comportamento no servidor de email. Atenção, isso é apenas para teste e não deve ser colocado em produção.
# Crie o arquivo com a configuração default:
cat /etc/fail2ban/jail.local
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1
bantime = 28800
findtime = 3600
maxretry = 5
destemail = postmaster@example.com
sender = fail2ban@example.com
chain = INPUT
# Crie o arquivo com a configuração específica para analisar as tentivas no servidor de email:
cat /etc/fail2ban/jail.d/smtpd.conf
[smtpd]
enabled = true
port = 25
protocol = tcp
filter = postfix-custom
maxretry = 2
findtime = 3600
bantime = 10800
logpath = /var/log/mail.log
banaction = iptables-multiport
# Agora crie um filtro customizado, vamos obter os IP que devam ser bloqueados usando esse filtro:
vim /etc/fail2ban/filter.d/postfix-custom.conf
[Definition]
_daemon = postfix/smtpd
failregex=^.*: connect from .*\[<HOST>\]
^.*: NOQUEUE: reject: RCPT from unknown\[<HOST>\]
^.*: lost connection after .*from unknown\[<HOST>\]
ignoreregex =
Agora vamos revisar as opções, para o primeiro arquivo temos:
Opção | Significado |
---|---|
ignoreip | Define quais endereços IP devem ser ignorados pelo Fail2Ban. Neste caso, 127.0.0.1/8 e ::1 são ignorados, o que significa que o Fail2Ban não aplicará regras a conexões originadas desses IPs. |
bantime | Especifica o tempo em segundos durante o qual um IP será banido após exceder o limite de tentativas definido (maxretry). Neste caso, o tempo de banimento é de 28.800 segundos, o que equivale a 8 horas. |
findtime | Define o período em segundos durante o qual o Fail2Ban irá monitorar tentativas de login malsucedidas para determinar se o IP deve ser banido. Neste caso, o período de monitoramento é de 3.600 segundos, o que equivale a 1 hora. |
maxretry | Indica o número máximo de tentativas de login malsucedidas permitidas antes que o Fail2Ban acione a ação de banimento. Neste caso, o limite é definido como 5 tentativas. |
destemail | Define o endereço de e-mail para o qual os alertas gerados pelo Fail2Ban serão enviados. Neste exemplo, os alertas serão enviados para "postmaster@example.com". |
sender | Especifica o endereço de e-mail que será usado como remetente nos alertas gerados pelo Fail2Ban. Neste caso, o endereço de remetente é "fail2ban@example.com". |
chain | Indica a chain de filtragem do iptables na qual o Fail2Ban irá adicionar as regras de banimento. Neste caso, as regras serão adicionadas à chain "INPUT" do iptables. |
Para o segundo arquivo:
Opção | Significado |
---|---|
enabled | Esta opção determina se o Fail2Ban está habilitado para monitorar e proteger o serviço SMTP. Neste caso, está definido como true , o que significa que o Fail2Ban está ativado para o serviço SMTP. |
port | Especifica a porta na qual o serviço SMTP está ouvindo. Neste caso, o serviço SMTP está configurado para ouvir na porta 25. |
protocol | Define o protocolo de rede usado pelo serviço. Aqui, o protocolo é configurado como "tcp", indicando que o serviço SMTP opera sobre o protocolo TCP. |
filter | Indica o nome do filtro que o Fail2Ban deve usar para analisar os logs em busca de tentativas de login malsucedidas. Neste exemplo, o filtro "postfix-custom" será utilizado. |
maxretry | Essa opção sobrescreve o valor definido em /etc/fail2ban/jail.local . |
findtime | Essa opção sobrescreve o valor definido em /etc/fail2ban/jail.local . |
bantime | Essa opção sobrescreve o valor definido em /etc/fail2ban/jail.local . |
logpath | Especifica o caminho do arquivo de log que o Fail2Ban irá analisar para encontrar tentativas de login malsucedidas. Neste caso, o arquivo de log é /var/log/mail.log . |
banaction | Indica a ação de banimento a ser executada quando um IP é considerado culpado pelo Fail2Ban. Neste exemplo, a ação é definida como iptables-multiport , que possui configurações de regras para bloquear IP no iptables. |
Para o terceiro arquivo:
Opção | Significado |
---|---|
_daemon | Indica o nome do daemon ou processo que está sendo monitorado. Neste caso, o processo é "postfix/smtpd". |
failregex | Define as expressões regulares que o Fail2Ban usará para analisar os logs em busca de tentativas de login malsucedidas. |
ignoreregex | Permite especificar expressões regulares que o Fail2Ban deve ignorar ao analisar os logs. Neste caso, a opção está vazia, o que significa que nenhuma expressão regular está sendo ignorada. |
fail2ban-regex
Com o utilitário fail2ban-regex
podemos testar a regra criada e verificar as linhas de logs que estão se enquadrando no filtro que estamos usando. Vou deixar apenas alguns exemplos na parte de logs:
fail2ban-regex /var/log/mail.log /etc/fail2ban/filter.d/postfix-custom.conf --print-all-matched
+
Running tests
=============
Use failregex filter file : postfix-custom, basedir: /etc/fail2ban
Use log file : /var/log/mail.log
Use encoding : UTF-8
Results
=======
Failregex: 532 total
|- #) [# of hits] regular expression
| 1) [493] ^.*: connect from .*\[<HOST>\]
| 2) [3] ^.*: NOQUEUE: reject: RCPT from unknown\[<HOST>\]
| 3) [36] ^.*: lost connection after .*from unknown\[<HOST>\]
`-
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
| [2394] {^LN-BEG}(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
`-
Lines: 2394 lines, 0 ignored, 532 matched, 1862 missed
[processed in 0.13 sec]
|- Matched line(s):
| Sep 17 23:23:28 servertest postfix/smtpd[339294]: NOQUEUE: reject: RCPT from unknown[37.139.129.135]: 454 4.7.1 <stevendarryl114@outlook.com>: Relay access denied; from=<test@servertest.com.br> to=<stevendarryl114@outlook.com> proto=SMTP helo=<win-clj1b0gq6jp.domain>
| Sep 17 23:25:39 servertest postfix/smtpd[339294]: lost connection after RCPT from unknown[37.139.129.135]
| Sep 18 16:30:49 servertest postfix/smtpd[625996]: NOQUEUE: reject: RCPT from unknown[147.78.103.248]: 454 4.7.1 <spameri@tiscali.it>: Relay access denied; from=<spameri@tiscali.it> to=<spameri@tiscali.it> proto=ESMTP helo=<WIN-CLJ1B0GQ6JP>
| Sep 19 00:51:05 servertest postfix/smtpd[763375]: NOQUEUE: reject: RCPT from unknown[87.120.84.249]: 454 4.7.1 <spameri@tiscali.it>: Relay access denied; from=<spameri@tiscali.it> to=<spameri@tiscali.it> proto=ESMTP helo=<WIN-CLJ1B0GQ6JP>
| Sep 19 16:51:42 servertest postfix/smtpd[1028558]: connect from scan-13h.shadowserver.org[184.105.247.226]
| Sep 19 16:52:13 servertest postfix/smtpd[1028558]: connect from scan-13m.shadowserver.org[184.105.247.246]
| Sep 19 16:56:02 servertest postfix/smtpd[1029711]: connect from unknown[79.110.48.16]
| Sep 19 16:58:02 servertest postfix/smtpd[1030245]: connect from unknown[147.78.103.96]
| Sep 19 17:02:56 servertest postfix/smtpd[1031531]: connect from unknown[147.78.103.88]
| Sep 19 17:05:53 servertest postfix/smtpd[1032310]: connect from unknown[185.216.71.142]
| Sep 19 17:09:17 servertest postfix/smtpd[1033199]: connect from unknown[147.78.103.96]
| Sep 19 17:20:40 servertest postfix/smtpd[1036209]: connect from unknown[147.78.103.96]
| Sep 19 17:31:59 servertest postfix/smtpd[1039174]: connect from unknown[147.78.103.96]
| Sep 19 17:43:23 servertest postfix/smtpd[1042708]: connect from unknown[147.78.103.96]
| Sep 19 17:54:44 servertest postfix/smtpd[1045927]: connect from unknown[147.78.103.96]
| Sep 19 17:56:32 servertest postfix/smtpd[1046418]: connect from unknown[185.216.71.142]