话痨司机啊 发表于 2022-5-25 17:12

DDNS_DNSPOD 亲测可用

本帖最后由 话痨司机啊 于 2022-5-25 20:20 编辑

之前我自己电脑上的DDNS软件坏了,自己用python写了一个,分享一下,亲测可用,可以写个监听IP变化自动更新DDNS{仅限腾讯(DDNSPOD)DDNS}。











"""
      ************************************
          Description:
          Author: ...
          Github: https://github.com/jianala
          Date: 2022-05-25 17:01:33
          FilePath: Administrator\Desktop\ddns_dnspod.py
          LastEditors: @话痨
          LastEditTime: 2022-05-25 17:08:06
          善始者实繁,克终者盖寡。

      ************************************
"""


import requests
import json
from requests.adapters import HTTPAdapter
import logging
import time
import os
from threading import Thread

logging.basicConfig(filemode='a',filename=os.path.join(os.path.dirname(__file__),'ddns.log'),level=logging.INFO,format='%(asctime)s %(message)s',datefmt='%Y-%m-%d %H:%M:%S',encoding='utf8')
s = requests.session()
s.mount('https://', HTTPAdapter(max_retries=5))# 超时重传次数
login_token = 'id,token'
domain_id = 'domain_id'
ip_list = ["one"]
# curl 'https://dnsapi.cn/Domain.List' -d 'login_token=<login_token>&format=json' 获取domain_id
record_id = ''
def getRecordID():
    """
    获取record_id
    """
    global record_id
    logging.info("获取dns记录ing,可能会卡主")
    url = 'https://dnsapi.cn/Record.List'
    formdata = {
      'domain_id': domain_id,
      'login_token': login_token
    }
    try:
      login = s.post(url=url, data=formdata, timeout=2)
    except requests.exceptions.RequestException:
      logging.info("请求超时,请重试")
    rs = login.json()
    if rs.get('records'):
      record_id = rs['records']['id']
      logging.info("获取dns记录完毕")
    else:
      raise SystemError('获取dns记录失败')


def getIP():
    """
    获取IP地址
    """
    logging.info("获取iping")
    url = "http://www.3322.org/dyndns/getip"
    IPInfo = requests.get(url)
    IPInfo.encoding = 'UTF-8'
    ip = IPInfo.text
    logging.info("获取ip完毕")
    return ip


def check_ip():
    """
    检测IP地址是否变化
    """
    ip = getIP().strip()
    ip_list.append(ip)
    pop_ip = ip_list.pop(0)
    time.sleep(900) # 15分钟检测一次
    if pop_ip != 'one' and pop_ip != ip_list:
      return True
    else:
      return False
   
def start_once_ddns():
    """
    程序第一次运行执行一次
    """
    url = 'https://dnsapi.cn/Record.Ddns'
    getRecordID()
    ip = getIP().strip()
    formdata = {
                'domain_id': domain_id,
                'login_token': login_token,
                'record_line': '默认',
                'record_line_id': '10=1',
                'value': ip,
                'record_id': record_id
            }
    try:
      rs = s.post(url=url, data=formdata, timeout=2)
    except requests.exceptions.RequestException:
      logging.info("首次请求超时,请重试!")
    if (json.loads(rs.text)['status']['code'] == '1'):
      message = json.loads(rs.text)['status']['message'], '域名解析已更改为' + ip
      logging.info(str(message))
    else:
      logging.info("首次操作失败")

      
def updateRecord():
    """
    循环监听IP变化,如果IP改变则更新记录
    """
    global ip_list
    while True:
      if check_ip():
            logging.info("更改解析ing,可能会卡住")
            url = 'https://dnsapi.cn/Record.Ddns'
            formdata = {
                'domain_id': domain_id,
                'login_token': login_token,
                'record_line': '默认',
                'record_line_id': '10=1',
                'value': ip_list,
                'record_id': record_id
            }
            try:
                rs = s.post(url=url, data=formdata, timeout=2)
            except requests.exceptions.RequestException:
                getRecordID() # 如果失败,可能是因为record_id被删除或者过期,重新获取
                logging.info("请求超时,请重试!")
            if (json.loads(rs.text)['status']['code'] == '1'):
                message = json.loads(rs.text)['status']['message'], '域名解析已更改为' + ip_list
                logging.info(str(message))
            else:
                logging.info("操作失败")

if __name__ == '__main__':
    t1 = Thread(target=start_once_ddns)
    t1.start()
    t1.join()
    updateRecord()
   

无有代者 发表于 2022-5-26 16:36

