使用Python脚本动态更新DNSPod域名记录 (DDNS)

#!/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报告。


Posted

in

by

Tags:

评论 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *