Um fenômeno peculiar está em minha mente. Como você deve saber, lidar com um servidor de e-mail diretamente exposto à Internet pode ser uma grande “alegria” para vários indivíduos que tentam invadi-lo ou usá-lo como retransmissor. Não tenho problemas em bloquear manualmente endereços ou intervalos que me incomodam através do firewall, mesmo que isso exija algum esforço. Não estou muito interessado em automatizar todo o processo com fail2ban; Prefiro saber o que está ‘acontecendo’.
Então, criei várias regras com iptables e ip6tables, e seu número quase atingiu um patamar. No entanto, para manter alguma aparência de organização, gostaria de relacionar a quantidade de IPs V4 e intervalos V4 bloqueados ao número total de endereços V4. Em relação a este último, estou deixando de lado o fato de que existem alguns endereços não permitidos, como endereços de transmissão ou intervalos de endereços privados, que não são roteados. Em vez disso, estou assumindo de forma simplista que pode haver 2 ^ 32 endereços com quatro bytes.
Das regras para iptables, extraio os intervalos de IP especificados usando filtros, principalmente com awk, e obtenho uma lista semelhante a esta:
...
27.72.155.100/32
37.9.0.0/20
37.9.32.0/20
37.9.48.0/21
37.9.64.0/18
37.9.128.0/21
...
Portanto, a combinação usual de endereço e bits válidos na máscara. Eu processo esta lista com um pequeno programa Perl que lida com STDIN. Para determinar a quantidade de endereços afetados de tal string, uso a biblioteca Perl "Net::IP", que fornece processamento conveniente. Por exemplo, depois $str = "37.9.32.0/20"
, é possível fazer $ip = new Net::IP($str); $count = $ip -> size();
, e $count agora contém 4096, que é o resultado de 2^(32-20). Até agora está tudo bem.
O problema surge quando tento realizar cálculos com $count. Depois de somar todas as quantidades, quero determiná-las como uma porcentagem da quantidade total de IP possível, dividindo-as por 2 ^ 32. Mesmo com valores individuais, o problema é evidente: a tentativa de dividir a quantidade determinada de 4096 por 3 não produz o número de ponto flutuante "1365,33...", mas simplesmente o valor inteiro 1365. Tentei converter antes da divisão para obter formatos claros, mas não ajudou. Provavelmente tem algo a ver com o código orientado a objetos usado pelo Net::IP. Admito que, como ex-programador assembler, não sou muito versado em programação orientada a objetos e tenho dificuldade com isso. O que provavelmente é necessário é uma espécie de \$count -> getInt()
porque:
Recorri a uma abordagem de força bruta para realmente obter o resultado desejado como um número de ponto flutuante, iterando a quantidade de IP em um loop, diminuindo o resultado OOP de Net::IP. Mas isso é muito grosseiro e ignora completamente o conceito elegante de Net::IP. Além disso, tenho certeza de que há especialistas entre vocês que podem me indicar algo que produza o famoso “efeito aha”, e estou ansioso por isso. Aqui está o código-fonte que usei, reduzido a um único endereço/máscara IP em Perl:
#!/usr/bin/perl
use strict;
use Net::IP;
my $count = 0;
my $str = "37.9.32.0/20";
my $ip = new Net::IP($str) or die (Net::IP::Error());
my $count = $ip -> size();
print "this is the result of 4096/3\t\t\t: ", 4096 / 3, "\n";
print "this is count\t\t\t\t\t: ", $count, "\n";
print "and this is the result of \$count / 3\t\t: ", $count / 3, "\n";
print "and this is the result of int(\$count) / 3\t: ", int($count) / 3, "\n";
my $countW = 0;
while ($count > 0) {
$count--;
$countW++;
}
print "and now comes the result of \$countW / 3\t\t: ", $countW / 3, "\n";
E aqui os resultados produzidos:
this is the result of 4096/3 : 1365.33333333333
this is count : 4096
and this is the result of $count / 3 : 1365
and this is the result of int($count) / 3 : 1365
and now comes the result of $countW / 3 : 1365.33333333333