全平台通用,无依赖
# This program establish ddns service
# to modify the public ip address of dns server.
# The dns server is dnspod.
# /etc/crontab # if centos etc.
# */10 * * * * root /usr/local/sbin/dnspod_ddns.sh 1>&2> /dev/null
# /etc/crontabs/root # if openwrt etc.
# */10 * * * * /usr/sbin/dnspod_ddns.sh

TOKEN="1,44e"
DOMAIN="y5.p"
SUB_DOMAIN="test"

# TOKEN=`cat dnspod_ddns.conf|grep TOKEN|awk -F'=' '{print $2}'`
# DOMAIN=`cat dnspod_ddns.conf|grep -e '^DOMAIN'|awk -F'=' '{print $2}'`
# SUB_DOMAIN=`cat dnspod_ddns.conf|grep SUB_DOMAIN|awk -F'=' '{print $2}'`


DATA="login_token=$TOKEN&format=json&domain=$DOMAIN&sub_domain=$SUB_DOMAIN&record_type=A&offset=0&length=3"
JOSN_RECORDS=`curl -4 -s -X POST https://dnsapi.cn/Record.List -d $DATA`

RECORD_ID=`echo $JOSN_RECORDS|sed '/id/ s/.*id":"\(.*\)","ttl.*/\1/'`
LINE_ID=`echo $JOSN_RECORDS|sed '/line_id/ s/.*line_id":"\(.*\)","type.*/\1/'`
#=================get record ip
IP_RESOLVED=`echo $JOSN_RECORDS|sed '/value/ s/.*value":"\(.*\)","enabled.*/\1/'`

#================get real ip
#REAL_IP=`cat</dev/tcp/ns1.dnspod.net/6666`
REAL_IP=`curl -4 -smyip.ipip.net|awk -F' |:' '{print $3}'`

#REAL_IP="2.2.3.2"
if [ $REAL_IP != $IP_RESOLVED ]; then
        #================modify record
        DATA="login_token=$TOKEN&format=json&domain=$DOMAIN&record_id=$RECORD_ID&sub_domain=$SUB_DOMAIN&value=$REAL_IP&record_type=A&record_line_id=$LINE_ID"
        # echo $DATA
        JSON_RESULT=`curl -4 -s -X POST https://dnsapi.cn/Record.Modify -d $DATA`
        echo $JSON_RESULT >> /var/log/dnspod_ddns.log
        IP_RESOLVED=$REAL_IP
fi

JieW_L 发表于 2022-5-25 17:15

github上有纯shell的啊

Licoy 发表于 2022-5-25 17:29

可以使用这个godns,支持windows,macos,linux:https://github.com/TimothyYe/godns

话痨司机啊 发表于 2022-5-25 17:32

JieW_L 发表于 2022-5-25 17:15
github上有纯shell的啊

我都不知道啊~

话痨司机啊 发表于 2022-5-25 17:37

Licoy 发表于 2022-5-25 17:29
可以使用这个godns,支持windows,macos,linux:https://github.com/TimothyYe/godns

半吊子不会Go语言。。我LINUX用是不是得安装GO环境,有DOCKER版本的吗?

Licoy 发表于 2022-5-25 17:39

话痨司机啊 发表于 2022-5-25 17:37
半吊子不会Go语言。。我LINUX用是不是得安装GO环境,有DOCKER版本的吗?

不用安装go环境呀,直接下载发行版然后运行就可以了

Licoy 发表于 2022-5-25 17:40

话痨司机啊 发表于 2022-5-25 17:37
半吊子不会Go语言。。我LINUX用是不是得安装GO环境,有DOCKER版本的吗?

https://github.com/TimothyYe/godns/releases/tag/v2.7.7

JieW_L 发表于 2022-5-25 17:55

楼上Go语言的那个太强大了,功能很多
单纯只用DNSPOD,可以试试这个
https://github.com/rehiy/dnspod-shell

话痨司机啊 发表于 2022-5-25 20:00

本帖最后由 话痨司机啊 于 2022-5-25 20:03 编辑

Licoy 发表于 2022-5-25 17:39
不用安装go环境呀,直接下载发行版然后运行就可以了



readme.md -> GOOS=linux GOARCH=mips/mipsle GOMIPS=softfloat go build -a

我用的linux系统的,不能运行exe,不过还是谢谢啦~

话痨司机啊 发表于 2022-5-25 20:04

本帖最后由 话痨司机啊 于 2022-5-25 20:07 编辑

JieW_L 发表于 2022-5-25 17:55
楼上Go语言的那个太强大了,功能很多
单纯只用DNSPOD,可以试试这个
https://github.com/rehiy/dnspod-sh ...
跟我思路差不多,他写的多了一个IPV6的,我写的多了个log日志记录变更信息的,不过还是长知识了,谢谢~
页: [1] 2
查看完整版本: DDNS_DNSPOD 亲测可用