ddnslib.py - 更新adsl用户外网ip到动态域名网站no-ip.com,并发送新ip到指定邮箱的python脚本

虽然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
ready to working ...
222.44.176.139
prevIP= currIP=222.44.176.139
ip changed
(220, '163.com Anti-spam GT for Coremail System (163com[20121016])')
(250, 'OK')
(334, 'dXNXXXXhbWU6')
(334, 'UGFXXXXvcmQ6')
(235, 'Authentication successful')
(250, 'Mail OK')
(250, 'Mail OK')
(354, 'End data with .')
(250, 'Mail OK queued as smtp1,C9GowXXXXXLTtgJRWEgEAg--.6418S2 1359132371')
mail sent
Successfully updated 222.44.176.139 to yourNoIPhostname.no-ip.org
root@n13u:/jffs# ./ddnslib.py
ready to working ...

222.44.176.139
prevIP=222.44.176.139 currIP=222.44.176.139
ip not changed
root@n13u:/jffs#


如何在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

你可能感兴趣的:(ddnslib.py - 更新adsl用户外网ip到动态域名网站no-ip.com,并发送新ip到指定邮箱的python脚本)