Estou com um problema ao configurar meu firewalld para ter um link perfeito com o docker e o fail2ban.
Primeiro, o que quero alcançar é a seguinte configuração de roteamento de tráfego:
[PUBLIC] ->
[FIREWALLD] -> (
[143/tcp FORWARD PORT] -----> [DOCKER/143/tcp]
[ 22/tcp] -----> [openssh locally running]
)
falha2banimento
Configurei o fail2ban para ouvir meu contêiner docker, verificar erros de autenticação e configurar um ban usando firewall-cmd
. Isso funciona até agora. Assim que eu erro de autenticação 3 vezes, ele envia um comando para o firewalld.
Encaminhamento de porta
Eu também configurei o encaminhamento de porta para o docker. Estou configurando explicitamente, porque não quero que o docker destrua minha rede. Talvez isso seja algo que eu não precise no futuro, mas é configurado por meio da StrictForwardPorts=yes
configuração. https://firewalld.org/2024/11/strict-forward-ports
Meta
O objetivo é que sempre que um gatilho fail2ban acontecer, o IP não tenha mais acesso à porta 143 (encaminhada) e (talvez) nem às outras. Mas, a princípio, eu gostaria de banir por porta.
Problema
O problema atualmente é que, se uma regra de rejeição avançada for criada, ela bloqueará a porta 22 para esse IP, mas não a porta 143.
Tentativas
Eu também tentei colocar o IP na drop
zona, dando a ele a prioridade -10
. Mesmo resultado de erro. A porta 22 é descartada, mas a 143 ainda funciona.
O que estou fazendo errado? Aqui está minha configuração de zona da última tentativa:
docker (active)
target: ACCEPT
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces: br-0aa8d4b5dde7 docker0
sources:
services:
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule priority="-999" family="ipv4" source address="192.168.178.44" reject
drop (active)
target: DROP
ingress-priority: -10
egress-priority: -10
icmp-block-inversion: no
interfaces:
sources: 192.168.178.44
services:
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
public (default, active)
target: default
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces:
sources:
services: dhcpv6-client ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
port=143:proto=tcp:toport=143:toaddr=172.18.0.2
source-ports:
icmp-blocks:
rich rules:
rule priority="-999" family="ipv4" source address="192.168.178.44" reject
Como visto: Na verdade, o endereço 192.168.178.44 deveria estar totalmente bloqueado para a zona pública. Mas não está. Além disso, adicionei o IP à drop zone. Parece que a prioridade da drop zone está funcionando, pois minha conexão SSH é descartada em vez de rejeitada, mas a porta 143 ainda está acessível
Atualização 1: Algumas informações de depuração
$ sudo firewall-cmd --get-policies
allow-host-ipv6 docker-forwarding
Atualização 2: --info-policy=docker-forwarding
docker-forwarding (active)
priority: -1
target: ACCEPT
ingress-zones: ANY
egress-zones: docker
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules: `
Atualização 3:
Outra ideia que me veio à mente foi criar outra política com prioridade -10, contendo a regra rica:
sudo firewall-cmd --permanent --new-policy ban-pre-routing
sudo firewall-cmd --permanent --policy ban-pre-routing --add-ingress-zone ANY
sudo firewall-cmd --permanent --policy ban-pre-routing --add-egress-zone HOST
sudo firewall-cmd --permanent --policy ban-pre-routing --set-priority -10
sudo firewall-cmd --permanent --policy ban-pre-routing --add-rich-rule="rule family=ipv4 source address=192.168.178.44 port port=143 protocol=tcp reject"
Ainda sem efeito. Meu Host *.44 ainda pode se conectar à máquina. Se eu deixar de fora a port port=143 protocol=tcp
parte, ele bloquearia a máquina para ssh - enquanto ainda seria capaz de acessar a porta 143.
Atualização 4: Usando a Atualização 3 com a política configurada para egress zone docker, não resulta em diferença. Minhas configurações estão assim agora:
$ sudo firewall-cmd --list-all-policies
allow-host-ipv6 (active)
priority: -15000
target: CONTINUE
ingress-zones: ANY
egress-zones: HOST
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv6" icmp-type name="neighbour-advertisement" accept
rule family="ipv6" icmp-type name="neighbour-solicitation" accept
rule family="ipv6" icmp-type name="redirect" accept
rule family="ipv6" icmp-type name="router-advertisement" accept
ban-pre-routing (active)
priority: -10
target: CONTINUE
ingress-zones: ANY
egress-zones: docker
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="192.168.178.44" port port="143" protocol="tcp" reject
docker-forwarding (active)
priority: -1
target: ACCEPT
ingress-zones: ANY
egress-zones: docker
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
E para zonas:
$ sudo firewall-cmd --list-all --zone=public
public (default, active)
target: default
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces:
sources:
services: dhcpv6-client ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
port=143:proto=tcp:toport=143:toaddr=172.18.0.2
source-ports:
icmp-blocks:
rich rules:
$ sudo firewall-cmd --list-all --zone=drop
drop
target: DROP
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
$ sudo firewall-cmd --list-all --zone=docker
docker (active)
target: ACCEPT
ingress-priority: 0
egress-priority: 0
icmp-block-inversion: no
interfaces: br-c5f172e4effe docker0
sources:
services:
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
Também postei uma postagem na página do firewalld no github. Lá, o usuário erig0 me apontou qual era o problema real. Veja a discussão do GitHub
Como o encaminhamento de porta é definido com uma prioridade muito maior do que qualquer outra coisa no kernel do Linux, a regra de encaminhamento de porta é levada em consideração e todo o resto que vem depois é ignorado.
É por isso que nenhuma das minhas tentativas de bloquear a porta usando o método padrão funcionou.
Veja como configurar todo o encaminhamento de porta com uma opção de bloqueio (específica de porta) usando
firewalld
:Obtenha uma cópia limpa da
firewalld
configuração (se necessário)Desvantagem: Desligue
iptables
para docker. Para fazer isso, certifique-se de que/etc/docker/daemon.json
existeiptables
propriedade está definida parafalse
iptables
. Caso contrário, você se verá em uma situação em que o docker permite tráfego independentemente da configuração do seu firewall.Agora, reconfigure a comunicação docker-container.
docker
zona predefinida defirewalld
: ⚠️ Certifique-se de adicionar todas as sub-redes que você precisa - com o comando acima. No meu caso, eu também tinha um ambiente docker-compose rodando no172.18.0.1/16 subnet
.Habilitar comunicação container-outbound (se desejado). Isso também diz respeito à comunicação container2container (host internamente):
Esses comandos irão
Como resultado, seu contêiner deve ser capaz de ter sucesso
curl google.com
.Por último, mas não menos importante, habilite o acesso externo aos contêineres docker se permitido pelo encaminhamento de porta:
Agora, tudo está conectado para encaminhamento de porta puramente de
firewalld
, o docker deixa seus dedos fora do caminho. Configurar o encaminhamento de porta em si agora é direto.Configure um IPset (se necessário, um IPset dedicado por porta(-set) - você decidirá). Este IPset conterá todos os endereços IP bloqueados para aquela porta(-set) específica
Adicione uma nova política para encaminhamento de porta:
O que essa regra faz:
143/tcp
, EEsta é a configuração completa do firewall. Para adicionar um IP, execute:
E para habilitá-lo novamente para acesso:
Tenha em mente que, se você fornecer
--permanent
, você tem que recarregar o firewall. Para ter mudanças imediatas em vigor, deixe de fora--permanent
ao executar o comando - No entanto, você terá que ter em mente que esse ip desaparece da lista após o próximo recarregamento/reinicialização/reinicialização.