有很多时候需要获取联通,电信,教育网等ISP的网段,因为不同ISP之间的连接很差,延迟非常高,网上有很流传度非常高的shell脚本用来获取ISP的网段,我的这个版本也是根据这个版本进行修改的,其实思路都是一样的,都是通过对apnic的whois服务器获得信息进行整理而得。

我改进的脚本加入了shell的并发处理,因为各个IP段的处理进程之间是没有相关性的,所以这会大大减小脚本处理的时间,你可以随意更改thread值来调整处理的进程数,当然,越大的thread值带来更少的处理时间但也可能给你的服务器带来更大的压力。

 
  
  1. #!/bin/bash   
  2. DIR=/root/dns/script   
  3. FILE=$DIR/ip_apnic   
  4. CHN=$DIR/iplist   
  5. tel=$DIR/CHINANET   
  6. cnc=$DIR/CNCGROUP   
  7. cer=$DIR/CERNET   
  8. crtc=$DIR/CRTC   
  9. cmnet=$DIR/CMNET   
  10. other=$DIR/OTHER   
  11. fifofile=$DIR/fifo   
  12. thread=20 #设置并发处理的进程数  
  13.    
  14. rm -f $FILE   
  15. rm -f $tel $cer $cnc $other $cmnet $crtc $CHN   
  16. wget http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest -O $FILE   
  17.    
  18. rm -f $fifofile   
  19. mkfifo $fifofile   
  20. exec 6<>$fifofile   
  21. rm $fifofile   
  22. for ((i=0;i<$thread;i++))   
  23. do   
  24.    echo   
  25. done >&6   
  26.    
  27. grep 'apnic|CN|ipv4|' $FILE | cut -f 4,5 -d'|'|sed -e 's/|/ /g' >$CHN   
  28.    
  29. while read ip cnt   
  30. do   
  31.        read -u6   
  32.        {   
  33.         echo $ip:$cnt   
  34.         mask=$(cat <<EOF | bc | tail -1   
  35.         pow=32;   
  36.         define log2(x) {   
  37.         if (x<=1) return (pow);   
  38.                 pow--;   
  39.                 return(log2(x/2));   
  40.         }   
  41.         log2($cnt)   
  42. EOF   
  43. )   
  44.          touch $DIR/$ip.tmp   
  45.          while [ -z "`cat $DIR/$ip.tmp`" ]   
  46.          do   
  47.              /etc/whois/bin/whois3 -h whois.apnic.net $1 >$DIR/$ip.tmp   
  48.              echo "TRY PROCESS __________________________________$ip"   
  49.          done                 # 因为有时候连接whois服务器会超时,所以每次执行的时候判断是否正常获取了whois信息  
  50.          num=`grep "CERNET" $DIR/$ip.tmp |wc -l`   
  51.                 if [ "$num" != "0" ]   
  52.                 then   
  53.                         echo $ip/$mask >> $cer   
  54.                         echo "cernet"   
  55.                         echo >&6   
  56.                         rm -f $DIR/$ip.tmp   
  57.                         continue   
  58.                 else   
  59.                          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; }'`   
  60.                         if [ "$NETNAME" = "CNC" -o "$NETNAME" = "UNICOM" -o "$NETNAME" = "CNCGROUP"  ]   
  61.                         then   
  62.                                 echo $ip/$mask >> $cnc   
  63.                                 echo "cnc"   
  64.                                 echo >&6   
  65.                                 rm -f $DIR/$ip.tmp   
  66.                                 continue   
  67.                         elif [ "$NETNAME" = "CHINATELECOM" -o "$NETNAME" = "CHINANET" ]   
  68.                         then   
  69.                                 echo $ip/$mask >> $tel   
  70.                                 echo "chinanet"   
  71.                                 echo >&6   
  72.                                 rm -f $DIR/$ip.tmp   
  73.                                 continue   
  74.                         else   
  75.                                 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'`   
  76.                                 case $MB in   
  77.                                 CNCGROUP)   
  78.                                         echo $ip/$mask >> $cnc   
  79.                                         echo "cnc"   
  80.                                         echo >&6   
  81.                                         rm -f $DIR/$ip.tmp   
  82.                                 ;;   
  83.                                 CHINANET)   
  84.                                         echo $ip/$mask >> $tel   
  85.                                         echo "chinanet"   
  86.                                         echo >&6   
  87.                                         rm -f $DIR/$ip.tmp   
  88.                                 ;;   
  89.                                 *)   
  90.                                         num=`grep -E "CHINANET|CHINATELECOM" $DIR/$ip.tmp |wc -l`   
  91.                                         if [ "$num" != "0" ]   
  92.                                         then   
  93.                                                 echo $ip/$mask >> $tel   
  94.                                                 echo "chinanet"   
  95.                                                 echo >&6   
  96.                                                 rm -f $DIR/$ip.tmp   
  97.                                                 continue   
  98.                                         else   
  99.                                                 num=`grep "CRTC" $DIR/$ip.tmp |wc -l`   
  100.                                                 if [ "$num" != "0" ]   
  101.                                                 then   
  102.                                                         echo $ip/$mask >> $crtc   
  103.                                                         echo "railway"   
  104.                                                         echo >&6   
  105.                                                         rm -f $DIR/$ip.tmp   
  106.                                                         continue   
  107.                                                 else   
  108.                                                         num=`grep "CMNET" $DIR/$ip.tmp |wc -l`   
  109.                                                         if [ "$num" != "0" ]   
  110.                                                         then   
  111.                                                                 echo $ip/$mask >> $cmnet   
  112.                                                                 echo "cmnet"   
  113.                                                                 echo >&6   
  114.                                                                 rm -f $DIR/$ip.tmp   
  115.                                                                 continue   
  116.                                                         else   
  117.                                                                 num=`grep -E "China Unicom|CNC Group" $DIR/$ip.tmp |wc -l`   
  118.                                                                 if [ "$num" != "0" ]   
  119.                                                                 then   
  120.                                                                         echo $ip/$mask >> $cnc   
  121.                                                                         echo "cnc"   
  122.                                                                         echo >&6   
  123.                                                                         rm -f $DIR/$ip.tmp   
  124.                                                                         continue   
  125.                                                                 else   
  126.                                                                         echo $ip/$mask >> $other   
  127.                                                                         rm -f $DIR/$ip.tmp   
  128.                                                                         echo >&6   
  129.                                                                 fi   
  130.                                                         fi   
  131.                                                 fi   
  132.                                         fi   
  133.                                 ;;   
  134.                                 esac   
  135.                           fi   
  136.                    fi   
  137.        }&   
  138. done <$CHN #加入了并发处理,根据thread的进程数进行处理这样能大大减少脚本处理的速度  
  139.    
  140. wait   
  141. exec 6>&-   
  142. echo "fisrt script is finished"   

整个脚本看起来很复杂,其实主要是对whois获取的信息进行处理的过程,改进的部分除了加入并发大大提高脚本的执行速度之外主要就是调整了各个ISP地址段的处理过程,使其更准确,在我两个月的使用中,发现准确率非常高,可以满足大部分应用的需求。

联通的IP段自动输出到CNCGROUP文件中,电信的输出到CHINANET文件中,教育网输出到CERNET文件中,我还加入了铁通和移动网段的处理,剩下的都输出到OTHER文件中,你可以根据需求自己订制自己所需要的ISP的网段。

这个脚本最大的亮点莫过于here document的使用,让这个枯燥无味的脚本优雅了许多,也更加简洁,你可以使用vim配合here document对手头大量的文档进行相同的操作,快速准确。