一、前情提要

​ 由于当前IPv4公网地址匮乏 ,一般来说,即便你是电信或联通的宽带,运营商默认也是不会给你分配公网 IP 的,需要向运营商提出申请,根据地区不同,申请难易程度不同。少数地区可以通过公众号或装维师父直接联系申请,大部分地区需要拨打人工客服(电信 10000,联通 10010)以“家中要安装家庭网络摄像头”为理由申请动态公网 IP(千万不能说是服务器或其他设备),少数地区可能一次无法申请成功(很多客服不清楚动态公网 IP,所以可以尝试多换几个客服),申请成功后重启光猫即可。不过运营商提供的公网IP地址是动态的,一段时间后或光猫/路由器重启,公网IP地址就发生变化。 这就导致我们不能直接把得到的公网IP绑定到自己的域名上,每次IP地址发生变化,域名就无法访问了。于是就需要用到DDNS服务。DDNS(动态域名解析)是把互联网域名指向可变IP地址的系统。DNS只是提供了域名和IP地址之间的静态对应关系,当IP地址发生变化时,DNS无法动态的更新域名和IP地址之间的对应关系,从而导致访问失败。但是DDNS系统是将用户的动态IP地址映射到一个固定的域名解析服务上,用户每次连接网络时,客户端程序通过信息传递把该主机的动态IP地址传送给位于服务商主机上的服务器程序,实现动态域名解析。

​ 官方文档可参考 阿里云 DNS API 快速入门 。

注:现在不少路由器都带有DDNS服务,不过提供的服务商有限仅支持花生壳、公云等。要想使用自己手头的阿里域名就需要自己来解决了。

二、准备

前期准备

1、公网IP(向运营商申请的动态IP)

2、域名(通过阿里云购买的域名)

3、可以运行python程序的服务器(路由器/电脑/树莓派)

4、安装两个Python-SDK库

# 核心库
pip install aliyun-python-sdk-core
# 域名库
pip install aliyun-python-sdk-alidns

aliyunsdkcore.acs_exception.exceptions.ClientException

如果出现该报错:aliyunsdkcore.acs_exception.exceptions.ClientException: SDK.HttpError (‘Connection aborted.’, ConnectionResetError(104, ‘Connection reset by peer’))

安装另一个核心库即可,安装代码如下:

pip install aliyun-python-sdk-core-v3

三、获取 AccessKey

通过阿里云控制台进入RAM访问控制页面新建子用户,获取 AccessKey ID 和 AccessKey Secret


四、实现逻辑

1、获取当前IP

2、存储获取到的IP

3、比对IP(因为阿里云不允许修改相同的解析,所以需要比对IP是否有变化)

4、获取解析记录列表

#!/usr/bin/env python
#coding=utf-8from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequestclient = AcsClient('', '', 'cn-hangzhou')request = DescribeDomainRecordsRequest()
request.set_accept_format('json')request.set_DomainName("xx.com")response = client.do_action_with_exception(request)

5、添加解析记录

#!/usr/bin/env python
#coding=utf-8from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequestclient = AcsClient('', '', 'cn-hangzhou')request = AddDomainRecordRequest()
request.set_accept_format('json')request.set_DomainName("xx.com")
request.set_RR("@")
request.set_Type("A")
request.set_Value("60")response = client.do_action_with_exception(request)

6、修改解析记录

#!/usr/bin/env python
#coding=utf-8from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequestclient = AcsClient('', '', 'cn-hangzhou')request = UpdateDomainRecordRequest()
request.set_accept_format('json')request.set_RecordId("xx.com")
request.set_RR("@")
request.set_Type("A")
request.set_Value("60")response = client.do_action_with_exception(request)

五、源代码

github地址:https://github.com/a-00/AliyunDDNS

DDNS.py

