#!/usr/bin/python """ Checks the current portforwarding status of the router against the actual IP address of the computer. Makes mods if necessary. """ # Current LAN IP: # router NAT configuration for resume: default_ports=['80','8021','8814','9673','18373','5555','4662','8080','4115','6969','2000','2216','3333','1214','25','6881','6882','6883'] default_udp_ports=['4672','5000'] #Note: # 3333 -> Gnutella | # 2000, 2216 -> OpenFT/priv Amule | -> giFT # 1214 -> FastTrak | # 5000udp -> priv Amule | # 80, 8021, 8090 -> Zope # 9673 -> Apache # 8814 -> SSH # 6969, 6881, 6883 -> BNBT # # 18373 -> rainbow-hub # 4672udp. 4662 -> amule / eDonkey # 46762 -> Bittorrent # 8080 -> YaCY # 4115, 9114 -> Dijjer # 7777 -> Freenet # 7144 -> Peercast # 5555 -> Skype HELP="""Tool to control 3com router's NAT. Single options: (usage: cknat option) /// No option /// Loads portlist (/var/log/rrr/cknat.portlist) correct router's NAT if necessary l,-l,--l,list,print Lists the current cknat portlist r,-r,--r,restore Restores cknat's internal portlist c,-c,--c,ck,-ck,--ck,check As with no option Multiple options: (usage: cknat s ...portlist) s,-s,--s,save IF present in first position, tells to apply the proposed changes to the portlist ... portlist ... List of ports to open/close Portlist format: [action][port number][protocol string] Actions: + opens the port - closes the port Protocol Strings: t,tcp TCP No str TCP u,udp UDP Examples: +8080tcp or +8080t or +8080 will port-forward tcp port 8080 to your computer -4656u or -4656udp will close udp port 4656 cknat s +80 +25 +22 +21 -> Will open tcp ports for most common services and save that configuration cknat -s -25 -> Will close tcp port 25. The modify will be forgotten the next time you run cknat, because the option -s is missing.""" import httplib from urllib import urlencode from os import remove from sys import argv, exit from commands import getstatusoutput as go global log log=open('/var/log/rrr/cknat.log','a') def replacer(obj,lista,to): for s in lista: obj=obj.replace(s,to) return obj def manage_ports(action): global ports, udp_ports if action=='restore': portlist=open('/var/log/rrr/cknat.portlist','w') for port in default_ports: portlist.write(port+'tcp\n') for port in default_udp_ports: portlist.write(port+'udp\n') portlist.close() ports=default_ports udp_ports=default_udp_ports if action=='load': portlist=open('/var/log/rrr/cknat.portlist','r') data=portlist.readlines() ports=[] udp_ports=[] for entry in data: if entry[-4:-1]=='tcp': ports+=[entry[:-4]] if entry[-4:-1]=='udp': udp_ports+=[entry[:-4]] portlist.close() if action=='save': portlist=open('/var/log/rrr/cknat.portlist','w') for port in ports: portlist.write(port+'tcp\n') for port in udp_ports: portlist.write(port+'udp\n') portlist.close() def getIP(): global IP a=go('sudo ifconfig eth0|grep addr:10.0.0.')[1] a=a.replace(' ','\n').splitlines() for el in a: if 'addr:10.0.0.' in el: IP=el.replace('addr:','') #print "Current IP: "+IP op=open('/var/log/rrr/ip','w') op.write(IP) op.close() IP=IP.split('.')[-1] def getNAT(): global conn, nat conn = httplib.HTTPConnection('10.0.0.1') conn.request('POST','/cgi-bin/login.exe','pws=admin') resp = conn.getresponse() resp.read() #print str(resp.status)+resp.reason conn.request('GET','/nat_v.stm') resp=conn.getresponse() red=resp.read() op=open('/tmp/routernat.html.tmp','w') op.write(red) op.close() a=go('cat /tmp/routernat.html.tmp|grep document.forms|grep pip1.value')[1] NAT=a.replace(';','\n').replace('document.forms[0].','').splitlines() remove('/tmp/routernat.html.tmp') nat={'tcp':[],'udp':[]} for enum in range(len(NAT)/6): s=str(enum+1) n=enum*6 ip=replacer(NAT[n],['pip'+s,'.value=','"'],'') port=replacer(NAT[n+1],['pport'+s,'.value=','"'],'') proto=replacer(NAT[n+2],['ptype'+s,'[','].defaultChecked=true'],'') if proto=='0': nat['tcp']+=[(ip,port)] elif proto=='1': nat['udp']+=[(ip,port)] else: print 'decode error' def correct(): params={} i=0 msg='NAT Port Forwarding modified as follow:\n' msg+='IP\tprPort\tpubPort\n' if len(ports)+len(udp_ports)>20: print "/!\ Too many ports specified!" exit(256) # ptype=1 per porte TCP; ptype=2 per porte UDP for port in ports: params['pip'+str(i+1)]=IP params['pport'+str(i+1)]=port params['puport'+str(i+1)]=port params['enable'+str(i+1)]='1' params['ptype'+str(i+1)]='1' msg+=IP+'\t'+port+'\t'+port+'\n' i+=1 for port in udp_ports: params['pip'+str(i+1)]=IP params['pport'+str(i+1)]=port params['puport'+str(i+1)]=port params['enable'+str(i+1)]='1' params['ptype'+str(i+1)]='2' msg+=IP+'\t'+port+'\t'+port+'\tudp'+'\n' i+=1 params=urlencode(params) conn.request('POST','/cgi-bin/setup_virtualsrv.exe',params) r=conn.getresponse() print str(r.status)+r.reason print msg log.write(go('date')[1]+msg) conn.close() def check(): check_count=0 for port in ports: if (IP,port) in nat['tcp'] and (IP,port) not in nat['udp']: check_count+=1 for port in udp_ports: if (IP,port) in nat['udp'] and (IP,port) not in nat['tcp']: check_count+=1 if check_count!=len(ports)+len(udp_ports): print 'Correcting port forwarding table...' correct() return 'COMMITTING...' return 'SKIPPING' getIP() getNAT() if len(argv)==1 or ( len(argv)==2 and argv[1] in ['c','-c','--c','ck','-ck','--ck','check'] ): manage_ports('load') check() exit() if len(argv)==2: if argv[1] in ['h','-h','--h','help','info']: print HELP log.close() exit() if argv[1] in ['l','-l','--l','list','print']: manage_ports('load') for port in ports: print port+'tcp' for port in udp_ports: print port+'udp' log.close() exit() if argv[1] in ['r', '-r', '--r', 'restore']: manage_ports('restore') log.write(go('date')[1]+' ## RESTORE FORCED:\n') check() log.close() exit() save=False act='TEMPORARY' if len(argv)>=2: argv.pop(0) if argv[0] in ['s','-s','--s','save']: save=True act='SAVING' argv.pop(0) ports=[]; udp_ports=[] for port in nat['tcp']: ports+=port[1] for port in nat['udp']: udp_ports+=port[1] for arg in argv: port=None; udp_port=None # Determine port type: if arg[-1]=='u': udp_port=arg[:-1] elif arg[-3:]=='udp': udp_port=arg[:-3] elif arg[-1]=='t': port=arg[:-1] elif arg[-3:]=='tcp': port=arg[:-3] else: port=arg # Open port: if arg[0]=='+': if port not in ports and port!=None: ports+=[port[1:]] continue if udp_port not in udp_ports and udp_port!=None: udp_ports+=[udp_port[1:]] continue # Close port: if arg[0]=='-': if port not in ports and port!=None: ports.remove(port[1:]) continue if udp_port not in udp_ports and udp_port!=None: udp_ports.remove(udp_port[1:]) # Apply modifications, if necessary: log.write(go('date')[1]+' ## '+act+' PORTLIST: '+check()+'\n') # Save to portlist the new configuration: if save==True: manage_ports('save') log.close()