如果发现服务器有大量存取记录, 要检查是否 DDOS 攻击, 可以开启记录档检查, 但资料量大的话, 要人手检查也很困难, 所以我写了这个简单的 Perl Script, 用作检查记录档内出现次数最多的 IP, 锁定出现频率最高的 IP 作检查会容易得多。
编写时想到有多种记录档也有此需要, 只要记录档是一行一个记录, 而每行只有一个 IP 出现便可以用, 已经试过 apache access log 及 error log, /var/log/secure, /var/log/vsftpd.log 也可以正确使用。执行速度尚算可以, 检查一个 350MB 的 apache log, 使用 raid1 的服务器需时大约 6 秒。
使用方法为: count_ip.pl log_file [count]
例如我想检查 apache log, 记录档在/var/log/httpd/access.log, 是这样:
./count_ip.pl /var/log/httpd/access.log
默认会显示头 10 个出现最多的 IP, 如果想显示更多 IP 也可以自订, 例如想显示 20 个 IP:
./count_ip.pl /var/log/httpd/access.log 20
如果想储存结果的话, 可以这样:
./count_ip.pl /var/log/httpd/access-20150416.log > /var/log/ip_count_result.log
这样结果便会储存在 /var/log/ip_count_result.log
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
#!/usr/bin/perl ############################################################################### # Name: count_ip.pl # Author: Sam Tang # Website: http://www.phpini.com/ # Purpose: read log file and print a report, display top tarffic ip, the ip # total access times and total access. ############################################################################### use strict; use warnings; no warnings 'numeric'; # disable Argument "XXX" isn't numeric warning my $line_num = 10; ### default show top 10 records if (!$ARGV[0]) { die "Usage: count_ip.pl logfile [display lines]\n"; } my $log = $ARGV[0]; $line_num = $ARGV[1] if ($ARGV[1]); ##### open log file, get the hostname and traffic open(my $fh, '<', $log) or die "Could not open file '$log' $!"; my %ip; my $total = 0; ##### save ip data to %ip while (my $row = <$fh>) { if( $row =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ ){ $ip{$1}++; $total++; } } ##### print top ip report print "==================================\n"; print " << IP Traffic Report: >>\n==================================\n"; my $start = 0; foreach my $host (reverse sort { $ip{$a} <=> $ip{$b} } keys %ip) { if ($start < $line_num) { print $start+1 . "."; ### print order number print " " if $start < 9; ### add space for left align print " $host: $ip{$host}\n"; ### print data } $start++; } print "==================================\n"; print " Total Access: $total\n"; print "==================================\n"; |
下载后确定第 1 行是服务器上面 perl 的路径, 加入可执行权限便以使用了。
我出现了下方的错误
./count_ip.pl /var/log/httpd/access_log
Global symbol “$log” requires explicit package name at ./count_ip.pl line 21.
Global symbol “$log” requires explicit package name at ./count_ip.pl line 22.
Execution of ./count_ip.pl aborted due to compilation errors.