Por que o iptables não está bloqueando um endereço IP?

9

Eu configurei o fail2ban para monitorar um certo padrão de tráfego malicioso que estou obtendo e banir os endereços IP associados.

Tudo parece estar funcionando muito bem - o regex está correspondendo adequadamente ao padrão e o endereço IP do problema está sendo adicionado ao iptables.

No entanto, quando verifico os logs do Apache, ainda estou recebendo ocorrências do endereço IP que está sendo banido. É como se o iptables não estivesse funcionando.

Então, deixe-me compartilhar algumas especificidades apenas para confirmar que tudo está configurado corretamente.

Primeiro, vou limpar e recarregar as regras do iptables:

$ sudo iptables -F
$ cat /etc/iptables.firewall.rules 
*filter

#  Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT

#  Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#  Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

#  Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

#  Allow SSH connections
#
#  The -dport number should be the same port number you set in sshd_config
#
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

#  Allow ping
-A INPUT -p icmp -j ACCEPT

#  Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

#  Drop all other inbound - default deny unless explicitly allowed policy
-A INPUT -j DROP
-A FORWARD -j DROP

COMMIT
$ sudo iptables-restore < /etc/iptables.firewall.rules
$ sudo iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
    0     0 REJECT     all  --  *      *       0.0.0.0/0            127.0.0.0/8          reject-with icmp-port-unreachable
   14  1432 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    1    60 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:22
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           
    0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            limit: avg 5/min burst 5 LOG flags 0 level 7 prefix "iptables denied: "
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   11  1638 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0  

Agora, eis a aparência da configuração fail2ban:

$ cat /etc/fail2ban/filter.d/apache-xmlrpc.conf 
[Definition]
failregex = .*:80 <HOST> .*POST .*xmlrpc\.php.*
ignoreregex =
$ cat /etc/fail2ban/jail.local 
[apache-xmlrpc]

enabled  = true
port     = http,https
filter   = apache-xmlrpc
logpath  = /var/log/apache2/other_vhosts_access.log
maxretry = 6
$ fail2ban-regex /var/log/apache2/other_vhosts_access.log /etc/fail2ban/filter.d/apache-xmlrpc.conf 

Running tests
=============

Use regex file : /etc/fail2ban/filter.d/apache-xmlrpc.conf
Use log file   : /var/log/apache2/other_vhosts_access.log


Results
=======

Failregex
|- Regular expressions:
|  [1] .*:80 <HOST> .*POST .*xmlrpc\.php.*
|
`- Number of matches:
   [1] 29 match(es)

Ignoreregex
|- Regular expressions:
|
`- Number of matches:

Summary
=======

Addresses found:
[1]
    80.82.70.239 (Sat Jul 13 02:41:52 2013)
    80.82.70.239 (Sat Jul 13 02:41:53 2013)
    80.82.70.239 (Sat Jul 13 02:41:55 2013)
    80.82.70.239 (Sat Jul 13 02:41:56 2013)
    80.82.70.239 (Sat Jul 13 02:41:57 2013)
    80.82.70.239 (Sat Jul 13 02:41:58 2013)
    80.82.70.239 (Sat Jul 13 02:41:59 2013)
    80.82.70.239 (Sat Jul 13 02:42:00 2013)
    80.82.70.239 (Sat Jul 13 02:42:02 2013)
    80.82.70.239 (Sat Jul 13 02:42:03 2013)
    80.82.70.239 (Sat Jul 13 02:42:04 2013)
    80.82.70.239 (Sat Jul 13 02:42:05 2013)
    80.82.70.239 (Sat Jul 13 02:42:06 2013)
    80.82.70.239 (Sat Jul 13 02:42:07 2013)
    80.82.70.239 (Sat Jul 13 02:42:09 2013)
    80.82.70.239 (Sat Jul 13 02:42:10 2013)
    80.82.70.239 (Sat Jul 13 02:42:11 2013)
    80.82.70.239 (Sat Jul 13 02:42:12 2013)
    80.82.70.239 (Sat Jul 13 02:42:13 2013)
    80.82.70.239 (Sat Jul 13 02:42:15 2013)
    80.82.70.239 (Sat Jul 13 02:42:16 2013)
    80.82.70.239 (Sat Jul 13 02:42:17 2013)
    80.82.70.239 (Sat Jul 13 02:42:18 2013)
    80.82.70.239 (Sat Jul 13 02:42:19 2013)
    80.82.70.239 (Sat Jul 13 02:42:20 2013)
    80.82.70.239 (Sat Jul 13 02:42:22 2013)
    80.82.70.239 (Sat Jul 13 02:42:23 2013)
    80.82.70.239 (Sat Jul 13 02:42:24 2013)
    80.82.70.239 (Sat Jul 13 02:42:25 2013)

