Leitor de longa data, pôster da primeira vez .. yada yada yada ..
De qualquer forma, espero que alguém tenha alguma experiência com o módulo iptables / netfilter LIMIT ou HASHLIMIT e explique o comportamento que estou presenciando.
Histórico: Temos um servidor da Web e queremos limitar quantas conexões um cliente pode ter ao longo de um mês (os keepalives HTTP estão desativados, por coincidência). Então, estou tentando usar o módulo LIMIT do iptables para limitar o número de suas novas conexões a um número definido por mês (digamos 500). O módulo LIMIT iptables usa um algoritmo de "token bucket", então eu deveria ser capaz de definir o limite-burst (tamanho do balde) para 500 e o limite (taxa de recarga) para 500 dividido por 28 dias ou cerca de 18 / dia. Isso fará com que a caçamba seja reabastecida no prazo de um mês (4 semanas), se for completamente esvaziada. (Eu entendo que isso vai realmente conceder mais do que exatamente 500, mas deve estar perto o suficiente para as nossas necessidades).
Aqui estão as minhas regras de iptables (Nós agrupamos IPs usando o ipset. LimBurTest4 contém minhas máquinas de teste de fonte)
Chain INPUT (policy DROP 2316 packets, 186K bytes)
pkts bytes target prot opt in out source destination
2952K 626M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED /* Accept outgoing return traffic */
379 13702 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8 state NEW limit: avg 1/sec burst 1
377 30868 DROP icmp -- * * 0.0.0.0/0 0.0.0.0/0
0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:0x3F/0x00 /* Block NULL packets */
73 14728 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:!0x17/0x02 state NEW /* Block SYN flood */
0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:0x3F/0x3F /* Block XMAS packets */
24 120 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 match-set LimBurTest4 src tcp dpt:443 limit: avg 18/day burst 500 /* LimitBurst Test */
76 30180 LOG tcp -- * * 0.0.0.0/0 0.0.0.0/0 match-set LimBurTest4 src tcp dpt:443 /* LimitBurst Testing */ LOG flags 0 level 4 prefix "LimBurTest Over Quota "
2522 138K REJECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 /* Reject queries */ reject-with tcp-reset
Eu adiciono a regra LIMIT assim:
iptables -I INPUT 7 -m set --match-set LimBurTest4 src -p tcp --dport 443 -m limit --limit 18/day --limit-burst 500 -m comment --comment "Limit Burst Test" -j ACCEPT
Teste: Em seguida, criei um script de shell simples para fazer solicitações ao meu servidor da Web, uma após a outra, usando o curl. Cada solicitação bem-sucedida demora cerca de 0,20 ms. A saída do script é assim:
./limBurTest.sh
1 - 200 - 0.257 ms
2 - 200 - 0.193 ms
3 - 200 - 0.155 ms
etc.
etc.
Resultado: Minha expectativa dessa configuração seria rapidamente (em alguns segundos) usar todas as 500 conexões antes de começar a ver as conexões rejeitadas. No entanto, isso não está acontecendo de jeito nenhum. Em vez disso, meu script de teste fez 24 conexões bem-sucedidas e o restante foi rejeitado. Por exemplo, na saída acima do iptables, executei meu shell script em um loop 100 vezes e você pode ver 24 correspondências de regras ACCEPT e 76 correspondências de regras de LOG após a regra ACCEPT. Eu testei isso no CentOS 6.8 e no Ubuntu 16.04 e ambos se comportam dessa maneira, mas isso parece contrário à documentação. Por que não posso usar todas as 500 conexões especificadas por limite de burst?
E, sim, é claro, eu pesquisei bastante e vi muitos exemplos de pessoas dizendo que o módulo LIMIT deve funcionar exatamente como descrevi. E eu li os documentos do netfilter várias vezes.
O que estou perdendo aqui?
Obrigado antecipadamente.