#!/usr/bin/env python3 # -*- coding:utf-8 -*- """ Dynamic DNS update for DNSPod """ __version__ = "0.1.0" __author__ = "suokunlong.cn" import http.client import urllib import socket import time import json # Change the following user and domain info. # Use Token, see https://support.dnspod.cn/Kb/showarticle/tsid/227/ ID = "12345" Token = "e4420a54a980850a72566a3dcb099946" domain_id = "20114473" record_id="127782777" sub_domain = "home" # 60 seconds per minute * minutes retry_internal = 60*30 # common-parameters: # https://www.dnspod.cn/docs/info.html#common-parameters params_common = dict( login_token = ("%s,%s" % (ID, Token)), format = "json", lang = "en" ) current_ip = None headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/json"} dnsapi_url = "dnsapi.cn" def get_new_ip(): sock = socket.create_connection(('ns1.dnspod.net', 6666), 20) new_ip = sock.recv(16) # the real out-side ip address new_ip = new_ip.decode() sock.close() return new_ip def get_record_ip(): # https://dnsapi.cn/Record.Info d={"domain_id":domain_id, "record_id": record_id} params = params_common params.update(d) # print(params) conn = http.client.HTTPSConnection(dnsapi_url) conn.request("POST", "/Record.Info", urllib.parse.urlencode(params), headers) response = conn.getresponse() data = response.read().decode('utf8') data = json.loads(data) conn.close() if data['status']['code']!="1": # raise an exception when detailed error message if the status code is not 1. raise Exception(data['status']['message']) record_ip = data['record']['value'] # the ip in dnspod record return record_ip def ddns(new_ip): """update new_ip in dnspod record """ d={"domain_id":domain_id, "record_id": record_id, "sub_domain": sub_domain, "value": new_ip, 'record_line': '默认'} params = params_common params.update(d) conn = http.client.HTTPSConnection(dnsapi_url) conn.request("POST", "/Record.Ddns", urllib.parse.urlencode(params), headers) response = conn.getresponse() data = response.read().decode('utf8') data = json.loads(data) conn.close() if data['status']['code']!="1": raise Exception(data['status']['message']) return True if __name__ == '__main__': while True: try: print("------", time.ctime(), "------") new_ip = get_new_ip() print("New IP: ", new_ip) if new_ip != current_ip: record_ip = get_record_ip() print("Record IP: ", record_ip) if record_ip != new_ip: if ddns(new_ip): current_ip = new_ip print("updated.") else: print("failed.") else: print("same ip, pass.") except Exception as e: print(e) pass if retry_internal == 0: exit() else: time.sleep(retry_internal)
使用方法:
直接在命令行终端中运行,保持终端开启即可。Linux下,可在终端中“文件 – 新建配置文件 – 命令 – 运行自定义命令”,从而每次直接从终端的文件菜单中启动。
以上代码本人已完美运行一个月没有出错。欢迎在评论中提交bug报告。
Leave a Reply