rodando em Rocky Linux 9.2 com podman 4.4.1. Eu tenho um podman Pod com keycloak + postgresql dentro, rodando sem root. O próprio pod com --network 'slirp4netns:port_handler=slirp4netns'
. O contêiner keycloak está sendo executado, --log-driver json-file --log-opt path=/var/log/keycloak.log
então tenho o arquivo de log no próprio sistema host. Há também um proxy traefik que torna o keycloak acessível, terminação SSL no traefik + terminação SSL no próprio keycloak.
Tudo funciona até agora, vejo o endereço IP real de um usuário tentando fazer login nos logs. Fail2ban está sendo executado no sistema host, o regex também está funcionando e está banindo o endereço IP correto, MAS mesmo que o IP esteja banido (vejo isso em fail2ban-client status keycloak
), o usuário ainda pode continuar enviando logins.
/etc/fail2ban/jail.d/keycloak.local
[keycloak]
backend = auto
enabled = true
filter = keycloak
maxretry = 3
bantime = 86400
findtime = 86400
logpath = /var/log/keycloak.log
action = iptables-allports[name=keycloak]
Portanto, antes do banimento, o iptables estava vazio:
iptables -n -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Após a proibição:
iptables -n -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
f2b-keycloak tcp -- 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain f2b-keycloak (1 references)
target prot opt source destination
REJECT all -- xx.xx.xx.xx 0.0.0.0/0 reject-with icmp-port-unreachable
RETURN all -- 0.0.0.0/0 0.0.0.0/0
Eu também li algo sobre que o Docker está usando a cadeia FORWARD, então configurei action = iptables-allports[name=keycloak, protocol=all, chain=FORWARD]
no arquivo keycloak jail, o iptables tinha então a regra na cadeia FORWARD, mas ainda não estava funcionando. O mesmo comportamento de usar a configuração padrão (na cadeia INPUT).
Como posso fazer com que o contêiner podman sem root obedeça ao banimento de ip do iptables? Alguma ideia?
Responder1
Fail2ban funciona (por padrão) no nível do firewall, que funciona no nível do IP.
Dada a sua configuração, todo o tráfego é retransmitido por uma instância externa do Traefik cujo IP é o único que entra em contato com o Keycloak, o que significa que o firewall pode bloquear esse IP ou permiti-lo.
Se você deseja bloquear IPs com comportamento incorreto, você precisa bloqueá-los no host Traefik (dadas as informações que você forneceu).
Responder2
brincar com o cabeçalho fail2ban e X-Forwarded-For não seria uma solução satisfatória. Resolvi isso usando a abordagem da API opnsense. Resumo rápido:
- criou um usuário (chave de API) com as permissões para alias_util e endpoints de estados de firewall de diagnóstico.
- criou um alias
ipv4_blacklist
do tipo Externo (avançado) - criou uma regra de firewall para bloquear tudo desde a origem
ipv4_blacklist
- criou uma ação personalizada do keycloak usando
actionban
eactionunban
pois actionban
você precisa de dois comandos:
- Adicionando o IP fornecido à lista negra via
api/firewall/alias_util/add/ipv4_blacklist
- Eliminando as sessões ativas via
api/diagnostics/firewall/kill_states
, para que a ação de banimento entre em vigor imediatamente
para actionunban
um comando é suficiente:
- Simplesmente exclua o ip fornecido via
api/firewall/alias_util/delete/ipv4_blacklist