【DDNS】Python实现阿里云域名DDNS

第一步:拥有阿里云域名,设置阿里云域名管理账号

转载自:https://www.jianshu.com/p/b8e01206f58c
1.1 登录阿里云控制台
1.2 在产品与服务中搜“访问控制”
在这里插入图片描述
1.3 创建新用户,只勾选编程访问。
这里要记住AccessKeyID和AccessKey Secret,后面需要用到。
在这里插入图片描述
1.4 添加DNS管理权限
找到AliyunDNSFullAccess权限,并添加。
在这里插入图片描述

第二步:新建加载运行python文件

参考:https://blog.zeruns.tech/archives/507.html
实际使用时会遇到请求超时等情况.
作出了一些代码的修改:(目前只修改了ipv4,ipv6自行参考修改~)
1.在超时时不再请求。
2.断网重连
1.环境安装:
python环境

2.需要安装的库:

pip install aliyun-python-sdk-core-v3
pip install aliyun-python-sdk-domain
pip install aliyun-python-sdk-alidns
pip install requests

3.新建aliddns.py文件,修改配置:

accessKeyId = "xxx"  # 将accessKeyId改成自己的accessKeyId
accessSecret = "xxx"  # 将accessSecret改成自己的accessSecret
domain = "xxx.cn"  # 你的主域名
name_ipv4 = "xxx"  # 要进行ipv4 ddns解析的子域名
name_ipv6 = ""  # 要进行ipv6 ddns解析的子域名

4.用cmd运行aliddns.py文件
改进后的aliddns.py文件
添加了ping IP的方法get_external_ip(),用来防止ip检测的网站挂掉。

from ast import For
from operator import truediv
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkalidns.request.v20150109.DescribeSubDomainRecordsRequest import DescribeSubDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequest
import requests
from urllib.request import urlopen
import json
# import subprocess
from datetime import datetime
from threading import Timer
# import socket

ipv4_flag = 1  # 是否开启ipv4 ddns解析,1为开启,0为关闭
ipv6_flag = 0  # 是否开启ipv6 ddns解析,1为开启,0为关闭
accessKeyId = "xxx"  # 将accessKeyId改成自己的accessKeyId
accessSecret = "xxx"  # 将accessSecret改成自己的accessSecret
domain = "xxx.cn"  # 你的主域名
name_ipv4 = "xxx"  # 要进行ipv4 ddns解析的子域名
name_ipv6 = ""  # 要进行ipv6 ddns解析的子域名


print_str = []

client = AcsClient(accessKeyId, accessSecret, 'cn-hangzhou')

def update(RecordId, RR, Type, Value):  # 修改域名解析记录
    from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest
    request = UpdateDomainRecordRequest()
    request.set_accept_format('json')
    request.set_RecordId(RecordId)
    request.set_RR(RR)
    request.set_Type(Type)
    request.set_Value(Value)
    response = client.do_action_with_exception(request)
    


def add(DomainName, RR, Type, Value):  # 添加新的域名解析记录
    from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest
    request = AddDomainRecordRequest()
    request.set_accept_format('json')
    request.set_DomainName(DomainName)
    request.set_RR(RR)
    request.set_Type(Type)
    request.set_Value(Value)    
    response = client.do_action_with_exception(request)
    print_str.append("%s"%response)

def ping(): #ping百度查看网络状态,断网重新执行方法
  try:
   html = requests.get("https://www.aliyun.com",timeout=10)
  except:
   print_str.append("未获取ping通")
   return 0
  return 1
    # return1 = subprocess.call('ping www.baidu.com', shell = False)
    # if return1:
    #   return 0
    # else:
    #   return 1

def get_external_ip():
  #使用try 捕捉异常
  try:
    #ip = urlopen(url='https://api-ipv4.ip.sb/ip',timeout=10.0).read()  # 使用IP.SB的接口获取ipv4地址,这个网址崩溃过
    ip = urlopen(url='http://ifconfig.me',timeout=10.0).read()  # 获取ipv4地址
  except:
    print_str.append("未获取到ip地址")
    # try:
    #   ip = urlopen(url='https://api4.ipify.org',timeout=10.0).read()  # 获取ipv4地址
    # except:
    #   ip = requests.get('https://ident.me').text.strip()
    #   return ip
    # return ip
  return ip

