有很多时候需要获取联通,电信,教育网等ISP的网段,因为不同ISP之间的连接很差,延迟非常高,网上有很流传度非常高的shell脚本用来获取ISP的网段,我的这个版本也是根据这个版本进行修改的,其实思路都是一样的,都是通过对apnic的whois服务器获得信息进行整理而得。
我改进的脚本加入了shell的并发处理,因为各个IP段的处理进程之间是没有相关性的,所以这会大大减小脚本处理的时间,你可以随意更改thread值来调整处理的进程数,当然,越大的thread值带来更少的处理时间但也可能给你的服务器带来更大的压力。
- #!/bin/bash
- DIR=/root/dns/script
- FILE=$DIR/ip_apnic
- CHN=$DIR/iplist
- tel=$DIR/CHINANET
- cnc=$DIR/CNCGROUP
- cer=$DIR/CERNET
- crtc=$DIR/CRTC
- cmnet=$DIR/CMNET
- other=$DIR/OTHER
- fifofile=$DIR/fifo
- thread=20 #设置并发处理的进程数
- rm -f $FILE
- rm -f $tel $cer $cnc $other $cmnet $crtc $CHN
- wget http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest -O $FILE
- rm -f $fifofile
- mkfifo $fifofile
- exec 6<>$fifofile
- rm $fifofile
- for ((i=0;i<$thread;i++))
- do
- echo
- done >&6
- grep 'apnic|CN|ipv4|' $FILE | cut -f 4,5 -d'|'|sed -e 's/|/ /g' >$CHN
- while read ip cnt
- do
- read -u6
- {
- echo $ip:$cnt
- mask=$(cat <<EOF | bc | tail -1
- pow=32;
- define log2(x) {
- if (x<=1) return (pow);
- pow--;
- return(log2(x/2));
- }
- log2($cnt)
- EOF
- )
- touch $DIR/$ip.tmp
- while [ -z "`cat $DIR/$ip.tmp`" ]
- do
- /etc/whois/bin/whois3 -h whois.apnic.net $1 >$DIR/$ip.tmp
- echo "TRY PROCESS __________________________________$ip"
- done # 因为有时候连接whois服务器会超时,所以每次执行的时候判断是否正常获取了whois信息
- num=`grep "CERNET" $DIR/$ip.tmp |wc -l`
- if [ "$num" != "0" ]
- then
- echo $ip/$mask >> $cer
- echo "cernet"
- echo >&6
- rm -f $DIR/$ip.tmp
- continue
- else
- NETNAME=`sed -e '/./{H;$!d;}' -e 'x;/netnum/!d' $DIR/$ip.tmp |grep ^netname | sed -e 's/.*: \(.*\)/\1/g' | sed -e 's/-.*//g'| sed -e 's/cJ/ /g' | awk -F' ' '{ printf $1; }'`
- if [ "$NETNAME" = "CNC" -o "$NETNAME" = "UNICOM" -o "$NETNAME" = "CNCGROUP" ]
- then
- echo $ip/$mask >> $cnc
- echo "cnc"
- echo >&6
- rm -f $DIR/$ip.tmp
- continue
- elif [ "$NETNAME" = "CHINATELECOM" -o "$NETNAME" = "CHINANET" ]
- then
- echo $ip/$mask >> $tel
- echo "chinanet"
- echo >&6
- rm -f $DIR/$ip.tmp
- continue
- else
- MB=`sed -e '/./{H;$!d;}' -e 'x;/mnt-by/!d' $DIR/$ip.tmp|grep ^mnt-by |head -1| sed -e 's/.*: \(.*\)/\1/g' |sed -e 's/ *MAINT-//g'| sed -e 's/-.*//g'`
- case $MB in
- CNCGROUP)
- echo $ip/$mask >> $cnc
- echo "cnc"
- echo >&6
- rm -f $DIR/$ip.tmp
- ;;
- CHINANET)
- echo $ip/$mask >> $tel
- echo "chinanet"
- echo >&6
- rm -f $DIR/$ip.tmp
- ;;
- *)
- num=`grep -E "CHINANET|CHINATELECOM" $DIR/$ip.tmp |wc -l`
- if [ "$num" != "0" ]
- then
- echo $ip/$mask >> $tel
- echo "chinanet"
- echo >&6
- rm -f $DIR/$ip.tmp
- continue
- else
- num=`grep "CRTC" $DIR/$ip.tmp |wc -l`
- if [ "$num" != "0" ]
- then
- echo $ip/$mask >> $crtc
- echo "railway"
- echo >&6
- rm -f $DIR/$ip.tmp
- continue
- else
- num=`grep "CMNET" $DIR/$ip.tmp |wc -l`
- if [ "$num" != "0" ]
- then
- echo $ip/$mask >> $cmnet
- echo "cmnet"
- echo >&6
- rm -f $DIR/$ip.tmp
- continue
- else
- num=`grep -E "China Unicom|CNC Group" $DIR/$ip.tmp |wc -l`
- if [ "$num" != "0" ]
- then
- echo $ip/$mask >> $cnc
- echo "cnc"
- echo >&6
- rm -f $DIR/$ip.tmp
- continue
- else
- echo $ip/$mask >> $other
- rm -f $DIR/$ip.tmp
- echo >&6
- fi
- fi
- fi
- fi
- ;;
- esac
- fi
- fi
- }&
- done <$CHN #加入了并发处理,根据thread的进程数进行处理这样能大大减少脚本处理的速度
- wait
- exec 6>&-
- echo "fisrt script is finished"
整个脚本看起来很复杂,其实主要是对whois获取的信息进行处理的过程,改进的部分除了加入并发大大提高脚本的执行速度之外主要就是调整了各个ISP地址段的处理过程,使其更准确,在我两个月的使用中,发现准确率非常高,可以满足大部分应用的需求。
联通的IP段自动输出到CNCGROUP文件中,电信的输出到CHINANET文件中,教育网输出到CERNET文件中,我还加入了铁通和移动网段的处理,剩下的都输出到OTHER文件中,你可以根据需求自己订制自己所需要的ISP的网段。
这个脚本最大的亮点莫过于here document的使用,让这个枯燥无味的脚本优雅了许多,也更加简洁,你可以使用vim配合here document对手头大量的文档进行相同的操作,快速准确。
转载于:https://blog.51cto.com/shunter/1076743