Use IPtables ou rota nula para colocar na lista negra cerca de 1 milhão de endereços IP?

21

Eu me deparei com uma situação em que um cliente precisa colocar na blacklist um conjunto de pouco menos de 1 milhão de endereços IP individuais (sem sub-redes), e o desempenho da rede é uma preocupação. Embora eu conjecture que as regras do IPTables teriam menos impacto sobre o desempenho do que as rotas, isso é apenas conjectura.

Alguém tem alguma evidência sólida ou outra justificativa para favorecer IPTables ou roteamento nulo como solução para a lista negra de longas listas de endereços IP? Nesse caso, tudo é automatizado, portanto, a facilidade de uso não é realmente uma preocupação.

EDIT 26-Nov-11

Após alguns testes e desenvolvimento, parece que nenhuma dessas opções é viável. Parece que as pesquisas de rota e iptables fazem buscas lineares através do conjunto de regras e demoram muito tempo para processar essas várias regras. No hardware moderno, colocar itens de 1M em uma lista negra do iptables reduz o servidor para cerca de 2 dúzias de pacotes por segundo. Então IPTables e rotas nulas estão fora.

ipset , como recomendado por Jimmy Hedman, seria ótimo, exceto pelo fato de não permitir que você rastreie mais de 65536 endereços em um conjunto, então não posso nem tentar usá-lo a menos que alguém tenha alguma ideia .

Aparentemente, a única solução para bloquear muitos IPs é fazer uma pesquisa indexada na camada de aplicativo. Não é assim?

Mais informações:

O caso de uso nesta instância está impedindo que uma lista de "endereços de ofensores conhecidos" de endereços IP acessem conteúdo estático em um servidor da web. FWIW, fazendo o bloqueio através do Deny from do Apache é igualmente lento (se não mais), como também faz uma varredura linear.

FYI: A solução final de trabalho foi usar o mod_rewrite do apache em conjunto com um mapa de banco de dados berkeley para fazer buscas na lista negra. A natureza indexada dos bancos de dados de Berkeley permitiu que a lista fosse dimensionada com o desempenho O (log N).

    
por tylerl 25.11.2011 / 23:31

6 respostas

15

tente usar o iptables e criar uma árvore de vários níveis para diminuir o número de pesquisas.

iptables -N rules_0_0_0_0_2
iptables -N rules_64_0_0_0_2
iptables -N rules_128_0_0_0_2
iptables -N rules_192_0_0_0_2
iptables -N rules_0_0_0_0_4
iptables -N rules_16_0_0_0_4

iptables -A INPUT -p tcp --dport 80 -s 0.0.0.0/2 -j rules_0_0_0_0_2
iptables -A INPUT -p tcp --dport 80 -s 64.0.0.0/2 -j rules_64_0_0_0_2
iptables -A INPUT -p tcp --dport 80 -s 128.0.0.0/4 -j rules_128_0_0_0_2
iptables -A INPUT -p tcp --dport 80 -s 192.0.0.0/4 -j rules_192_0_0_0_2

iptables -A rules_0_0_0_0_2 -s 0.0.0.0/4 -j rules_0_0_0_0_4
iptables -A rules_0_0_0_0_2 -s 16.0.0.0/4 -j rules_16_0_0_0_4

e assim por diante - adicionando níveis de aninhamento; Obviamente, você precisará de uma maneira automática de construir as regras e você deve ter cadeias apenas para as redes onde você tem um ou mais ofensores - desta forma você pode reduzir o número de pesquisas que devem ser feitas significativamente e eu acho que poderia realmente funciona.

    
por 26.11.2011 / 23:38
10

Isso é exatamente o que usa o ipset .

A partir do link do site :

Se você quiser

  • armazena vários endereços IP ou números de porta e corresponde à coleção pelo iptables de uma só vez;
  • atualiza dinamicamente as regras do iptables em relação a endereços IP ou portas sem penalidade de desempenho;
  • expressa um conjunto de regras de endereço IP e portas complexas com uma única regra iptables e se beneficia da velocidade dos conjuntos de IP

o ipset pode ser a ferramenta adequada para você.