def setDnsv4():
  if ipv4_flag == 1 & ping()==1:
      try:
        request = DescribeSubDomainRecordsRequest()
        request.set_accept_format('json')
        request.set_DomainName(domain)
        request.set_SubDomain(name_ipv4 + '.' + domain)
        request.set_Type("A")
        response = client.do_action_with_exception(request)  # 获取域名解析记录列表
        # print_str.append("获取域名解析记录列表:%s" % response)
        domain_list = json.loads(response)  # 将返回的JSON数据转化为Python能识别的
        # 加上timeout参数,可判断阿里云是否阻止访问
        #获取IPV4地址
        ip =get_external_ip()
        # print_str.append("获取到ip地址:%s" % ip)
        ipv4 = str(ip, encoding='utf-8')
        # print("获取到IPv4地址:%s" % ipv4)
        print_str.append("获取到IPv4地址:%s" % ipv4)


        if domain_list['TotalCount'] == 0:
            add(domain, name_ipv4, "A", ipv4)
            # print("新建域名解析成功")
            print_str.append("新建域名解析成功")
        elif domain_list['TotalCount'] == 1:
            if domain_list['DomainRecords']['Record'][0]['Value'].strip() != ipv4.strip():
                update(domain_list['DomainRecords']['Record'][0]['RecordId'], name_ipv4, "A", ipv4)
                # print("修改域名解析成功")
                print_str.append("修改域名解析成功")
            else:  # https://blog.zeruns.tech
                # print("IPv4地址没变")
                print_str.append("IPv4地址没变")
        elif domain_list['TotalCount'] > 1:
            from aliyunsdkalidns.request.v20150109.DeleteSubDomainRecordsRequest import DeleteSubDomainRecordsRequest
            request = DeleteSubDomainRecordsRequest()
            request.set_accept_format('json')
            request.set_DomainName(domain) 
            request.set_RR(name_ipv4)
            request.set_Type("A") 
            response = client.do_action_with_exception(request)
            add(domain, name_ipv4, "A", ipv4)
            # print("修改域名解析成功")
            print_str.append("修改域名解析成功")
      except Exception as err:
        print_str.append(err.__class__.__name__) # 错误类型
        print_str.append(err) # 错误明细
        # print("联网失败")
        print_str.append("联网失败")

  else:
    # print("联网失败")
    print_str.append("联网失败")


def setDnsv6():
  if ipv6_flag == 1 & ping()==1:
      request = DescribeSubDomainRecordsRequest()
      request.set_accept_format('json')
      request.set_DomainName(domain)
      request.set_SubDomain(name_ipv6 + '.' + domain)
      request.set_Type("AAAA")
      response = client.do_action_with_exception(request)  # 获取域名解析记录列表
      domain_list = json.loads(response)  # 将返回的JSON数据转化为Python能识别的

      ip = urlopen('https://api-ipv6.ip.sb/ip').read()  # 使用IP.SB的接口获取ipv6地址
      ipv6 = str(ip, encoding='utf-8')
      print("获取到IPv6地址:%s" % ipv6)

      if domain_list['TotalCount'] == 0:
          add(domain, name_ipv6, "AAAA", ipv6)
          print("新建域名解析成功")
      elif domain_list['TotalCount'] == 1:
          if domain_list['DomainRecords']['Record'][0]['Value'].strip() != ipv6.strip():
              update(domain_list['DomainRecords']['Record'][0]['RecordId'], name_ipv6, "AAAA", ipv6)
              print("修改域名解析成功")
          else: 
              print("IPv6地址没变")
      elif domain_list['TotalCount'] > 1:
          from aliyunsdkalidns.request.v20150109.DeleteSubDomainRecordsRequest import DeleteSubDomainRecordsRequest
          request = DeleteSubDomainRecordsRequest()
          request.set_accept_format('json')
          request.set_DomainName(domain)
          request.set_RR(name_ipv6)  # https://blog.zeruns.tech
          request.set_Type("AAAA") 
          response = client.do_action_with_exception(request)
          add(domain, name_ipv6, "AAAA", ipv6)
          print("修改域名解析成功")

# 打印时间函数
def timeSet(inc):
    print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
    setDnsv4()
    t = Timer(inc, timeSet, (inc,))
    t.start()
# 5s
timeSet(60)

以前的aliddns.py文件(此代码不稳定,请看已改进代码块)

from ast import For
from operator import truediv
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkalidns.request.v20150109.DescribeSubDomainRecordsRequest import DescribeSubDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequest
import requests
from urllib.request import urlopen
import json
# import subprocess
from datetime import datetime
from threading import Timer
# import socket

ipv4_flag = 1  # 是否开启ipv4 ddns解析,1为开启,0为关闭
ipv6_flag = 0  # 是否开启ipv6 ddns解析,1为开启,0为关闭
accessKeyId = "xxx"  # 将accessKeyId改成自己的accessKeyId
accessSecret = "xxx"  # 将accessSecret改成自己的accessSecret
domain = "xxx.cn"  # 你的主域名
name_ipv4 = "xxx"  # 要进行ipv4 ddns解析的子域名
name_ipv6 = ""  # 要进行ipv6 ddns解析的子域名


client = AcsClient(accessKeyId, accessSecret, 'cn-hangzhou')

