#!/bin/bash
# このプログラムは GNU GPL ライセンスの下で、変更および再配布を認めます。
# 2011年5月11日 (C) Magic Object
#
# このスクリプトは、Linuxでの使用を前提としています。
#
# このスクリプトでは、以下のコマンドを使用しています。
#
# bash
# gawk
# iptables
# ip6tables
# service
# 
# 注意）RedHat 系で使用する場合は問題無いと思いますが、古い ubuntu などでは、
# service コマンドをインストールする必要があります。
#
# 注意）PATH が通っていない場合は、追記するようにしてください。
#
# このスクリプトでは、gawk で 32bit の正の整数最大値(4294967295)を利用しています。
# gawk で、次のコマンドで正しい値が表示されない場合は、別途、対応版を入手してください。 
#
# gawk 'BEGIN{ print 4294967295; }'
#
# このスクリプトは /etc/cron.weekly などに配置することによって、自動化する事が可能です。
#
# このスクリプトの実行には、スーパーユーザー権限が必要です。
#
########################################################################################
# スーパーユーザー権限チェック
########################################################################################
if test $UID -ne 0
then
	exit 1;
fi
########################################################################################
# シグナルトラップ宣言
########################################################################################

trap '' SIGINT;
trap '' SIGHUP;

########################################################################################
# 変数宣言
########################################################################################

# 一時ファイルパス
export TEMPFILE="/tmp/$$.tmp";

# ipv4 ブロックアドレス 一時ファイルパス
export IPV4_BLOCK="/tmp/$$.block.ipv4";

# ipv6 ブロックアドレス 一時ファイルパス
export IPV6_BLOCK="/tmp/$$.block.ipv6";

# ブロック対象国(ドメイン識別コード)
# ブロック対象国(ドメイン識別コード)
export BLOCK_COUNTRIES='CN,HK,KR,KP';

########################################################################################
# 関数宣言
########################################################################################

# 一時ファイルの削除  
function RemoveTempFile() {
	if test -f $TEMPFILE;
		then rm $TEMPFILE;
	fi;
	if test -f $IPV4_BLOCK;
		then rm $IPV4_BLOCK;
	fi;
	if test -f $IPV6_BLOCK;
		then rm $IPV6_BLOCK;
	fi;
}
########################################################################################
# 処理本体 
########################################################################################

#ファイルの削除
RemoveTempFile;

#=====================================================================================
# APNIC の割り当てリスト取得
#=====================================================================================
wget -q -O $TEMPFILE 'http://ftp.apnic.net/stats/apnic/delegated-apnic-latest';

if test $? -ne 0;
then
	# 取得失敗
	RemoveTempFile;
	exit $?;
fi
#=====================================================================================
# 解析し、IPリストを抽出
#=====================================================================================
gawk -F '|' 'BEGIN {
		#--------------------------------------------------------------------
		# ブロック対象国の正規表現を作成
		#--------------------------------------------------------------------
		split( ENVIRON["BLOCK_COUNTRIES"], blockList, "," );
		blockRegExpStr = "";
		for( key in blockList ) {
			if( length( blockRegExpStr ) > 1 ) {
				blockRegExpStr = blockRegExpStr "|" blockList[key];
			}
			else {
				blockRegExpStr = blockList[key];
			}
		}
		#--------------------------------------------------------------------
		# ipv4 用のマスク最大値	 32bit 最大値
		#--------------------------------------------------------------------
		ipv4Max = 4294967295;
		#--------------------------------------------------------------------
	}
	( $1 == "apnic" && $3 == "ipv4" &&  match( $2, blockRegExpStr ) ) {
		#--------------------------------------------------------------------
		maskValue = ipv4Max;
		addressCount = int($5);
		maskValue = ipv4Max - ( addressCount - 1 );
		maskStr = "";
		while( maskValue > 0 ) {
			byteValue = maskValue % 256;
			maskValue = int( maskValue / 256 );
			
			if( length( maskStr ) > 0 ) {
				maskStr = byteValue "." maskStr;
			}
			else {
				maskStr = byteValue "";
			}
		}
		print $4 "/" maskStr >> ENVIRON["IPV4_BLOCK"];
		#--------------------------------------------------------------------
	}
	( $1 == "apnic" && $3 == "ipv6" &&  match( $2, blockRegExpStr ) ) {
		#--------------------------------------------------------------------
		print $4 "/" $5 >> ENVIRON["IPV6_BLOCK"];
		#--------------------------------------------------------------------
	}' $TEMPFILE
#=====================================================================================
# IPリストからコマンドを実行
#=====================================================================================

gawk '{ print "iptables -A INPUT -s " $1 " -j DROP"; }' $IPV4_BLOCK | bash;
gawk '{ print "ip6tables -A INPUT -s " $1 " -j DROP"; }' $IPV6_BLOCK | bash;

#=====================================================================================
# ブロックリストを保存
#=====================================================================================
Ip4Save=''

if
test -f /usr/libexec/iptables.init
then
	Ip4Save='/usr/libexec/iptables.init save';
elif
test -f /usr/libexec/iptables/iptables.init
then
	Ip4Save='/usr/libexec/iptables/iptables.init save';
else
	Ip4Save='/sbin/service iptables save';
fi

${Ip4Save};

Ip6Save=''

if
test -f /usr/libexec/ip6tables.init
then
	Ip6Save='/usr/libexec/ip6tables.init save';
elif
test -f /usr/libexec/iptables/ip6tables.init
then
	Ip6Save='/usr/libexec/iptables/ip6tables.init save';
else
	Ip6Save='/sbin/service ip6tables save';
fi

${Ip6Save};

#=====================================================================================
# 一時ファイルの削除
#=====================================================================================
RemoveTempFile;

#=====================================================================================
# 終了
#=====================================================================================

exit 0;
