IPチェック
前職で必要に迫られて2年ほど前に接続元の国名を調べるスクリプトを書いたd:id:hideden:20051108が、なんか間違った事書いてある上にわかりづらい。もう1回書くのもだるいのでバックアップを漁ったところ、発見。
[hideden@sv1]$ perl netstat_country_code.pl Getting IP List... Parse IP List... Getting netstat... Analyzing netstat... JP : 13 CN : 1 TW : 2
実行するとこんな感じ。netstat実行して、Port80番へのその時点での接続の接続元を調べる。過疎サーバーだと何もでない。
なんの役に立つかはちょっと不明。
汚いけどまぁ動くからいいや。書き直すほど使う頻度高くないし。バックアップがわりにはっとく。
#!/usr/bin/perl use strict; use LWP::UserAgent; use HTTP::Request; $| = 1; my @ip_list; if ( -e "./ip_list.txt" && int( -M "./ip_list.txt" ) == 0 ) { print "Loading IP List Cache...\n"; open( LIST, "ip_list.txt" ); while (<LIST>) { chomp; my ( $st, $ed, $area ) = split( /\t/, $_ ); push( @ip_list, { st => $st, ed => $ed, area => $area } ); } close LIST; } else { print "Getting IP List... \n"; my $ua = LWP::UserAgent->new(); my $req = HTTP::Request->new( GET => "http://ftp.apnic.net/stats/apnic/delegated-apnic-latest" ); my $res = $ua->request($req); die "can't get IP List... \n" unless $res->is_success; my $list = $res->content; print "Parse IP List... \n"; my @list_data = split( /[\r\n]+/, $list ); foreach (@list_data) { my ( $nic, $area, $type, $ip_addr, $num, $date, $mode ) = split( /\|/, $_ ); next if $type ne 'ipv4'; next if $area eq '*'; my $long_ip; $long_ip = ($long_ip << 8) + $_ foreach split /\./, $ip_addr; push( @ip_list, { st => $long_ip, ed => $long_ip + $num, area => $area } ); } @ip_list = sort { $a->{'st'} <=> $b->{'st'} } @ip_list; open( SAVE, ">./ip_list.txt" ); foreach (@ip_list) { print SAVE "$_->{'st'}\t$_->{'ed'}\t$_->{'area'}\n"; } close SAVE; } my $list_num = @ip_list; print "Getting netstat... \n"; my $netstat = `netstat -an`; my @n_stat = split( /[\r\n]+/, $netstat ); print "Analyzing netstat... \n\n"; my %res; foreach (@n_stat) { my $flg = 0; my $st_ip = 0; my $cnt = $list_num; my ( $type, $rq, $sq, $lip, $rip, $stat ) = split( /[\s\t]+/, $_ ); next if $type ne 'tcp'; next if $stat eq 'TIME_WAIT'; my ( $l_ip, $l_pt ) = split( /\:/, $lip ); my ( $r_ip, $r_pt ) = split( /\:/, $rip ); next if $l_pt ne '80'; # port 80 connection only my $ip; $ip = ($ip << 8) + $_ foreach split /\./, $r_ip; next if $ip == 0; while ( $cnt > 10 ) { if ( $cnt % 2 == 1 ) { $cnt = int( $cnt / 2 ) + 1; } else { $cnt = $cnt / 2; } if ( $ip_list[ $st_ip + $cnt - 1 ]->{'ed'} <= $ip ) { $st_ip = $st_ip + $cnt - 1; } } for ( my $i = $cnt ; $i > 0 ; $i-- ) { if ( $ip_list[ $st_ip + $i ]->{'st'} <= $ip && $ip_list[ $st_ip + $i ]->{'ed'} >= $ip ) { $res{ $ip_list[ $st_ip + $i ]->{'area'} }++; $flg = 1; last; } } $res{'UNKNOWN'}++ if $flg == 0; } print "$_ : $res{$_}\n" foreach sort keys %res;