def update(RecordId, RR, Type, Value):  # 修改域名解析记录
    from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest
    request = UpdateDomainRecordRequest()
    request.set_accept_format('json')
    request.set_RecordId(RecordId)
    request.set_RR(RR)
    request.set_Type(Type)
    request.set_Value(Value)
    response = client.do_action_with_exception(request)


def add(DomainName, RR, Type, Value):  # 添加新的域名解析记录
    from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest
    request = AddDomainRecordRequest()
    request.set_accept_format('json')
    request.set_DomainName(DomainName)
    request.set_RR(RR)
    request.set_Type(Type)
    request.set_Value(Value)    
    response = client.do_action_with_exception(request)

def ping(): #ping百度查看网络状态,断网重新执行方法
  try:
   html = requests.get("http://www.baidu.com",timeout=2)
  except:
   return 0
  return 1
    # return1 = subprocess.call('ping www.baidu.com', shell = False)
    # if return1:
    #   return 0
    # else:
    #   return 1

def setDnsv4():
  if ipv4_flag == 1 & ping()==1:
      try:
        request = DescribeSubDomainRecordsRequest()
        request.set_accept_format('json')
        request.set_DomainName(domain)
        request.set_SubDomain(name_ipv4 + '.' + domain)
        request.set_Type("A")
        response = client.do_action_with_exception(request)  # 获取域名解析记录列表
        domain_list = json.loads(response)  # 将返回的JSON数据转化为Python能识别的
        # 加上timeout参数,可判断阿里云是否阻止访问
        ip = urlopen(url='https://api-ipv4.ip.sb/ip',timeout=10.0).read()  # 使用IP.SB的接口获取ipv4地址
        ipv4 = str(ip, encoding='utf-8')
        print("获取到IPv4地址:%s" % ipv4)


        if domain_list['TotalCount'] == 0:
            add(domain, name_ipv4, "A", ipv4)
            print("新建域名解析成功")
        elif domain_list['TotalCount'] == 1:
            if domain_list['DomainRecords']['Record'][0]['Value'].strip() != ipv4.strip():
                update(domain_list['DomainRecords']['Record'][0]['RecordId'], name_ipv4, "A", ipv4)
                print("修改域名解析成功")
            else:  # https://blog.zeruns.tech
                print("IPv4地址没变")
        elif domain_list['TotalCount'] > 1:
            from aliyunsdkalidns.request.v20150109.DeleteSubDomainRecordsRequest import DeleteSubDomainRecordsRequest
            request = DeleteSubDomainRecordsRequest()
            request.set_accept_format('json')
            request.set_DomainName(domain) 
            request.set_RR(name_ipv4)
            request.set_Type("A") 
            response = client.do_action_with_exception(request)
            add(domain, name_ipv4, "A", ipv4)
            print("修改域名解析成功")
      except:
        print("联网失败")

  else:
    print("联网失败")

def setDnsv6():
  if ipv6_flag == 1 & ping()==1:
      request = DescribeSubDomainRecordsRequest()
      request.set_accept_format('json')
      request.set_DomainName(domain)
      request.set_SubDomain(name_ipv6 + '.' + domain)
      request.set_Type("AAAA")
      response = client.do_action_with_exception(request)  # 获取域名解析记录列表
      domain_list = json.loads(response)  # 将返回的JSON数据转化为Python能识别的

      ip = urlopen('https://api-ipv6.ip.sb/ip').read()  # 使用IP.SB的接口获取ipv6地址
      ipv6 = str(ip, encoding='utf-8')
      print("获取到IPv6地址:%s" % ipv6)

      if domain_list['TotalCount'] == 0:
          add(domain, name_ipv6, "AAAA", ipv6)
          print("新建域名解析成功")
      elif domain_list['TotalCount'] == 1:
          if domain_list['DomainRecords']['Record'][0]['Value'].strip() != ipv6.strip():
              update(domain_list['DomainRecords']['Record'][0]['RecordId'], name_ipv6, "AAAA", ipv6)
              print("修改域名解析成功")
          else: 
              print("IPv6地址没变")
      elif domain_list['TotalCount'] > 1:
          from aliyunsdkalidns.request.v20150109.DeleteSubDomainRecordsRequest import DeleteSubDomainRecordsRequest
          request = DeleteSubDomainRecordsRequest()
          request.set_accept_format('json')
          request.set_DomainName(domain)
          request.set_RR(name_ipv6)  # https://blog.zeruns.tech
          request.set_Type("AAAA") 
          response = client.do_action_with_exception(request)
          add(domain, name_ipv6, "AAAA", ipv6)
          print("修改域名解析成功")

# 打印时间函数
def timeSet(inc):
    print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
    setDnsv4()
    t = Timer(inc, timeSet, (inc,))
    t.start()
# 5s
timeSet(60)

转载时请标明文章中的出处和引用!

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值