chnroutes 估计懂网络很多人都认得。挺不错的自动更新路由表脚本。
挤了点时间简单修改了一下。将它支持生成RouterOS脚本,方便软路由器做根据IP自动择线了。
注意脚本会清空原有的地址列表china_address_lists
#!/usr/bin/env python import re import urllib2 import sys import argparse import math import textwrap import time def generate_ros(metric): results = fetch_ip_data() rosscript_header=textwrap.dedent(""" # %s by chnrouters # /ip firewall address-list remove [find list =china_address_lists ] """ % time.strftime(‘%b/%d/%Y %H:%M:%S‘,time.localtime(time.time()))) rfile=open(‘ros_addlist_china.rsc‘,‘w‘) rfile.write(rosscript_header) for ip,_,mask2 in results: address_item="add address=%s/%d list=china_address_lists\n"%(ip,mask2) rfile.write(address_item) rfile.close() print "Usage: Import the content of the newly created ros_addlist_china.rsc to your routeros," "script while clear the original before add." def generate_ovpn(metric): results = fetch_ip_data() rfile=open(‘routes.txt‘,‘w‘) for ip,mask,_ in results: route_item="route %s %s net_gateway %d\n"%(ip,mask,metric) rfile.write(route_item) rfile.close() print "Usage: Append the content of the newly created routes.txt to your openvpn config file," " and also add ‘max-routes %d‘, which takes a line, to the head of the file." % (len(results)+20) def generate_linux(metric): results = fetch_ip_data() upscript_header=textwrap.dedent(""" #!/bin/bash export PATH="/bin:/sbin:/usr/sbin:/usr/bin" OLDGW=`ip route show | grep ‘^default‘ | sed -e ‘s/default via \\([^ ]*\\).*/\\1/‘` if [ $OLDGW == ‘‘ ]; then exit 0 fi if [ ! -e /tmp/vpn_oldgw ]; then echo $OLDGW > /tmp/vpn_oldgw fi """) downscript_header=textwrap.dedent(""" #!/bin/bash export PATH="/bin:/sbin:/usr/sbin:/usr/bin" OLDGW=`cat /tmp/vpn_oldgw` """) upfile=open(‘ip-pre-up‘,‘w‘) downfile=open(‘ip-down‘,‘w‘) upfile.write(upscript_header) upfile.write(‘\n‘) downfile.write(downscript_header) downfile.write(‘\n‘) for ip,mask,_ in results: upfile.write(‘route add -net %s netmask %s gw $OLDGW\n‘%(ip,mask)) downfile.write(‘route del -net %s netmask %s\n‘%(ip,mask)) downfile.write(‘rm /tmp/vpn_oldgw\n‘) print "For pptp only, please copy the file ip-pre-up to the folder/etc/ppp," "and copy the file ip-down to the folder /etc/ppp/ip-down.d." def generate_mac(metric): results=fetch_ip_data() upscript_header=textwrap.dedent(""" #!/bin/sh export PATH="/bin:/sbin:/usr/sbin:/usr/bin" OLDGW=`netstat -nr | grep ‘^default‘ | grep -v ‘ppp‘ | sed ‘s/default *\\([0-9\.]*\\) .*/\\1/‘` if [ ! -e /tmp/pptp_oldgw ]; then echo "${OLDGW}" > /tmp/pptp_oldgw fi dscacheutil -flushcache """) downscript_header=textwrap.dedent(""" #!/bin/sh export PATH="/bin:/sbin:/usr/sbin:/usr/bin" if [ ! -e /tmp/pptp_oldgw ]; then exit 0 fi ODLGW=`cat /tmp/pptp_oldgw` """) upfile=open(‘ip-up‘,‘w‘) downfile=open(‘ip-down‘,‘w‘) upfile.write(upscript_header) upfile.write(‘\n‘) downfile.write(downscript_header) downfile.write(‘\n‘) for ip,_,mask in results: upfile.write(‘route add %s/%s "${OLDGW}"\n‘%(ip,mask)) downfile.write(‘route delete %s/%s ${OLDGW}\n‘%(ip,mask)) downfile.write(‘\n\nrm /tmp/pptp_oldgw\n‘) upfile.close() downfile.close() print "For pptp on mac only, please copy ip-up and ip-down to the /etc/ppp folder," "don‘t forget to make them executable with the chmod command." def generate_win(metric): results = fetch_ip_data() upscript_header=textwrap.dedent("""@echo off for /F "tokens=3" %%* in (‘route print ^| findstr "\\<0.0.0.0\\>"‘) do set "gw=%%*" """) upfile=open(‘vpnup.bat‘,‘w‘) downfile=open(‘vpndown.bat‘,‘w‘) upfile.write(upscript_header) upfile.write(‘\n‘) upfile.write(‘ipconfig /flushdns\n\n‘) downfile.write("@echo off") downfile.write(‘\n‘) for ip,mask,_ in results: upfile.write(‘route add %s mask %s %s metric %d\n‘%(ip,mask,"%gw%",metric)) downfile.write(‘route delete %s\n‘%(ip)) upfile.close() downfile.close() # up_vbs_wrapper=open(‘vpnup.vbs‘,‘w‘) # up_vbs_wrapper.write(‘Set objShell = CreateObject("Wscript.shell")\ncall objShell.Run("vpnup.bat",0,FALSE)‘) # up_vbs_wrapper.close() # down_vbs_wrapper=open(‘vpndown.vbs‘,‘w‘) # down_vbs_wrapper.write(‘Set objShell = CreateObject("Wscript.shell")\ncall objShell.Run("vpndown.bat",0,FALSE)‘) # down_vbs_wrapper.close() print "For pptp on windows only, run vpnup.bat before dialing to vpn," "and run vpndown.bat after disconnected from the vpn." def generate_android(metric): results = fetch_ip_data() upscript_header=textwrap.dedent(""" #!/bin/sh alias nestat=‘/system/xbin/busybox netstat‘ alias grep=‘/system/xbin/busybox grep‘ alias awk=‘/system/xbin/busybox awk‘ alias route=‘/system/xbin/busybox route‘ OLDGW=`netstat -rn | grep ^0\.0\.0\.0 | awk ‘{print $2}‘` """) downscript_header=textwrap.dedent(""" #!/bin/sh alias route=‘/system/xbin/busybox route‘ """) upfile=open(‘vpnup.sh‘,‘w‘) downfile=open(‘vpndown.sh‘,‘w‘) upfile.write(upscript_header) upfile.write(‘\n‘) downfile.write(downscript_header) downfile.write(‘\n‘) for ip,mask,_ in results: upfile.write(‘route add -net %s netmask %s gw $OLDGW\n‘%(ip,mask)) downfile.write(‘route del -net %s netmask %s\n‘%(ip,mask)) upfile.close() downfile.close() print "Old school way to call up/down script from openvpn client. " "use the regular openvpn 2.1 method to add routes if it‘s possible" def fetch_ip_data(): #fetch data from apnic print "Fetching data from apnic.net, it might take a few minutes, please wait..." url=r‘http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest‘ data=urllib2.urlopen(url).read() cnregex=re.compile(r‘apnic\|cn\|ipv4\|[0-9\.]+\|[0-9]+\|[0-9]+\|a.*‘,re.IGNORECASE) cndata=cnregex.findall(data) results=[] for item in cndata: unit_items=item.split(‘|‘) starting_ip=unit_items[3] num_ip=int(unit_items[4]) imask=0xffffffff^(num_ip-1) #convert to string imask=hex(imask)[2:] mask=[0]*4 mask[0]=imask[0:2] mask[1]=imask[2:4] mask[2]=imask[4:6] mask[3]=imask[6:8] #convert str to int mask=[ int(i,16 ) for i in mask] mask="%d.%d.%d.%d"%tuple(mask) #mask in *nix format mask2=32-int(math.log(num_ip,2)) results.append((starting_ip,mask,mask2)) return results if __name__==‘__main__‘: parser=argparse.ArgumentParser(description="Generate routing rules for vpn.") parser.add_argument(‘-p‘,‘--platform‘, dest=‘platform‘, default=‘routeros‘, nargs=‘?‘, help="Target platforms, it can be openvpn, mac, linux," "win, android. openvpn by default.") parser.add_argument(‘-m‘,‘--metric‘, dest=‘metric‘, default=5, nargs=‘?‘, type=int, help="Metric setting for the route rules") args = parser.parse_args() if args.platform.lower() == ‘openvpn‘: generate_ovpn(args.metric) elif args.platform.lower() == ‘linux‘: generate_linux(args.metric) elif args.platform.lower() == ‘mac‘: generate_mac(args.metric) elif args.platform.lower() == ‘win‘: generate_win(args.metric) elif args.platform.lower() == ‘android‘: generate_android(args.metric) elif args.platform.lower() == ‘routeros‘: generate_ros(args.metric) else: print>>sys.stderr, "Platform %s is not supported."%args.platform exit(1)
时间: 2024-11-09 02:48:36