虽然ddwrt上已经自带了关联动态ip到no-ip.com的选项,但发现它关联的ip和ip138.com上查到的不一致,而ip138上的却是正确的,于是只好自己写段脚本来更新no-ip.com上的动态ip地址了,顺便加上了把新ip发送到指定邮箱功能。
假设python装在了/opt下,ddnslib.py放在了/jffs目录下,计划每两小时检测一次,那么路由器里面的cron是这么写的(注意在dd-wrt上,cron执行时的环境变量和ssh登录上后的环境变量不一样,所以要加上python可执行程序的绝对路径):
0 */2 * * * root /opt/bin/python2 /jffs/ddnslib.py
ddnslib.py 完整代码
#!/usr/bin/env python2 # coding:utf-8 import httplib import base64 import string import datetime import smtplib __version__ = '0.1' __author__ = '[email protected]' class DDNS(): def __init__(self): pass def updateNoIP(self,username,password,hostname,ipaddr): """ update ip to no-ip.com """ auth = 'Basic '+base64.b64encode(username+':'+password).strip() agent = 'ddnslib.UpdateNoIP'+'/'+__version__+' '+__author__ headers = {'Authorization':auth,\ 'User-Agent':agent} conn = httplib.HTTPConnection('dynupdate.no-ip.com') conn.request(method = 'GET',\ url = '/nic/update?hostname='+hostname+'&myip='+ipaddr,\ headers = headers) resp = conn.getresponse() if resp.status == 200: print 'Successfully updated',ipaddr,'to',hostname else: print 'Update failed for',hostname,'with',resp.status,resp.reason class WANIP(): def __init__(self): pass def getIPFrom138(self): """ get WAN IP from ip138.com """ conn = httplib.HTTPConnection("iframe.ip138.com") conn.request("GET","/ic.asp") resp = conn.getresponse() if resp.status == 200: data = resp.read() ipaddr = data[string.find(data,'[')+1:string.find(data,']')] else: print 'getIPFrom138 failed with',resp.status,resp.reason ipaddr = '1.1.1.1' return ipaddr class MailIP(): def __init__(self): pass def sendFrom163(self,sender,password,receiver,subject,content): """ send mail from 163.com """ server = 'smtp.163.com' port = 25 # append send time to the subject sendtime = '@'+datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') # remove domain suffix atindex = string.find(sender,'@') username = sender if atindex != -1: username = sender[:atindex] mailfrom = username + '@163.com' smtp = smtplib.SMTP() print smtp.connect("%s:%s" % (server,port)) print smtp.docmd("HELO",server) print smtp.docmd("AUTH LOGIN") print smtp.docmd(base64.b64encode(username)) print smtp.docmd(base64.b64encode(password)) print smtp.docmd("MAIL FROM:","<%s>" % mailfrom) print smtp.docmd("RCPT TO:","<%s>" % receiver) print smtp.docmd("DATA") data = """from: %s to: %s subject: %s #there must be at least two blank lines below subject, #or mail body would be swallowed %s . """ % (mailfrom,receiver,subject+sendtime,content) print smtp.docmd(data) smtp.quit() print "mail sent" class FileIP(): def __init__(self): pass def isIPChanged(self,currIP): ret = False with open('/tmp/ddns.ip','a+') as f: prevIP = f.read() print 'prevIP='+prevIP,'currIP='+currIP if prevIP == '' or prevIP != currIP: f.seek(0,0) f.truncate() f.write(currIP) ret = True f.close() return ret if __name__ == '__main__': print 'ready to working ...' ipaddr = WANIP().getIPFrom138() print ipaddr if FileIP().isIPChanged(ipaddr): print 'ip changed' MailIP().sendFrom163('your163mailid','your163mailpass','[email protected]',\ 'IP='+ipaddr,'test mail') DDNS().updateNoIP('yourNoIPaccount','yourNoIPpass',\ 'yourNoIPhostname.no-ip.org',ipaddr) else: print 'ip not changed'
测试输出:
root@n13u:/jffs# ./ddnslib.py如何在dd-wrt路由器上安装python请参照下文
启用刷了dd-wrt的无线路由器asus-n13u-b1外置usb存储支持,安装python2.7
http://blog.csdn.net/t0nsha/article/details/8522814
REF:
No-IP DNS Update API
http://www.noip.com/integrate/request