Tsukiji Systems
RSS1.0


googleで
サイト内検索
このブログ
を検索!
  help

巻き戻し中。

2012年
9月
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


2012-09-09(日) 国別 [長年日記]

_ PC IPリスト

自動でipfwに突っ込むツール作成完了。 引数にipfwのルール番号と2文字の国コード入れればおk。 APNICのリストは、wgetのspiderモードで"Last-Modified"が変わったときだけ落とすようにした。 IP+個数をCIDRに変換するperlはこちらのスクリプトを流用。*1 これね 【convert_cidr.pl】
# convert_cidr.pl
#!/usr/bin/perl
#
# 各RIRのIPアドレスデータベース・ファイルより各レコードの開始IPとホスト数をCIDR表記に変換
#
# ARIN:     ftp://ftp.arin.net/pub/stats/arin/delegated-arin-latest
# RIPE NCC: ftp://ftp.ripe.net/pub/stats/ripencc/delegated-ripencc-latest
# APNIC:    ftp://ftp.apnic.net/pub/stats/apnic/delegated-apnic-latest
# LACNIC:   ftp://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-latest
# AfriNIC:  ftp://ftp.afrinic.net/pub/stats/afrinic/delegated-afrinic-latest
#
# 使い方
# /usr/bin/perl convert_cidr.pl < delegated-arin-latest > output.txt
#
# 一行出力
sub printrule {
  my $Country=$_[0];
  my $Address=$_[1];
  my $AddressCount=$_[2];
#
  my $SubnetMaskBinCnt = sprintf "%b", scalar($AddressCount);
  $SubnetMaskBinCnt =~ s/1//g;
  my $SubnetBit = (32 - length($SubnetMaskBinCnt));
#
  # calc subnet mask
  my $SubnetMaskBit=(1 << 31);
  my $SubnetMaskVal=0;
  for($j=0; $j<$SubnetBit; $j++) {
    $SubnetMaskVal|=$SubnetMaskBit;
    $SubnetMaskBit>>=1;
  }
  my $SubnetMaskVal1=($SubnetMaskVal >> 24)&255;
  my $SubnetMaskVal2=($SubnetMaskVal >> 16)&255;
  my $SubnetMaskVal3=($SubnetMaskVal >> 8)&255;
  my $SubnetMaskVal4=$SubnetMaskVal&255;
#
  print "$Country\t$Address/$SubnetBit\n";
}
#
while(){
  @TextArray = split(/\|/, $_);
#
# IPv4のみパース実行
  if (lc(@TextArray[2]) eq "ipv4") {
#
# ホスト数を10進数から2進数に変換
    $SubnetMaskBin = sprintf "%b", scalar(@TextArray[4]);
    $SubnetMaskBinCnt = $SubnetMaskBin;
    $SubnetMaskBinCnt =~ s/0//g;
#
# ドットアドレスをドットで分割
    @AddressArray = split(/\./, @TextArray[3]);
    if($#AddressArray < 3){
      next;
    }
#
# 要素数を判定し代入
    $AddressValue  = scalar(@AddressArray[0]) << 24;
    $AddressValue |= scalar(@AddressArray[1]) << 16;
    $AddressValue |= scalar(@AddressArray[2]) << 8;
    $AddressValue |= scalar(@AddressArray[3]);
#
# 2進数に変換のホスト数の長さ(バイト数)繰り返す
              for($i=0; $i 0){
        $AddressStr  = sprintf "%d.", ($AddressValue >> 24) & 255;
          $AddressStr .= sprintf "%d.", ($AddressValue >> 16) & 255;
          $AddressStr .= sprintf "%d.", ($AddressValue >> 8) & 255;
          $AddressStr .= sprintf "%d", $AddressValue & 255;
#
          while($AddressCount > 0){
            $AddressCountSub = $AddressCount;
#
            while(($AddressValue & ($AddressCountSub - 1)) > 0){
              $AddressCountSub /= 2;
            }
#
            $AddressStr  = sprintf "%d.", ($AddressValue >> 24) & 255;
            $AddressStr .= sprintf "%d.", ($AddressValue >> 16) & 255;
            $AddressStr .= sprintf "%d.", ($AddressValue >> 8) & 255;
            $AddressStr .= sprintf "%d", $AddressValue & 255;
#
            printrule(@TextArray[1], $AddressStr, $AddressCountSub);
#
            $AddressValue += $AddressCountSub;
            $AddressCount -= $AddressCountSub;
          }
        }else{
          $AddressStr  = sprintf "%d.", ($AddressValue >> 24) & 255;
          $AddressStr .= sprintf "%d.", ($AddressValue >> 16) & 255;
          $AddressStr .= sprintf "%d.", ($AddressValue >> 8) & 255;
          $AddressStr .= sprintf "%d", $AddressValue & 255;
          $AddressCount = 2 ** (length($SubnetMaskBin) - $i - 1);
#
          printrule(@TextArray[1], $AddressStr, $AddressCount);
#
          $AddressValue += $AddressCount;
        }
      }
    }
  }
}
で、同じディレクトリに下記のshellを置いてcronで叩く。
【IP-country-BL.sh】

