我有一个日志文件,以这种方式列出了列入白名单的 IP 范围:
"217.29.0.0-217.29.255.255",
"204.12.0.0-204.12.255.255",
"198.54.223.0-198.54.223.255",
我还在编写一个 bash 脚本,除其他外,它需要检查此日志文件并确定指定的 IP 是否已列入白名单。
例如,对于 IP 204.12.5.10
,我如何使用具有指定范围的日志文件来确定该 IP 是否属于该文件中的某个范围?
答案1
对于 IP 地址,需要记住的一点是,它们实际上只是 32 位数字的表示。
因此,您可以通过将八位字节乘以基数 256 将它们转换为十进制。
例如:
217.29.0.0 == 216 * 256 ^ 3 + 29 * 256 ^2 + 0 * 256 ^1 + 0 * 256 ^ 0
== 3640655872
因此,给定一个像上面这样的范围 - 首先将它们都转换,这样你就有了开始和结束。然后比较所有传入的 IP,看看它们是否“适合”。
所以像这样(说明算法):
#!/usr/bin/env perl
use strict;
use warnings;
my $ip_to_check = "204.12.5.10";
my $dword = 0;
for ( split( '\.', $ip_to_check ) ) { $dword *= 256; $dword += $_ }
print "Checking $dword\n";
while (<DATA>) {
my ( $start, $finish ) = m/([\d\.]+)/g;
my $start_dword = 0;
for ( split '\.', $start ) { $start_dword *= 256; $start_dword += $_ }
my $end_dword = 0;
for ( split '\.', $finish ) { $end_dword *= 256; $end_dword += $_ }
print "Range:\n";
print "\t$start \t=> $start_dword\n";
print "\t$finish \t=> $end_dword\n";
print "$ip_to_check is in $_\n" if $dword >= $start_dword and $dword <= $end_dword;
}
__DATA__
"217.29.0.0-217.29.255.255",
"204.12.0.0-204.12.255.255",
"198.54.223.0-198.54.223.255",
可以很容易地将其作为“检查脚本”来执行 - 通过读取文件(而不是DATA
)并$ip_to_check
从中获取STDIN
)。
(注意 - 因为纯粹perl
可以很容易地变成一个衬垫,或者一个要调用的脚本。或者重写 - 我敢说你可以expr
很容易地做到这一点)。
答案2
这是一个awk版本:
want=204.12.77.5
awk -v want=$want -F- '
function canon(ip){
split(" "ip,x,/[^0-9]+/)
return sprintf("%03d%03d%03d%03d",x[2],x[3],x[4],x[5])
}
BEGIN { val = canon(want) }
{ low = canon($1); high = canon($2);
if(val>=low && val<=high)print "in range " $0
}' mylogfile
该函数canon
采用 IP 地址,拆分数字字段,然后将每个字段扩展为 3 位数字并返回字符串。它调用每行上的 2 个值,并将这些值与所需的 IP 地址(在开始时设置)进行比较,该地址也已被“规范化”。
答案3
我为 bash 脚本编写了这个函数:
function int_ip() {
OIFS=$IFS
IFS='.'
ip=($1)
IFS=$OIFS
echo "${ip[0]} * 256 ^ 3 + ${ip[1]} * 256 ^2 + ${ip[2]} * 256 ^1 + ${ip[3]} * 256 ^ 0" | bc
}
我这样使用它:
HOSTMIN=$(int_ip ${HOSTMIN})
HOSTMAX=$(int_ip ${HOSTMAX})
IPINT=$(int_ip ${NEWIP})
if ! [[ ${IPINT} -le ${HOSTMAX} && ${IPINT} -ge ${HOSTMIN} ]]; then
echo "IP Out of Range"
return 1
fi
我用来ipcalc
获取 hostmin 和 hostmax