#!/usr/bin/env python
# coding=utf-8"""
新增域名解析记录,参数说明如下:
:填写自己的accessKey,建议使用RAM角色管理的Key:填写自己的accessSecret,建议使用RAM角色管理的Secret
"""import os
import time
from aliyunsdkcore.client import AcsClient
from cxxh_function import wirte_to_file
from cxxh_function import add_record
from cxxh_function import update_record
from cxxh_function import Describe_Domain_Records
from cxxh_function import get_internet_ipwhile True:# 判断存放IP的文件是否存在,不存在则创建if os.path.exists("./ip"):passelse:wirte_to_file("./ip", "0.0.0.0")client = AcsClient('LTAI4G3PiidWoszTkEpC9DL8', '7Dx8BPqiy0Tyq822mPDMYEKmrT7SOt', 'cn-hangzhou')try:# 通过函数获取外网ipip = get_internet_ip()# print(ip)except Exception as e:print(e)pass# 下面开始对比ip,如果ip与之前记录的ip一致,则不执行任何操作,如果ip有变化,则会更新本地存储文件和更新域名解析with open("./ip", 'r') as f:old_ip = f.read()if ip == old_ip:print("本地记录未更新"+"\nnew_ip:"+ip+"\nold_ip:"+old_ip)else:des_relsult = Describe_Domain_Records(client, "A", "cccc.com")# 判断域名解析记录查询结果,TotalCount为0表示不存在这个域名的解析记录,需要新增一个if des_relsult["TotalCount"] == 0:add_relsult = add_record(client, "5", "600", "A", ip, "@", "cccc.com")record_id = add_relsult["RecordId"]print("域名解析新增成功!")wirte_to_file("./ip", ip)print("本地记录已更新"+"\nnew_ip:"+ip+"\nold_ip:"+old_ip)# 判断域名解析记录查询结果,TotalCount为1表示存在这个域名的解析记录,需要更新解析记录,更新记录需要用到RecordId,这个在查询函数中有返回des_relsult["DomainRecords"]["Record"][0]["RecordId"]elif des_relsult["TotalCount"] == 1:record_id = des_relsult["DomainRecords"]["Record"][0]["RecordId"]update_record(client, "5", "600", "A", ip, "@", record_id)print("域名解析更新成功!")wirte_to_file("./ip", ip)print("本地记录已更新"+"\nnew_ip:"+ip+"\nold_ip:"+old_ip)else:TotalCount = des_relsult["TotalCount"]print("存在%d个域名解析记录值,请核查删除后再操作!" % TotalCount)time.sleep(120)

cxxh_function.py

from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest
from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest
from aliyunsdkalidns.request.v20150109.DescribeSubDomainRecordsRequest import DescribeSubDomainRecordsRequest
import urllib.request
import json
import re# 写入文件
def wirte_to_file(path, content):with open(path, 'w') as f:f_name = open(path, 'w')f_name.write(content)# 新增解析记录,返回json格式的数据
def add_record(client, priority, ttl, record_type, value, rr, domainname):request = AddDomainRecordRequest()request.set_accept_format('json')request.set_Priority(priority)request.set_TTL(ttl)request.set_Value(value)request.set_Type(record_type)request.set_RR(rr)request.set_DomainName(domainname)response = client.do_action_with_exception(request)response = str(response, encoding='utf-8')relsult = json.loads(response)return relsult# 更新解析记录
def update_record(client, priority, ttl, record_type, value, rr, record_id):request = UpdateDomainRecordRequest()request.set_accept_format('json')request.set_Priority(priority)request.set_TTL(ttl)request.set_Value(value)request.set_Type(record_type)request.set_RR(rr)request.set_RecordId(record_id)response = client.do_action_with_exception(request)response = str(response, encoding='utf-8')return response# 获取解析记录列表
def Describe_Domain_Records(client, record_type, domainname):request = DescribeDomainRecordsRequest()request.set_accept_format('json')request.set_Type(record_type)request.set_DomainName(domainname)response = client.do_action_with_exception(request)response = str(response, encoding='utf-8')relsult = json.loads(response)return relsult# 获取外网地址
def get_internet_ip():url1 = 'https://ip.cn/api/index?ip=&type=0'url2 = 'http://www.3322.org/dyndns/getip'headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0'}req = urllib.request.Request(url=url1, headers=headers)  with urllib.request.urlopen(req) as response:html = response.read().decode('utf-8')ip = re.findall('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', html)[0]return ip

六、参考链接

使用Python调用阿里云解析DNS API实现DDNS(动态域名解析)

【script】python 调用阿里云解析 DNS API 实现 DDNS(动态域名解析)相关推荐

  1. python调用阿里云sdk

    python调用阿里云sdk python阿里SDK 安装阿里云 Python SDK 使用Python SDK 导入包 实例Action python阿里SDK 安装阿里云 Python SDK 完 ...

  2. 调用阿里云短信API发送短信通知

    调用阿里云短信API发送短信通知 昨天领导让我弄一个短信通知功能,原来也没有搞过,刚接过来的时候亚历山大,感觉很难搞.但是看过官方文档之后还是挺简单的.来让我们看一下这个短信接口怎么搞吧. 首先你需要 ...

  3. 使用java调用阿里云车牌识别API

    实现车牌识别功能我采用调用阿里云车牌识别API的方法,我使用的是eclipse,jdk 1.8,Tomcat 9.0 1.进入阿里云主页先创建阿里云账号 2.在控制台的头像那里找到AccessKey管 ...

  4. 阿里云添加DNS API 的accesskey

    阿里云添加DNS API 的accesskey 进入阿里云,在左侧栏搜索 "访问控制",然后来到访问控制界面,如果没有开通,直接开通就OK, 然后在进入用户管理->新建用户( ...

  5. JAVA中调用阿里云语音通知Api并接收消息回执

    JAVA中调用阿里云语音通知Api并接收消息回执 配置文件 需要的包 <dependency><groupId>com.aliyun</groupId><ar ...

  6. Python调用阿里云数据库监控数据

    概述 基于Python 3.6.0 实现 抓取公司云数据库监控数据 存入本地数据库 centos定时任务 每分钟执行一次 引入SDK # 安装Python SDK 包 pip install aliy ...

  7. python调用阿里云sdk入门(hello world)

    关于Python及pycharm的安装参考:1. python+pycharm 安装及测试_Hehuyi_In的博客-CSDN博客_pycharm安装成功测试 本文直接介绍如何调用阿里云sdk访问云上 ...

  8. 如何实现调用阿里云三方的api

    我本来是想上传视频了,但是阿里云这个api的收费很魔性.所以我的appcode是无法上传的,本来还想着大家直接把代码运行就可以了.你们只要改下appcode就可以了. 这个其实有免费的服务,自己找下就 ...

  9. python如何调用阿里云接口_python 调用阿里云云解析api添加记录

    首先安装阿里云SDK pip install aliyun-python-sdk-core pip install aliyun-python-sdk-alidns 可以配合jenkins传递参数 # ...

  10. Python+阿里云DNS 搭建DDNS动态域名解析

    家用的动态公网IP在断电以及一段时间后会变化,现在家宽公网IP开网盘以及代理管得越来越严格,已经有检测到被封的案例 上海检测web封停 这让我这种挂种子的PT党(迫真)感到害怕 以前我把国外的免费域名 ...

最新文章

  1. 开放式创新改变世界——OpenStack生态系统将重新洗牌
  2. [设计模式]设计模式之禅关于接口隔离原则
  3. poj-1064Cable master(二分)
  4. new 实例化对象是啥意思_前端经典面试题解密:JS的new关键字都干了什么?
  5. ECMS系统服务器死机的处理,内存问题服务器死机一例
  6. 【python】性能分析工具汇总
  7. python科学计算包与matlab_做科学计算用Python还是MATLAB?
  8. 分页查询为什么会报数组越界错误_Java Note-数据结构(1)数组
  9. apache配置好后编译rewrite
  10. css画三角形以及各种图形
  11. python nltk.download报错_python 文本转语音机器学习之nltk download安装测试包
  12. KeyPass密码管理软件使用说明
  13. 学校教材管理系统html,学校教材管理系统
  14. Android - View 和 ViewGroup
  15. 阅兵方阵(蓝桥杯2018真题)
  16. 【原创】QT5-卸载精灵v1.0-卸载windows软件-简易版
  17. 饥荒联机版服务器控制台本地和在线,饥荒联机版服务器代码有哪些_服务器常用指令一览_3DM单机...
  18. js-函数式编程-柯里化和语义化
  19. #三、股市数学拟合理论的理论兼容
  20. 基于vc的freetype字体轮廓解析_字体术语集

热门文章

  1. SecureCRT 不能输入命令及回车键不能用
  2. 计算机启动方式如何选择USB启动,bios设置usb启动的方法
  3. 任小龙 mysql笔记_小码哥-任小龙Java笔记-面向对象的全部笔记.pdf
  4. 美国大学 计算机,U.S.News美国大学计算机专业排名
  5. JAVA 通过wContour和geotools实现等值面分析、裁切、出图
  6. img标签底部总是留有一条白色空隙
  7. C# GDI+ 时钟表盘
  8. Excel 如何合并工作簿中多个工作表
  9. 用QQ聊天记录生成一个词云
  10. LHC有望揭示新的物理学理论