0

我的一点点代码有困难。

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;
      }
    }
  }
}

所以基本上我正在做的是每行打开一个地址列表 1。

接下来,我从脚本的另一部分对关键变量进行排序,并将其与我的列表匹配,如果匹配,则继续执行 if 语句。

现在使用匹配的密钥,我需要检查它是否已经被阻止,所以我使用 qx 来执行 iptables 和 grep 来获取该变量。如果它匹配一切都会完美运行。

如果它不匹配,换句话说,我iptables -nL | grep $key返回一个空白值,而不是继续我的 else 语句,它“抓住” $match 的空白值并继续执行。

对于我的生活,我无法弄清楚如何去除那个空白值并基本上将其显示为没有回报。

我知道有用于 iptables 等的模块,但是我必须使这个脚本尽可能通用。

4

2 回答 2

2

我建议您将整个输出iptables -nL放入一个数组并grep使用 Perl。这样,您将只调用该实用程序一次,并且很容易检测到一个空列表。

如果你写

my @iptables = qx(iptables -nL);

在代码的顶部,然后您可以通过以下方式查询此输出

my @match = grep /\b$key\b/, @iptables;

如果没有包含 IP 地址的记录,则后续

if (@match) { ... }

将失败。

您的代码还有一些其他问题。首先,您必须始终 在程序开始时声明所有变量,并在第一次使用时声明它们use strictuse warnings这将发现许多您可能很容易忽略的简单错误,尤其是在您寻求代码帮助时。

你的open电话应该看起来像

open my $fh, '<', $file or die $!;

和...一起

while (my $sort = <$fh>) { ... }

而且您似乎错过了哈希的重点。无需通读散列中的所有键来寻找匹配项,因为可以使用 直接访问散列元素$ips{$sort}。如果返回的值是undef该元素不存在,或者您可以使用 显式检查它的存在if (exists $ips{$sort}) { ... }

我无法进一步提供帮助,因为我无法访问提供iptables. 如果您需要更多帮助,请发布该实用程序的一些输出。

于 2013-01-13T17:49:13.727 回答
2

问题是,当iptables没有返回结果时,$banned它的默认值是undef. 用作正则表达式, $banned 匹配每个字符串,所以你的条件:

if ($key =~ $banned) {

总是匹配。我想你的意思可能是

if ($key eq $banned) {

如果$bannedundef(因为$matched为空或与正则表达式不匹配)或者您使用正则表达式提取的 IP 地址与$key.

如果您确信结果中的第一个 IPiptables将与您的条件相同,$key那么您可以将条件简化为

if ($match =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/) {
于 2013-01-13T17:50:32.643 回答