*1 あのページ、そのまま表示をコピーしてもエスケープされてる文字列があるので動きません。ソース見てコピーしないとね(;´Д`)

#!/bin/sh
#
WGET_CMD="/usr/local/bin/wget"
WGET_URL="http://ftp.apnic.net/pub/stats/apnic/delegated-apnic-latest"
TIME=`date +%Y%m%d%H%M%S`
LOG_DIR="/var/log/ipfwcount"
IFNAME="msk0"
IPFW_CMD="/sbin/ipfw"
C_DIR="/usr/local/etc/IP-country-list"
PERL_CMD="/usr/bin/perl"
#
# Parameter check
if [ "$1" = "" ];then
        echo 'Usage: IP-country-BL.sh [IPFW-number] [Country code(2byte)]'
        exit 1
fi
if [ "$2" = "" ];then
        echo 'Usage: IP-country-BL.sh [IPFW-number] [Country code(2byte)]'
        exit 1
fi
# Log dir check
if [ ! -d $LOG_DIR ];then
        mkdir $LOG_DIR
fi
# Set variable
IPFWNUM=`echo $1`
COUNTRY=`echo $2`
# File move
if [ -f $C_DIR/IP-country-BL_$COUNTRY.sh ];then
        mv $C_DIR/IP-country-BL_$COUNTRY.sh $C_DIR/IP-country-BL_$COUNTRY.sh.prev
else
        touch $C_DIR/IP-country-BL_$COUNTRY.sh
fi
# Get IP list from APNIC with checking diff
if [ -f $C_DIR/delegated-apnic-latest ];then
        $WGET_CMD -S $WGET_URL --spider -o $C_DIR/wgetlog.tmp
        TIME_STAMP=`grep "Last-Modified" $C_DIR/wgetlog.tmp|awk '{print $4$5$6$7}'`
        TIME_STAMP_LATEST=`grep "Last-Modified" $C_DIR/wgetlog.latest|awk '{print $4$5$6$7}'`
        echo $TIME_STAMP
        echo $TIME_STAMP_LATEST
        if [ $TIME_STAMP != $TIME_STAMP_LATEST ];then
                rm -f $C_DIR/delegated-apnic-latest
                $WGET_CMD -S $WGET_URL --spider -o $C_DIR/wgetlog.latest
                $WGET_CMD $WGET_URL -O $C_DIR/delegated-apnic-latest
        fi
else
        rm -f $C_DIR/delegated-apnic-latest
        $WGET_CMD -S $WGET_URL --spider -o $C_DIR/wgetlog.latest
        $WGET_CMD $WGET_URL -O $C_DIR/delegated-apnic-latest
fi
# Exec convert
$PERL_CMD $C_DIR/convert_cidr.pl < $C_DIR/delegated-apnic-latest > $C_DIR/CIDR.txt
/usr/bin/grep $COUNTRY $C_DIR/CIDR.txt|\
awk -v IPFWCMD=`echo $IPFW_CMD` -v IPFWNUM=`echo $IPFWNUM` -v IFNAME=`echo $IFNAME` '{
print IPFWCMD" add "IPFWNUM" deny ip from "$2" to any via "IFNAME
}' > $C_DIR/IP-country-BL_$COUNTRY.sh
# Check diff for each countries
/usr/bin/diff $C_DIR/IP-country-BL_$COUNTRY.sh $C_DIR/IP-country-BL_$COUNTRY.sh.prev
DIFF=`echo $?`
if [ $DIFF != "0" ];then
        $IPFW_CMD -a list |grep 00$IPFWNUM > $LOG_DIR/ipfwcount_$COUNTRY.log.$TIME
        $IPFW_CMD delete $IPFWNUM
        /bin/sh $C_DIR/IP-country-BL_$COUNTRY.sh
        exit 2
fi
exit 0

_ PC でもって

crontabにはこんな感じで突っ込むと、中韓さよなら(´ー`)/~~

############ IP blacklist by Country #############
5 2 * * * /usr/local/etc/IP-country-list/IP-country-BL.sh 170 CN
7 2 * * * /usr/local/etc/IP-country-list/IP-country-BL.sh 171 KR

_ PC 念のため

再起動時も既存のリストを反映するように、下記をrc.localに]追記。

/bin/sh /usr/local/etc/IP-country-list/IP-country-BL_CN.sh
/bin/sh /usr/local/etc/IP-country-list/IP-country-BL_KR.sh

_ PC 掲載

このリスト、cgiで取れるようにするか定時更新で置くようにしたいな。

仕事上も結構重宝する。

国別に拒否するだけじゃなくて、whitelistで「JPだけ」とかにも使えるわけだし。



アクセスカウンター!
累計:
本日:
昨日:
最近のツッコミ

(´・ω・`)ショボーン