Date template hits:
0 hit(s): MONTH Day Hour:Minute:Second
0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second Year
0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second
0 hit(s): Year/Month/Day Hour:Minute:Second
0 hit(s): Day/Month/Year Hour:Minute:Second
0 hit(s): Day/Month/Year Hour:Minute:Second
70 hit(s): Day/MONTH/Year:Hour:Minute:Second
0 hit(s): Month/Day/Year:Hour:Minute:Second
0 hit(s): Year-Month-Day Hour:Minute:Second
0 hit(s): Year.Month.Day Hour:Minute:Second
0 hit(s): Day-MONTH-Year Hour:Minute:Second[.Millisecond]
0 hit(s): Day-Month-Year Hour:Minute:Second
0 hit(s): TAI64N
0 hit(s): Epoch
0 hit(s): ISO 8601
0 hit(s): Hour:Minute:Second
0 hit(s): <Month/Day/Year@Hour:Minute:Second>

Success, the total number of match is 29

However, look at the above section 'Running tests' which could contain important
information.

Como você pode ver, eu tenho um failregex configurado em um filtro e o filtro está ativado. Usando fail2ban-regex, o filtro encontra uma correspondência no arquivo de log que estou monitorando. (Estou sendo atingido por um endereço IP problemático no momento, o que está facilitando bastante o teste.)

Então agora eu reinicio o fail2ban e observo as regras entrando em vigor:

$ sudo service fail2ban restart
 * Restarting authentication failure monitor fail2ban                                                                                                                         [ OK ] 
