30.6. Blacklistd

O Blacklistd é um daemon que escuta sockets para receber notificações de outros daemons sobre tentativas de conexão que falharam ou foram bem-sucedidas. É mais amplamente utilizado no bloqueio de muitas tentativas de conexão em portas abertas. Um exemplo excelente é o SSH, executado na Internet, recebendo muitas solicitações de conexão de bots ou scripts tentando adivinhar senhas e obter acesso. Utilizando blacklistd, o daemon pode notificar o firewall para criar uma regra de filtro para bloquear tentativas excessivas de conexão de uma única origem após várias tentativas. O Blacklistd foi desenvolvido pela primeira vez no NetBSD e apareceu na versão 7. O FreeBSD 11 importou o blacklistd do NetBSD.

Este capítulo descreve como instalar o blacklistd, configurá-lo e fornece exemplos de como usá-la. Os leitores devem estar familiarizados com os conceitos básicos de firewall, como regras. Para detalhes, consulte o capítulo sobre firewall. O PF é usado nos exemplos, mas outros firewalls disponíveis no FreeBSD também devem funcionar com o blacklistd.

30.6.1. Habilitando a Blacklistd

A configuração principal do blacklistd é armazenada em blacklistd.conf(5). Várias opções de linha de comando também estão disponíveis para alterar o comportamento em tempo de execução do blacklistd. Para persistir as configurações em uma reinicialização do sistema, deve se armazenar as opções em /etc/blacklistd.conf. Para ativar o daemon durante a inicialização do sistema, adicione a linha blacklistd_enable no /etc/rc.conf assim:

# sysrc blacklistd_enable=yes

Para iniciar o serviço manualmente, execute este comando:

# service blacklistd start

30.6.2. Criando um conjunto de regras no Blacklistd

As regras do blacklistd são configuradas em blacklistd.conf(5) com uma opção por linha. Cada regra contém uma tupla separada por espaços ou tabulações. As regras pertencem a um local ou a um remote, que se aplica à máquina em que o blacklistd está sendo executado ou a uma origem externa, respectivamente.

30.6.2.1. Regras Locais

Um exemplo de entrada blacklistd.conf para uma regra local se parece com isso:

[local]
ssh             stream  *       *               *       3       24h

Todas as regras que seguem a seção [local] são tratadas como regras locais (que é o padrão), aplicadas à máquina local. Quando uma seção [remote] é encontrada, todas as regras a seguir são tratadas como regras de máquina remota.

Sete campos definem uma regra separada por tabulações ou espaços. Os quatro primeiros campos identificam o tráfego que deve estar na lista negra. Os três campos a seguir definem o comportamento do backlistd. Os curingas são indicados como asteriscos (*), correspondendo a qualquer coisa nesse campo. O primeiro campo define a localização. Nas regras locais, essas são as portas de rede. A sintaxe para o campo local é a seguinte:

[address|interface][/mask][:port]

Os endereços podem ser especificados como IPv4 no formato numérico ou IPv6 entre colchetes. Um nome de interface como em0 também pode ser usado.

O tipo de socket é definido pelo segundo campo. Os socket TCP são do tipo stream, enquanto UDP é indicado como dgram. O exemplo acima usa TCP, pois o SSH está usando esse protocolo.

Um protocolo pode ser usado no terceiro campo de uma regra de lista negra. Os seguintes protocolos podem ser usados: tcp, udp, tcp6, udp6 ou numérico. Um curinga, como no exemplo, geralmente é usado para corresponder a todos os protocolos, a menos que haja um motivo para distinguir o tráfego por um determinado protocolo.

No quarto campo, o usuário ou proprietário efetivo do processo daemon que está reportando o evento é definido. O nome de usuário ou o UID pode ser usado aqui, bem como um curinga (veja a regra de exemplo acima).

O nome da regra do packet filter é declarado pelo quinto campo, que inicia a parte de comportamento da regra. Por padrão, blacklistd coloca todos os blocos sob uma âncora pf chamada blacklistd em pf.conf assim:

anchor "blacklistd/*" in on $ext_if
block in
pass out

Para blacklists separadas, um nome de âncora pode ser usado neste campo. Em outros casos, o curinga será suficiente. Quando um nome começa com um hífen (-), significa que uma âncora com o nome de regra padrão precedido deve ser usada. Uma modificação do exemplo acima usando o hífen ficaria assim:

ssh             stream  *       *               -ssh       3       24h

Com essa regra, quaisquer novas regras de blacklist são adicionadas a uma âncora chamada blacklistd-ssh.

Para bloquear sub-redes inteiras para uma única violação de regra, um / no nome da regra pode ser usado. Isso faz com que a parte restante do nome seja interpretada como a máscara a ser aplicada ao endereço especificado na regra. Por exemplo, esta regra bloquearia todos os endereços adjacentes a /24.

22              stream  tcp       *               */24    3       24h

Nota:

É importante especificar o protocolo apropriado aqui. O IPv4 e o IPv6 tratam o /24 de maneira diferente, é por isso que * não pode ser usado no terceiro campo para esta regra.

Esta regra define que, se qualquer host dessa rede estiver se comportando mal, todo o resto da rede também será bloqueado.

O sexto campo, chamado nfail, define o número de falhas de login necessárias para colocar na blacklist o IP remoto em questão. Quando um curinga é usado nessa posição, isso significa que o bloqueio nunca irá acontecer. Na regra de exemplo acima, um limite de três é definido, o que significa que, após três tentativas de logon no SSH em uma conexão, o IP é bloqueado.

