|
|
| |||||||
| |||||||||
巻き戻し中。
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2012-09-09(日) 国別 [長年日記]
_
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
_
でもって
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
_
念のため
再起動時も既存のリストを反映するように、下記を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
[ツッコミを入れる]
| Tweets by RC31E | |||||||||
| |||||||||
| |||||||||


