虽然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