我的代码有点困难。
open ("files","$list");
while (my $sort = <files>) {
chomp $sort;
foreach my $key (sort keys %ips) {
if ($key =~ $sort) {
print "key $key\n";
my $match =qx(iptables -nL | grep $key 2>&1);
print "Match Results $match\n";
chomp $match;
my $banned = $1 if $match =~ (/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/);
print "Banned Results $banned\n";
if ($key =~ $banned) {
print "Already banned $banned\n";
} else {
system ("iptables -A INPUT -s $key -j DROP");
open my $fh, '>>', 'banned.out';
print "Match Found we need to block it $key\n";
print $fh "$key:$timestamp\n";
close $fh;
}
}
}
}
基本上我正在做的是每行打开一个地址列表。
接下来,我将我的密钥变量从我的脚本的另一部分中整理出来,并将其与我的列表匹配,如果匹配则继续执行if语句。
现在使用匹配的密钥我需要检查并查看它是否已被阻止,所以我使用qx来执行iptables和grep for the variable。如果它匹配一切正常。
如果它不匹配,换句话说,我的iptables -nL | grep $key
返回一个空白值而不是转到我的else语句,它“抓取”$ match的空白值并继续执行。
对于我的生活,我无法弄清楚如何去除那个空白值并基本上表明它没有回报。
我知道iptables等有模块,但是我必须尽可能保持这个脚本的通用。
答案 0 :(得分:2)
我建议你使用Perl将iptables -nL
的整个输出放入一个数组中grep
。这样,您只需调用一次该实用程序,并且很容易检测到空列表。
如果你写
my @iptables = qx(iptables -nL);
在代码的顶部,然后您可以通过
查询此输出my @match = grep /\b$key\b/, @iptables;
如果没有包含IP地址的记录,则后续
if (@match) { ... }
会失败。
您的代码还有其他一些问题。首先,必须始终 use strict
和use warnings
在程序开始时,并在所有变量的第一个使用点声明它们。这将发现许多您可能容易忽略的简单错误,尤其适用于您要求代码帮助的情况。
您的open
电话应该是
open my $fh, '<', $file or die $!;
与
一起while (my $sort = <$fh>) { ... }
而你似乎已经错过了哈希的观点。无需读取哈希中查找匹配项的所有键,因为可以使用$ips{$sort}
直接访问哈希元素。如果返回的值为undef
,则该元素不存在,或者您可以使用if (exists $ips{$sort}) { ... }
显式检查其是否存在。
我无法继续帮助,因为我无法访问提供iptables
的平台。如果您需要更多帮助,请从实用程序发布一些输出。
答案 1 :(得分:2)
问题是,当iptables
未返回任何结果时,$banned
会保留其默认值undef
。用作正则表达式,$ banned匹配每个字符串,所以你的条件:
if ($key =~ $banned) {
始终匹配。我认为你打算写的可能是
if ($key eq $banned) {
如果$banned
为undef
(因为$matched
为空或与正则表达式不匹配)或者您使用正则表达式提取的IP地址有所不同,则会失败来自$key
。
如果您确信iptables
结果中的第一个IP与$key
相同,那么您可以将条件简化为
if ($match =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/) {