$ tail /var/log/fail2ban.log -n 50
2013-07-13 02:42:58,014 fail2ban.server : INFO   Stopping all jails
2013-07-13 02:42:58,745 fail2ban.jail   : INFO   Jail 'apache-xmlrpc' stopped
2013-07-13 02:42:59,439 fail2ban.jail   : INFO   Jail 'ssh' stopped
2013-07-13 02:42:59,440 fail2ban.server : INFO   Exiting Fail2ban
2013-07-13 02:43:08,055 fail2ban.server : INFO   Changed logging target to /var/log/fail2ban.log for Fail2ban v0.8.6
2013-07-13 02:43:08,057 fail2ban.jail   : INFO   Creating new jail 'ssh'
2013-07-13 02:43:08,111 fail2ban.jail   : INFO   Jail 'ssh' uses Gamin
2013-07-13 02:43:08,397 fail2ban.filter : INFO   Added logfile = /var/log/auth.log
2013-07-13 02:43:08,404 fail2ban.filter : INFO   Set maxRetry = 6
2013-07-13 02:43:08,414 fail2ban.filter : INFO   Set findtime = 600
2013-07-13 02:43:08,435 fail2ban.actions: INFO   Set banTime = 600
2013-07-13 02:43:09,277 fail2ban.jail   : INFO   Creating new jail 'apache-xmlrpc'
2013-07-13 02:43:09,277 fail2ban.jail   : INFO   Jail 'apache-xmlrpc' uses Gamin
2013-07-13 02:43:09,283 fail2ban.filter : INFO   Added logfile = /var/log/apache2/other_vhosts_access.log
2013-07-13 02:43:09,286 fail2ban.filter : INFO   Set maxRetry = 6
2013-07-13 02:43:09,289 fail2ban.filter : INFO   Set findtime = 600
2013-07-13 02:43:09,292 fail2ban.actions: INFO   Set banTime = 600
2013-07-13 02:43:09,458 fail2ban.jail   : INFO   Jail 'ssh' started
2013-07-13 02:43:09,792 fail2ban.jail   : INFO   Jail 'apache-xmlrpc' started
2013-07-13 02:43:11,361 fail2ban.actions: WARNING [apache-xmlrpc] Ban 80.82.70.239
$ sudo iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  244 39277 fail2ban-apache-xmlrpc  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 80,443
  101  7716 fail2ban-ssh  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 22
    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
    0     0 REJECT     all  --  *      *       0.0.0.0/0            127.0.0.0/8          reject-with icmp-port-unreachable
 3404  582K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
  349 20900 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443
   12   720 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            state NEW tcp dpt:22
    0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           
    2    80 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            limit: avg 5/min burst 5 LOG flags 0 level 7 prefix "iptables denied: "
    2    80 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
 3331 4393K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain fail2ban-apache-xmlrpc (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       80.82.70.239         0.0.0.0/0           
  244 39277 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain fail2ban-ssh (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       223.4.147.8          0.0.0.0/0           
  101  7716 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0  

Como o log fail2ban mostra, o conjunto de regras parece estar configurado corretamente. Você já pode ver que o endereço IP problemático está sendo capturado imediatamente e banido. A saída do iptables mostra que ele está de fato sendo descartado.

No entanto, já estou observando que não há pacotes descartados para esse endereço IP que correspondam à cadeia fail2ban-apache-xmlrpc. Com certeza, verifico os logs do apache:

$ tail /var/log/apache2/other_vhosts_access.log
www.--SNIP--.com:80 80.82.70.239 - - [13/Jul/2013:02:43:53 +0000] "POST /xmlrpc.php HTTP/1.1" 403 474 "-" "-"
www.--SNIP--.com:80 80.82.70.239 - - [13/Jul/2013:02:43:54 +0000] "POST /xmlrpc.php HTTP/1.1" 403 474 "-" "-"
www.--SNIP--.com:80 80.82.70.239 - - [13/Jul/2013:02:43:56 +0000] "POST /xmlrpc.php HTTP/1.1" 403 474 "-" "-"
www.--SNIP--.com:80 80.82.70.239 - - [13/Jul/2013:02:43:57 +0000] "POST /xmlrpc.php HTTP/1.1" 403 474 "-" "-"
www.--SNIP--.com:80 80.82.70.239 - - [13/Jul/2013:02:43:58 +0000] "POST /xmlrpc.php HTTP/1.1" 403 474 "-" "-"
www.--SNIP--.com:80 80.82.70.239 - - [13/Jul/2013:02:43:59 +0000] "POST /xmlrpc.php HTTP/1.1" 403 474 "-" "-"
www.--SNIP--.com:80 80.82.70.239 - - [13/Jul/2013:02:44:00 +0000] "POST /xmlrpc.php HTTP/1.1" 403 474 "-" "-"
www.--SNIP--.com:80 80.82.70.239 - - [13/Jul/2013:02:44:02 +0000] "POST /xmlrpc.php HTTP/1.1" 403 474 "-" "-"

Não, não está sendo bloqueado! Também posso confirmar isso no log fail2ban:

$ tail /var/log/fail2ban.log
2013-07-13 02:52:30,757 fail2ban.actions: WARNING [apache-xmlrpc] 80.82.70.239 already banned
2013-07-13 02:52:37,767 fail2ban.actions: WARNING [apache-xmlrpc] 80.82.70.239 already banned
2013-07-13 02:52:44,783 fail2ban.actions: WARNING [apache-xmlrpc] 80.82.70.239 already banned
2013-07-13 02:52:51,814 fail2ban.actions: WARNING [apache-xmlrpc] 80.82.70.239 already banned
2013-07-13 02:52:58,830 fail2ban.actions: WARNING [apache-xmlrpc] 80.82.70.239 already banned
2013-07-13 02:53:05,842 fail2ban.actions: WARNING [apache-xmlrpc] 80.82.70.239 already banned
2013-07-13 02:53:11,858 fail2ban.actions: WARNING [apache-xmlrpc] Unban 80.82.70.239
2013-07-13 02:53:12,910 fail2ban.actions: WARNING [apache-xmlrpc] Ban 80.82.70.239
2013-07-13 02:53:20,118 fail2ban.actions: WARNING [apache-xmlrpc] 80.82.70.239 already banned
2013-07-13 02:53:27,129 fail2ban.actions: WARNING [apache-xmlrpc] 80.82.70.239 already banned

Ele continua reaparecendo no log do apache e, portanto, o fail2ban está tentando continuar banindo-o!

Honestamente, não consigo entender por que motivo o iptables não está descartando o tráfego desse endereço IP. A ordem das regras parece correta para mim, com a DROP chegando antes de qualquer outra coisa.

Eu tenho vários resultados no Google em que as pessoas estão tendo um problema semelhante, mas sempre parece voltar a um problema de proibir o tráfego SSH onde elas estão em uma porta fora do padrão. No meu caso, estou apenas tentando banir um endereço IP na porta http padrão 80.

Espero estar apenas negligenciando algo incrivelmente simples. Este é um VPS executando o Ubuntu 12.04 no Linode. Se alguém tiver alguma idéia por favor me avise. Muito Obrigado...

EDIT : Aqui está a saída deiptables -S

$ sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N fail2ban-apache-xmlrpc
-N fail2ban-ssh
-A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-apache-xmlrpc
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT --reject-with icmp-port-unreachable
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
-A INPUT -j DROP
-A FORWARD -j DROP
-A OUTPUT -j ACCEPT
-A fail2ban-apache-xmlrpc -s 80.82.70.239/32 -j DROP
-A fail2ban-apache-xmlrpc -j RETURN
-A fail2ban-ssh -s 223.4.147.8/32 -j DROP
-A fail2ban-ssh -j RETURN
jsdalton
fonte
A saída iptables -spode ser mais útil para nós do que o formato deiptables -L
Daniel Widrick
@ lVlint67 - editei minha pergunta para mostrar a saída de iptables -Spara você. Deixe-me saber se isso lhe dá mais informações.
jsdalton
A última entrada de log do Apache é às 02:44:02 e a primeira mensagem fail2ban de que o IP foi banido é às 02:52:30, portanto, não vejo nenhuma evidência de que ele não funcione. Forneça o fail2ban.log completo para o período.
mgorven
A primeira proibição que vejo do log fail2ban foi às 2:43, mas também notei as discrepâncias de tempo. NOTA: a proibição ocorre no So now I restart fail2ban and observe the rules taking effect:bloco #
Daniel Widrick 13/07/2013

Respostas:

10

A iptables -ssaída parece correta e não sei como 80.82.70.239/32é chegar ao any:80seu servidor através do firewall. Meu primeiro palpite é que você tem um proxy / balanceador de carga na frente do servidor e o Apache está registrando o HTTP_X_FORWARDED_FORcabeçalho ou como é chamado. Se esse for o caso, será necessário mover a lógica do firewall para o proxy / balanceador de carga ou para o nível do aplicativo (o Apache amarrando o FORWARDED_FORcabeçalho e negando acesso.


De qualquer jeito:

O próximo curso de ação que eu adotaria é capturar a saída de iptables -svocê postada acima. Desative fail2ban e carregue a configuração com a cadeia fail2ban e o endereço IP bloqueados nas tabelas de ip.

Mas faça-o com o seguinte como primeira -Aregra:

-A INPUT -p tcp --dport 80 -j LOG --log-prefix "HTTP: "

Se você se sentir melhor aprisionando 80 e 443, vá em frente. O pensamento é que os logs do FIREWALL podem mostrar algo que está faltando se prestarmos atenção nos pacotes de fontes suspeitas.

Daniel Widrick
fonte
3
Você acertou em cheio. Não sei por que não pensei nisso antes. Apache está correndo atrás Cloudflare e eu não tenho Apache configurado para registrar o endereço IP HTTP_FORWARDED_FOR. O tráfego real está chegando pelo servidor Cloudflare - portanto, tentar bloqueá-lo usando fail2ban / iptables não funcionará. Obrigado!
Jsdalton
Usamos balanceadores de carga haproxy no campus para lidar com LB e HA, assim eu me familiarizei com as pequenas 'peculiaridades' que a instalação traz. Não sei o que é o Cloudflare, mas se você tiver acesso adequado, é possível mudar a proibição para o balanceador de carga. ... Se isso não for possível, o Apache poderá lidar com o bloqueio com algum método, mas não estou familiarizado com isso no topo da minha cabeça.
Daniel Widrick
@jsdalton Qual foi a solução que você encontrou? Em um barco similar agora mesmo.
Jay
Como você precisa examinar os cabeçalhos http, está procurando algo chamado "Layer 7" filtering or firewall. Caso contrário, você pode tentar bloquear as tentativas no balanceador de carga / proxy, se isso estiver sob seu controle.
Daniel Widrick
1

A saída do iptables realmente mostra que, embora exista uma regra para o endereço IP fail2ban que deve ser filtrado e descartado, nenhum pacote passou pela cadeia fail2ban xmlrpc e foi realmente descartado por essa regra. Em vez disso, todos os 224 pacotes que passaram por essa cadeia foram aceitos.

Dito isto, as regras estão realmente corretas. No entanto, parece que mais tráfego foi aceito pela regra de aceitar a porta TCP 80 do que na cadeia de filtros fail2ban. O motivo mais provável é que o tráfego que você queria bloquear entrou enquanto a cadeia fail2ban ainda não estava inserida na entrada (note que você não o possui em suas regras padrão, o que provavelmente é bom, mas significa que se você recarregar as tabelas de ip a cadeia fail2ban não entrará em vigor imediatamente).

Tente correr iptables -zpara zerar a contagem de pacotes e observe a saída iptables -nvLnovamente. A saída não deve ser a mesma. Além disso, considere salvar as regras para as cadeias fail2ban nas regras iniciais para iptables ( /etc/iptables.firewall.rules). Salve as regras de delegação como esta:

fail2ban-apache-xmlrpc  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            multiport dports 80,443

Salve também a existência das cadeias (como fail2ban-apache-xmlrpc), mas não salve os IPs banidos reais.

Falcon Momot
fonte
Obrigado Falcon. Provavelmente porque eu limpei as regras do iptables e depois de alguns momentos eu reiniciei o fail2ban e as regras fail2ban-apache-xmlrpc foram adicionadas. No entanto, tentei zerar a contagem de pacotes e verificar novamente. O resultado foi praticamente o mesmo. Todos os pacotes que entram nas regras fail2ban-apache-xmlrpc estão sendo RETURNed e nenhum está sendo DROPed. Confirmei que meus logs do Apache ainda estão mostrando tráfego chegando naquele endereço IP que deveria estar caindo.
Jsdalton
1

Eu tive exatamente o mesmo problema que o seu no meu próprio site. Configuração muito semelhante, pilha LAMP, algumas cadeias fail2ban funcionais, ainda vi os endereços IP supostamente proibidos aparecendo no arquivo de log de acesso. Não tenho nenhum proxy / balanceador de carga na frente do Apache.

A solução para o meu problema foi surpreendentemente simples: mova as instruções de banimento para a parte superior do arquivo de configuração do iptables!

Haidong
fonte