O último campo em uma definição de regra do blacklistd especifica por quanto tempo um host ficará na lista negra. A unidade padrão é segundos, mas sufixos como m, h e d também podem ser especificados por minutos, horas e dias, respectivamente.

A regra de exemplo na íntegra significa que, após três vezes a autenticação no SSH, resultará em uma nova regra de bloqueio de PF para esse host. As correspondências de regras são realizadas verificando primeiro as regras locais, uma após a outra, da mais específica à menos específica. Quando ocorre uma correspondência, as regras remote são aplicadas e o nome nfail e os campos de desativação são alterados pela regra remote correspondente.

30.6.2.2. Regras Remotas

As regras remotas são usadas para especificar como o blacklistd muda seu comportamento, dependendo do host remoto que está sendo avaliado no momento. Cada campo em uma regra remota é o mesmo que em uma regra local. A única diferença está na maneira como o blacklistd os usa. Para explicar, esta regra de exemplo é usada:

[remote]
203.0.113.128/25 *      *       *               =/25    =       48h

O campo de endereço pode ser um endereço IP (v4 ou v6), uma porta ou ambas. Isso permite definir regras especiais para um intervalo de endereços remotos específico, como neste exemplo. Os campos para tipo, protocolo e proprietário são identicamente interpretados como na regra local.

Porém, os campos de nome são diferentes: o sinal de igual (=) em uma regra remota diz ao blacklistd para usar o valor da regra local correspondente. Isso significa que a entrada da regra de firewall é obtida e o prefixo /25 (uma máscara de rede 255.255.255.128) é adicionada. Quando uma conexão desse intervalo de endereços é colocada na lista negra, toda a sub-rede é afetada. Um nome de âncora PF também pode ser usado aqui; nesse caso, o blacklisted adicionará regras para esse bloco de endereços à âncora desse nome. A tabela padrão é usada quando um curinga é especificado.

Um número personalizado de falhas na coluna nfail pode ser definido para um endereço. Isso é útil para exceções a uma regra específica, talvez para permitir a alguém uma aplicação menos rigorosa de regras ou um pouco mais de clemência nas tentativas de login. O bloqueio é desativado quando um asterisco é usado neste sexto campo.

As regras remotas permitem uma aplicação mais rigorosa dos limites das tentativas de logon, em comparação com as tentativas provenientes de uma rede local como um escritório.

30.6.3. Configuração do cliente no Blacklistd

Existem alguns pacotes de software no FreeBSD que podem utilizar a funcionalidade do blacklistd. Os dois mais proeminentes são ftpd(8) e sshd(8) para bloquear tentativas excessivas de conexão. Para ativar o blacklistd no daemon SSH, adicione a seguinte linha ao /etc/ssh/sshd_config:

UseBlacklist yes

Reinicie o sshd posteriormente para que essas alterações entrem em vigor.

A lista negra do ftpd(8) é ativada usando -B, em /etc/inetd.conf ou como uma flag no /etc/rc.conf assim:

ftpd_flags="-B"

Isso é tudo o que é necessário para que esses programas conversem com o blacklistd.

30.6.4. Gerenciamento do Blacklistd

O Blacklistd fornece ao usuário um utilitário de gerenciamento chamado blacklistctl(8). Ele exibe endereços e redes bloqueados que estão na lista negra pelas regras definidas em blacklistd.conf(5). Para ver a lista de hosts atualmente bloqueados, use dump combinado com -b assim.

# blacklistctl dump -b
      address/ma:port id      nfail   last access
213.0.123.128/25:22   OK      6/3     2019/06/08 14:30:19

Este exemplo mostra que houve 6 de três tentativas permitidas na porta 22 provenientes do intervalo de endereços 213.0.123.128/25. Há mais tentativas listadas do que são permitidas porque o SSH permite que um cliente tente vários logins em uma única conexão TCP. Uma conexão que está em andamento no momento não é interrompida pelo blacklistd. A última tentativa de conexão está listada na coluna last access da saída.

Para ver o tempo restante em que esse host estará na lista negra, adicione -r ao comando anterior.

# blacklistctl dump -br
      address/ma:port id      nfail   remaining time
213.0.123.128/25:22   OK      6/3     36s

Neste exemplo, restam 36 segundos para que este host não seja mais bloqueado.

30.6.5. Removendo hosts da lista de bloqueios

Às vezes, é necessário remover um host da lista de bloqueios antes que o tempo restante expire. Infelizmente, não há funcionalidade no blacklistd para fazer isso. No entanto, é possível remover o endereço da tabela PF usando pfctl. Para cada porta bloqueada, existe uma âncora filha dentro da âncora do blacklistd definida em /etc/pf.conf. Por exemplo, se houver uma âncora filha para bloquear a porta 22, ela será chamada blacklistd/22. Há uma tabela dentro dessa âncora filha que contém os endereços bloqueados. Essa tabela é chamada de port seguida pelo número da porta. Neste exemplo, ele seria chamada de port22. Com essas informações em mãos, agora é possível usar o pfctl(8) para exibir todos os endereços listados desta maneira:

# pfctl -a blacklistd/22 -t port22 -T show
...
213.0.123.128/25
...

Depois de identificar o endereço a ser desbloqueado da lista, o seguinte comando o remove da lista:

# pfctl -a blacklistd/22 -t port22 -T delete 213.0.123.128/25

O endereço agora foi removido do PF, mas ainda será exibido no blacklistctl, pois ele não conhece nenhuma alteração feita no PF. A entrada no banco de dados do blacklistd expirará e será removida de sua saída eventualmente. A entrada será adicionada novamente se o host estiver correspondendo a uma das regras de bloqueio no blacklistd novamente.

All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.