É escrito por um membro da equipe do netfilter, Jozsef Kadlecsik (que também escreveu o alvo REJECT), então essa é a melhor escolha que eu posso imaginar.

Incluso nos kernels recentes.

    
por 26.11.2011 / 10:10
5

Eu não testei isso sozinho, mas quando ouvi a descrição do seu problema eu imediatamente pensei " pf " (como no OpenBSD).

pf tem o conceito de tabelas de endereços , que podem ser apenas o que você está procurando.

De acordo com algumas pesquisas muito muito que eu fiz, parece que isso tem o potencial de escalar melhor que ipset . De acordo com o capítulo de FAQ do PF sobre as opções de tempo de execução , pronto para uso sem ajuste, o pf suporta um total de 1.000 tabelas, com um total de 200.000 entradas em todas as tabelas por padrão. (100.000 se o sistema tiver < 100MB de memória física). Isso me leva a acreditar que pelo menos vale a pena considerar tentar testar isso para ver se funciona em qualquer nível útil.

Claro, eu estou supondo que você esteja executando seus servidores no Linux, então você teria que ter uma caixa de firewall separada executando algum sistema operacional com pf (como o OpenBSD ou FreeBSD). Você também pode melhorar o rendimento eliminando qualquer tipo de filtragem de pacotes com estado.

    
por 26.11.2011 / 23:42
2

Você já investigou usando um FIB_TRIE em vez de FIB_HASH.

FIB_TRIE deve ser dimensionado muito melhor para suas contagens de prefixo. (/ 32s rotas nulas ainda são prefixos, apenas muito específicas)

Você pode precisar compilar seu próprio kernel para usá-lo, mas ajuda.

Notas do FIB_TRIE

    
por 27.11.2011 / 00:53
1

Para a posteridade: de acordo com ipset docs, o tamanho padrão de um conjunto é 65536, isso pode ser alterado por opções.

maxelem This parameter is valid for the create command of all hash type sets. It does define the maximal number of elements which can be stored in the set, default 65536. Example: ipset create test hash:ip maxelem 2048.

Eu coloquei isso aqui porque não posso comentar ainda.

    
por 14.11.2015 / 20:53
0

Algumas observações úteis para quem se deparar com este problema no futuro:

Primeiro de tudo, não analise nenhum tráfego que você não precise. Se você está bloqueando o tráfego TCP, por exemplo, apenas filtre os pacotes SYN, dessa forma você só acessa o filtro uma vez por conexão. Você pode usar -m state , se desejar, mas o acompanhamento de conexão tem sua própria sobrecarga que você pode evitar se o desempenho for um problema.

Segundo, colocar um milhão de regras no iptables leva muito tempo: vários minutos. Se você precisa rastrear muitas entidades, provavelmente seria melhor mantê-lo fora do netfliter. O tamanho do conjunto de regras faz a diferença.

Em terceiro lugar, o objetivo é evitar varreduras lineares; mas infelizmente, tanto o iptables quanto o iproute2 são inerentemente lineares. Você pode dividir suas regras em estilo de árvore binária em um grande número de cadeias, o que limita o número de regras que você precisa consultar, mas mesmo assim, o iptables não é adequado para esse tamanho de problema. funcionará , mas é um desperdício de recursos valiosos.

Em quarto lugar, e mais importante, empurrar sua carga de trabalho para o userspace não é uma má idéia. Isso permite que você escreva seu próprio código ou use uma solução pronta para uso ajustada ao seu conjunto de problemas. Minha própria solução para esse problema, como mencionado, era usar pesquisas BDB acionadas através do sistema mod_rewrite do apache. Isso teve o benefício adicional de acionar apenas uma pesquisa por sessão e somente depois que uma solicitação válida foi enviada. Nesse caso, o desempenho foi extremamente rápido e o custo da lista de bloqueio foi quase insignificante.

Você pode fazer manipulação de espaço do usuário semelhante com o iptables usando o -j QUEUE target em conjunto com libnetfilter_queue . Essa ferramenta é poderosa, simples e mal documentada. Eu recomendaria ler o máximo possível de quantas fontes você puder encontrar, pois há muitos materiais interessantes espalhados pela Web que não fazem parte de nenhuma documentação oficial.

    
por 19.09.2013 / 06:40