Descartando pedidos de entrada para um arquivo específico com iptables

1

Servidor é uma pilha LAMP padrão configurada via cpanel no CentOS 5.9.

Temos um arquivo chamado bad.php em um dos nossos domínios que está sendo acessado por engano, aproximadamente 10 vezes por segundo, por um provedor de serviços. O arquivo não existe mais e queremos bloquear essas solicitações da maneira mais eficiente possível. Atualmente, estamos retornando 410 respostas básicas, mas isso ainda envolve amarrar tópicos do apache, enviar cabeçalhos, etc.

Idealmente, quero apenas descartar as solicitações, não enviando nenhuma resposta. O bloqueio por IP não é uma opção, porque precisamos permitir que esses IPs acessem legitimamente outros arquivos. (E não, nós não podemos simplesmente pedir-lhes para parar.) Nós também não temos um firewall externo para trabalhar com (servidor arrendado, custos de firewall externos personalizados extras).

Meu pensamento é que a melhor opção seria uma regra do iptables como esta:

iptables -I INPUT -p tcp --dport 80 --destination [ip address] -m string \
    --algo kmp --string "bad\.php" -j DROP

Duas perguntas:

Primeiro, tentei essa regra (com o endereço IP do domínio no lugar do endereço IP), mas não teve efeito. Foi a primeira regra mostrada pelo iptables -L, então não deve ser sobrescrita por uma regra anterior:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       tcp  --  anywhere             [ip address]       tcp dpt:http STRING match "bad\.php" ALGO name kmp TO 65535

Eu estraguei tudo em algum lugar lá? Eu sou muito mais noob do iptables.

A segunda pergunta é, há alguma ressalva para isso? Haverá sobrecarga significativa com string iptables corresponder a cada solicitação (em comparação com o Apache RewriteRule com R = 410, como estamos usando agora)? Eu estou melhor apenas vivendo com isso? Ou existe uma opção melhor? (mod_security talvez?) O servidor não está perto de ser tenso, então não é uma necessidade, apenas uma otimização.

Edite em resposta a Saurabh Barjatiya:

Aqui está tudo o que vejo do tcpdump quando faço uma solicitação para o arquivo bad.php:

20:21:09.740217 IP [clientIP].62790 > [serverIP].http: S 3454863895:3454863895(0) win 8192 <mss 1460,nop,wscale 2,nop,nop,sackOK>
20:21:09.740243 IP [serverIP].http > [clientIP].62790: S 4112555138:4112555138(0) ack 3454863896 win 5840 <mss 1460,nop,nop,sackOK,nop,wscale 7>
20:21:09.838595 IP [clientIP].62790 > [serverIP].http: . ack 1 win 16425
20:21:09.838606 IP [clientIP].62790 > [serverIP].http: . 1:1461(1460) ack 1 win 16425
20:21:09.838622 IP [serverIP].http > [clientIP].62790: . ack 1461 win 69
20:21:09.838632 IP [clientIP].62790 > [serverIP].http: P 1461:1476(15) ack 1 win 16425
20:21:09.838638 IP [serverIP].http > [clientIP].62790: . ack 1476 win 69

Obviamente, a string de url real não está aqui. No entanto, meu entendimento é que o iptables pode filtrar por strings de url, então presumivelmente estou checando a coisa errada.

    
por Nathan Stretch 07.03.2013 / 03:09

1 resposta

0

O palpite é que a regra do iptables usará mais CPU que a configuração do apache. Mas, no entanto, é interessante usar o iptables para bloquear solicitações recebidas. Como as requisições não são gzipadas e elas também são geralmente em um único pacote, não vejo qualquer restrição à sua lógica.

Para entender por que a regra atual não está funcionando, tenho duas sugestões:

  1. Remova -d por algum tempo e veja se a regra funciona. Você pode ter cometido um erro bobo ao interpretar o IP de destino
  2. Capture os pacotes usando tcpdump ou wireshark e analise-os para ver as sequências que você pode encontrar em solicitações de bad.php. Isso também ajudará na verificação de que todas as solicitações bad.php realmente contêm bad.php conforme o esperado. Às vezes, as regras de reescrita locais podem fazer com que as solicitações sejam enviadas para bad.php, enquanto a solicitação original no pacote é para o good.php, fazendo com que a regra do iptables falhe.
por 07.03.2013 / 04:02