Estou tentando habilitar o fail2ban no Centos 7 com Apache. Eu tenho um aplicativo que grava no log de erros uma string específica quando o login falha.
responde com o endereço IP correto na lista de IP banidos,
> fail2ban-client status appname
Status for the jail: appname
|- Filter
| |- Currently failed: 1
| |- Total failed: 7
| `- File list: /var/log/httpd/api.appname-error.log
`- Actions
|- Currently banned: 1
|- Total banned: 3
`- Banned IP list: 10.50.0.68
Mas quando olho no iptables vejo que ele bloqueia todo o tráfego de entrada na linha 1 que corresponde ao meu aplicativo, EDITADO: adicionado iptables mais detalhados no final da pergunta
> iptables -L INPUT --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 REJECT tcp -- anywhere anywhere multiport dports https,http match-set f2b-appname src reject-with icmp-port-unreachable
2 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
3 ACCEPT all -- anywhere anywhere
4 INPUT_direct all -- anywhere anywhere
5 INPUT_ZONES_SOURCE all -- anywhere anywhere
6 INPUT_ZONES all -- anywhere anywhere
7 DROP all -- anywhere anywhere ctstate INVALID
8 REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Aqui está meu filtro, /etc/fail2ban/filter.d/appname.conf:
[Definition]
failregex = client <HOST>(.*)fail2ban\-appname\-login\-fail
O jail.local é curto:
[DEFAULT]
bantime = 1200
findtime = 3600
maxmatches = 4
[appname]
enabled = true
filter = appname
action = iptables-ipset-proto6[name=appname, port="https,http", protocol=tcp]
logpath = /var/log/httpd/api.appname-error.log
maxretry = 3
mode = normal
backend = auto
E uma linha típica do arquivo de log do Apache php:
[Sun Nov 26 10:22:31.255875 2023] [php7:notice] [pid 1837] [client 10.50.0.68:36530] fail2ban-appname-login-fail
Uma saída mais detalhada do iptables:
> sudo iptables-save -c
# Generated by iptables-save v1.4.21 on Mon Nov 27 07:42:05 2023
*nat
:PREROUTING ACCEPT [18229:1086560]
:INPUT ACCEPT [17668:1053268]
:OUTPUT ACCEPT [10696:675656]
:POSTROUTING ACCEPT [10696:675656]
:OUTPUT_direct - [0:0]
:POSTROUTING_ZONES - [0:0]
:POSTROUTING_ZONES_SOURCE - [0:0]
:POSTROUTING_direct - [0:0]
:POST_public - [0:0]
:POST_public_allow - [0:0]
:POST_public_deny - [0:0]
:POST_public_log - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_public - [0:0]
:PRE_public_allow - [0:0]
:PRE_public_deny - [0:0]
:PRE_public_log - [0:0]
[18230:1087136] -A PREROUTING -j PREROUTING_direct
[18230:1087136] -A PREROUTING -j PREROUTING_ZONES_SOURCE
[18230:1087136] -A PREROUTING -j PREROUTING_ZONES
[10696:675656] -A OUTPUT -j OUTPUT_direct
[10696:675656] -A POSTROUTING -j POSTROUTING_direct
[10696:675656] -A POSTROUTING -j POSTROUTING_ZONES_SOURCE
[10696:675656] -A POSTROUTING -j POSTROUTING_ZONES
[2972:212273] -A POSTROUTING_ZONES -o eth0 -g POST_public
[7724:463383] -A POSTROUTING_ZONES -g POST_public
[10696:675656] -A POST_public -j POST_public_log
[10696:675656] -A POST_public -j POST_public_deny
[10696:675656] -A POST_public -j POST_public_allow
[18229:1086560] -A PREROUTING_ZONES -i eth0 -g PRE_public
[1:576] -A PREROUTING_ZONES -g PRE_public
[18230:1087136] -A PRE_public -j PRE_public_log
[18230:1087136] -A PRE_public -j PRE_public_deny
[18230:1087136] -A PRE_public -j PRE_public_allow
COMMIT
# Completed on Mon Nov 27 07:42:05 2023
# Generated by iptables-save v1.4.21 on Mon Nov 27 07:42:05 2023
*mangle
:PREROUTING ACCEPT [315975:53668565]
:INPUT ACCEPT [315975:53668565]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [301701:219207592]
:POSTROUTING ACCEPT [301701:219207592]
:FORWARD_direct - [0:0]
:INPUT_direct - [0:0]
:OUTPUT_direct - [0:0]
:POSTROUTING_direct - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_public - [0:0]
:PRE_public_allow - [0:0]
:PRE_public_deny - [0:0]
:PRE_public_log - [0:0]
[315976:53669141] -A PREROUTING -j PREROUTING_direct
[315976:53669141] -A PREROUTING -j PREROUTING_ZONES_SOURCE
[315976:53669141] -A PREROUTING -j PREROUTING_ZONES
[315975:53668565] -A INPUT -j INPUT_direct
[0:0] -A FORWARD -j FORWARD_direct
[301701:219207592] -A OUTPUT -j OUTPUT_direct
[301701:219207592] -A POSTROUTING -j POSTROUTING_direct
[170984:20172057] -A PREROUTING_ZONES -i eth0 -g PRE_public
[144992:33497084] -A PREROUTING_ZONES -g PRE_public
[315976:53669141] -A PRE_public -j PRE_public_log
[315976:53669141] -A PRE_public -j PRE_public_deny
[315976:53669141] -A PRE_public -j PRE_public_allow
COMMIT
# Completed on Mon Nov 27 07:42:05 2023
# Generated by iptables-save v1.4.21 on Mon Nov 27 07:42:05 2023
*security
:INPUT ACCEPT [315132:53613699]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [301701:219207592]
:FORWARD_direct - [0:0]
:INPUT_direct - [0:0]
:OUTPUT_direct - [0:0]
[315132:53613699] -A INPUT -j INPUT_direct
[0:0] -A FORWARD -j FORWARD_direct
[301701:219207592] -A OUTPUT -j OUTPUT_direct
COMMIT
# Completed on Mon Nov 27 07:42:05 2023
# Generated by iptables-save v1.4.21 on Mon Nov 27 07:42:05 2023
*raw
:PREROUTING ACCEPT [315975:53668565]
:OUTPUT ACCEPT [301701:219207592]
:OUTPUT_direct - [0:0]
:PREROUTING_ZONES - [0:0]
:PREROUTING_ZONES_SOURCE - [0:0]
:PREROUTING_direct - [0:0]
:PRE_public - [0:0]
:PRE_public_allow - [0:0]
:PRE_public_deny - [0:0]
:PRE_public_log - [0:0]
[315976:53669141] -A PREROUTING -j PREROUTING_direct
[315976:53669141] -A PREROUTING -j PREROUTING_ZONES_SOURCE
[315976:53669141] -A PREROUTING -j PREROUTING_ZONES
[301701:219207592] -A OUTPUT -j OUTPUT_direct
[170984:20172057] -A PREROUTING_ZONES -i eth0 -g PRE_public
[144992:33497084] -A PREROUTING_ZONES -g PRE_public
[315976:53669141] -A PRE_public -j PRE_public_log
[315976:53669141] -A PRE_public -j PRE_public_deny
[315976:53669141] -A PRE_public -j PRE_public_allow
COMMIT
# Completed on Mon Nov 27 07:42:05 2023
# Generated by iptables-save v1.4.21 on Mon Nov 27 07:42:05 2023
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [132432:168012162]
:FORWARD_IN_ZONES - [0:0]
:FORWARD_IN_ZONES_SOURCE - [0:0]
:FORWARD_OUT_ZONES - [0:0]
:FORWARD_OUT_ZONES_SOURCE - [0:0]
:FORWARD_direct - [0:0]
:FWDI_public - [0:0]
:FWDI_public_allow - [0:0]
:FWDI_public_deny - [0:0]
:FWDI_public_log - [0:0]
:FWDO_public - [0:0]
:FWDO_public_allow - [0:0]
:FWDO_public_deny - [0:0]
:FWDO_public_log - [0:0]
:INPUT_ZONES - [0:0]
:INPUT_ZONES_SOURCE - [0:0]
:INPUT_direct - [0:0]
:IN_public - [0:0]
:IN_public_allow - [0:0]
:IN_public_deny - [0:0]
:IN_public_log - [0:0]
:OUTPUT_direct - [0:0]
[459:26548] -A INPUT -p tcp -m multiport --dports 443,80 -m set --match-set f2b-appname src -j REJECT --reject-with icmp-port-unreachable
[289740:52097048] -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[7724:463383] -A INPUT -i lo -j ACCEPT
[17676:1053754] -A INPUT -j INPUT_direct
[17676:1053754] -A INPUT -j INPUT_ZONES_SOURCE
[17676:1053754] -A INPUT -j INPUT_ZONES
[8:486] -A INPUT -m conntrack --ctstate INVALID -j DROP
[0:0] -A INPUT -j REJECT --reject-with icmp-host-prohibited
[0:0] -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A FORWARD -i lo -j ACCEPT
[0:0] -A FORWARD -j FORWARD_direct
[0:0] -A FORWARD -j FORWARD_IN_ZONES_SOURCE
[0:0] -A FORWARD -j FORWARD_IN_ZONES
[0:0] -A FORWARD -j FORWARD_OUT_ZONES_SOURCE
[0:0] -A FORWARD -j FORWARD_OUT_ZONES
[0:0] -A FORWARD -m conntrack --ctstate INVALID -j DROP
[0:0] -A FORWARD -j REJECT --reject-with icmp-host-prohibited
[144991:33496508] -A OUTPUT -o lo -j ACCEPT
[156710:185711084] -A OUTPUT -j OUTPUT_direct
[0:0] -A FORWARD_IN_ZONES -i eth0 -g FWDI_public
[0:0] -A FORWARD_IN_ZONES -g FWDI_public
[0:0] -A FORWARD_OUT_ZONES -o eth0 -g FWDO_public
[0:0] -A FORWARD_OUT_ZONES -g FWDO_public
[0:0] -A FWDI_public -j FWDI_public_log
[0:0] -A FWDI_public -j FWDI_public_deny
[0:0] -A FWDI_public -j FWDI_public_allow
[0:0] -A FWDI_public -p icmp -j ACCEPT
[0:0] -A FWDO_public -j FWDO_public_log
[0:0] -A FWDO_public -j FWDO_public_deny
[0:0] -A FWDO_public -j FWDO_public_allow
[17676:1053754] -A INPUT_ZONES -i eth0 -g IN_public
[0:0] -A INPUT_ZONES -g IN_public
[17676:1053754] -A IN_public -j IN_public_log
[17676:1053754] -A IN_public -j IN_public_deny
[17676:1053754] -A IN_public -j IN_public_allow
[0:0] -A IN_public -p icmp -j ACCEPT
[11:660] -A IN_public_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[17651:1052260] -A IN_public_allow -p tcp -m tcp --dport 80 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
[6:348] -A IN_public_allow -p tcp -m tcp --dport 3306 -m conntrack --ctstate NEW,UNTRACKED -j ACCEPT
COMMIT
# Completed on Mon Nov 27 07:42:05 2023
Eu esperava que o endereço IP aparecesse na "fonte" do iptables -L INPUT --line-numbers e fiquei surpreso ao ver "em qualquer lugar".
Não entendo, se o fail2ban mostra meu endereço IP na lista de IP banidos, por que ele não usa apenas esse endereço IP no iptables?
Como posso diagnosticar ou corrigir isso?
Te agradece!
A linha:
é equivalente a:
Se todas as correspondências forem avaliadas como verdadeiras, a regra de destino (introduzida com
-j
) será executada. Se alguma correspondência for avaliada como falsa, isso interromperá o processamento da regra antes de atingir a regra de destino, continuando para a próxima regra.Ter uma condição adicional como: " e também corresponder a qualquer endereço IP de origem" que seria
-s 0.0.0.0/0
ou como " e também corresponder a qualquer endereço IP de destino" (-d 0.0.0.0/0
) que são sempre verdadeiras, não altera o resultado (com raciocínio lógico: (x E verdadeiro) <=> x). Isso é tão comum que, embora o iptables (quando ainda eraiptables-legacy
) sempre armazenasse essas informações de origem e destino, mesmo com 0.0.0.0/0, elas não são exibidas nas saídas do conjunto de regras destinadas a serem reproduzidas ( ouiptables-save
)iptables -S
, mas ainda são exibidas comoanywhere
porqueiptables -L
de qualquer maneira, há uma coluna fixa para essas informações.O que importa aqui é o ipset visto na configuração do fail2ban:
que adicionam endereços IP recuperados de logs (quando as condições para tais logs se aplicam, etc., geralmente erros)...
... e o
-m set
módulo de correspondência associado na regra do iptables . Esta regra informa que para as portas TCP de destino 443 ou 80 de entrada (caso contrário, não irá mais longe) ele fará uma pesquisa pelo endereço de origem no conjunto ipsetf2b-appname
e avaliará como verdadeiro se for encontrado, levando ao terminal (sem processamento adicional )REJECT
alvo: o banimento, ou então continue para a próxima regra no conjunto de regras.Isso significa que fail2ban usa o comando
ipset
para adicionar entradas IP a um conjunto de IP , que pode então ser verificado (durante o caminho do pacote) pelo iptables que reagirá rejeitando qualquer correspondência.Então, para verificar o que foi adicionado, execute:
ou mais precisamente no caso de haver outros:
que deve terminar com algo semelhante a:
Notas:
iptables-ipset-proto6
apesar do nome lidar com IPv4 e IPv6 (verificando/etc/fail2ban/action.d/iptables-ipset-proto6.conf
->iptables-ipset.conf
que trata cada protocolo de maneira diferente)ipset
aceita subcomandos começando com ou sem--
por razões históricas.