利用Python+阿里云实现DDNS(动态域名解析)
因需求公司路由器公网ip不是动态的,需要及时的修改阿里云的域名解析
前期准备
二、准备
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
python安装
aliyun-python-sdk-core-v3
aliyun-python-sdk-alidns==2.0.6 #版本自定义
阿里云获取 AccessKey
通过阿里云控制台进入RAM访问控制页面新建子用户,获取 AccessKey ID 和 AccessKey Secret
创建用户
创建成功
实现逻辑
1、获取当前IP
2、存储获取到的IP
3、比对IP(因为阿里云不允许修改相同的解析,所以需要比对IP是否有变化)
4、获取解析记录列表
# 获取公网IP并进行修改
def Get_IPv4(self):
# 获取IP方法一
ipv4 = json.load(urlopen('http://jsonip.com'))['ip']
print("获取到IPv4地址:%s" % ipv4)
# 获取IP方法二,爬取IP地址
# ipv4 = getip()
request = DescribeSubDomainRecordsRequest()
request.set_accept_format('json')
request.set_DomainName(self.domain)
完整代码如下
from aliyunsdkcore.client import AcsClient
from aliyunsdkalidns.request.v20150109.DescribeSubDomainRecordsRequest import DescribeSubDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.DeleteSubDomainRecordsRequest import DeleteSubDomainRecordsRequest
from urllib.request import urlopen
import json
class Dnscontroller:
access_key_id = ""
#阿里云的新建账户id
access_key_secret = ""
region = ""
#时区
record_type = "A"
domain = ""
#上面是你的一级域名
name_ipv4 = ["二级域名1","二级域名2","二级域名3","二级域名4","二级域名5"]
#上面是你要修改的域名,我们的比较多,然后呢就以数组的方式去挨个修改
def __init__(self):
self.client = AcsClient(
self.access_key_id,
self.access_key_secret,
self.region
)
# 添加新的域名解析记录
def add(self, 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 = self.client.do_action_with_exception(request)
# 修改域名解析记录
def update(self, 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 = self.client.do_action_with_exception(request)
# 获取公网IP并进行修改
def Get_IPv4(self):
# 获取IP方法一
ipv4 = json.load(urlopen('http://jsonip.com'))['ip']
print("获取到IPv4地址:%s" % ipv4)
# 获取IP方法二,爬取IP地址
# ipv4 = getip()
request = DescribeSubDomainRecordsRequest()
request.set_accept_format('json')
request.set_DomainName(self.domain)
for item in self.name_ipv4:
request.set_SubDomain(item + '.' + self.domain)
response = self.client.do_action_with_exception(request)
domain_list = json.loads(response)
if domain_list['TotalCount'] == 0:
self.add(self.domain, item, self.record_type, ipv4)
print("新建域名:" + item + ",解析成功")
elif domain_list['TotalCount'] == 1:
if domain_list['DomainRecords']['Record'][0]['Value'].strip() != ipv4.strip():
self.update(domain_list['DomainRecords']['Record'][0]['RecordId'], item, self.record_type, ipv4)
print("修改域名:" + item + ",解析成功")
else:
print("IPv4地址没变")
elif domain_list['TotalCount'] > 1:
# 删除所有解析过的记录,并重新添加新的解析记录
request = DeleteSubDomainRecordsRequest()
request.set_accept_format('json')
request.set_DomainName(self.domain)
request.set_RR(item)
response = self.client.do_action_with_exception(request)
self.add(self.domain, item, self.record_type, ipv4)
print("修改域名解析成功")
if __name__ == "__main__":
Dnscontroller().Get_IPv4()
最终运行
2023年12月14日修改代码
增加功能
1添加用户代理信息来模拟浏览器请求
2尝试在每次请求之间添加延迟,以减缓请求速度
3添加没有 set_DomainName 方法
#!/usr/bin/env python3
from aliyunsdkcore.client import AcsClient
from aliyunsdkalidns.request.v20150109.DescribeSubDomainRecordsRequest import DescribeSubDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.DeleteSubDomainRecordsRequest import DeleteSubDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest
from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest
from urllib.request import Request, urlopen
import json
import time
class DnsController:
# 阿里云账户信息
access_key_id = ""
access_key_secret = ""
region = "cn-shanghai" # 阿里云区域
record_type = "A" # 解析记录类型
domain = "" # 一级域名
name_ipv4 = [""] # 待修改的子域名列表
def __init__(self):
# 初始化阿里云客户端
self.client = AcsClient(
self.access_key_id,
self.access_key_secret,
self.region
)
def add(self, RR, Type, Value):
# 创建添加域名解析记录的请求
request = AddDomainRecordRequest(DomainName=self.domain, RR=RR, Type=Type, Value=Value)
request.set_accept_format('json')
response = self.client.do_action_with_exception(request)
def update(self, RecordId, RR, Type, Value):
# 创建更新域名解析记录的请求
request = UpdateDomainRecordRequest(RecordId=RecordId, RR=RR, Type=Type, Value=Value)
request.set_accept_format('json')
response = self.client.do_action_with_exception(request)
def Get_IPv4(self):
# 添加延迟
time.sleep(1)
# 获取公网IPv4地址
url = 'http://jsonip.com'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'}
req = Request(url, headers=headers)
ipv4 = json.load(urlopen(req))['ip']
print("获取到IPv4地址:%s" % ipv4)
for item in self.name_ipv4:
# 创建获取子域名解析记录的请求
request = DescribeSubDomainRecordsRequest(SubDomain=item + '.' + self.domain)
request.set_accept_format('json')
response = self.client.do_action_with_exception(request)
domain_list = json.loads(response)
if domain_list['TotalCount'] == 0:
# 如果记录不存在,则新建
self.add(item, self.record_type, ipv4)
print("新建域名:" + item + ",解析成功")
elif domain_list['TotalCount'] == 1:
if domain_list['DomainRecords']['Record'][0]['Value'].strip() != ipv4.strip():
# 如果记录存在且IP不同,则更新
self.update(domain_list['DomainRecords']['Record'][0]['RecordId'], item, self.record_type, ipv4)
print("修改域名:" + item + ",解析成功")
else:
print("IPv4地址没变")
elif domain_list['TotalCount'] > 1:
# 如果存在多条记录,删除所有记录,并重新添加新的解析记录
for record in domain_list['DomainRecords']['Record']:
request = DeleteSubDomainRecordsRequest(DomainName=self.domain, RecordId=record['RecordId'])
request.set_accept_format('json')
response = self.client.do_action_with_exception(request)
self.add(item, self.record_type, ipv4)
print("修改域名解析成功")
if __name__ == "__main__":
DnsController().Get_IPv4()
2023年12月26日修改代码
增加功能
1UpdateDomainRecordRequest 类的构造方法不接受关键字参数
2出于安全考虑,避免硬编码敏感信息到脚本中,设置了 ALIYUN_ACCESS_KEY_ID 和 ALIYUN_ACCESS_KEY_SECRET 环境变量。
#!/usr/bin/env python3
from aliyunsdkcore.client import AcsClient
from aliyunsdkalidns.request.v20150109.DescribeSubDomainRecordsRequest import DescribeSubDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.DeleteSubDomainRecordsRequest import DeleteSubDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest
from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest
from urllib.request import Request, urlopen
import json
import time
import os
class DnsController:
def __init__(self):
self.access_key_id = os.environ.get('ALIYUN_ACCESS_KEY_ID')
self.access_key_secret = os.environ.get('ALIYUN_ACCESS_KEY_SECRET')
self.region = "cn-shanghai"
self.record_type = "A"
self.domain = ""
self.name_ipv4 = ["management", "www-test", "potree-test"]
self.client = AcsClient(
self.access_key_id,
self.access_key_secret,
self.region
)
def add(self, RR, Type, Value):
request = AddDomainRecordRequest()
request.set_DomainName(self.domain)
request.set_RR(RR)
request.set_Type(Type)
request.set_Value(Value)
request.set_accept_format('json')
response = self.client.do_action_with_exception(request)
def update(self, RecordId, RR, Type, Value):
request = UpdateDomainRecordRequest()
request.set_RecordId(RecordId)
request.set_RR(RR)
request.set_Type(Type)
request.set_Value(Value)
request.set_accept_format('json')
response = self.client.do_action_with_exception(request)
def Get_IPv4(self):
time.sleep(1)
url = 'http://jsonip.com'
headers = {'User-Agent': 'Mozilla/5.0'}
req = Request(url, headers=headers)
ipv4 = json.load(urlopen(req))['ip']
print("获取到IPv4地址:%s" % ipv4)
for item in self.name_ipv4:
request = DescribeSubDomainRecordsRequest()
request.set_SubDomain(item + '.' + self.domain)
request.set_accept_format('json')
response = self.client.do_action_with_exception(request)
domain_list = json.loads(response)
if domain_list['TotalCount'] == 0:
self.add(item, self.record_type, ipv4)
print("新建域名:" + item + ",解析成功")
elif domain_list['TotalCount'] == 1:
if domain_list['DomainRecords']['Record'][0]['Value'].strip() != ipv4.strip():
self.update(domain_list['DomainRecords']['Record'][0]['RecordId'], item, self.record_type, ipv4)
print("修改域名:" + item + ",解析成功")
else:
print("IPv4地址没变")
elif domain_list['TotalCount'] > 1:
request = DeleteSubDomainRecordsRequest()
request.set_DomainName(self.domain)
request.set_RR(item)
request.set_accept_format('json')
response = self.client.do_action_with_exception(request)
self.add(item, self.record_type, ipv4)
print("已清除过旧的记录,并更新了域名:" + item)
if __name__ == "__main__":
DnsController().Get_IPv4()
添加环境变量
macOS 或 Linux
在 macOS 或 Linux 系统中,你通常会在 ~/.bash_profile, ~/.bashrc, ~/.zshrc 或其他相似的shell配置文件中设置环境变量。
打开终端并根据你使用的Shell输入下列命令:
export ALIYUN_ACCESS_KEY_ID="你的AccessKeyId"
export ALIYUN_ACCESS_KEY_SECRET="你的AccessKeySecret"
为了使这些变量永久生效,你可以将它们添加到你的用户home目录下的 .bashrc 或 .zshrc 配置文件中。可以通过在终端中运行以下命令来完成:
echo 'export ALIYUN_ACCESS_KEY_ID="你的AccessKeyId"' >> ~/.bashrc
echo 'export ALIYUN_ACCESS_KEY_SECRET="你的AccessKeySecret"' >> ~/.bashrc
source ~/.bashrc
如果你的shell是zsh(如在最新版的macOS中),请将 .bashrc 替换为 .zshrc。
请记得将 “你的AccessKeyId” 和 “你的AccessKeySecret” 替换为你实际的凭据值。如果你不确定使用的shell类型,请通过 echo $SHELL 命令来检查。
设置后,你可以通过在终端中运行 echo $ALIYUN_ACCESS_KEY_ID 和 echo $ALIYUN_ACCESS_KEY_SECRET 来检查变量是否设置成功。
linux服务器上面添加计划任务定时执行
安装python3.7
网上找一下文档这里我就省略到了
wget https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tgz
在linux上执行python
步骤1;先查找python的 绝对路径
使用 which 查询 python3 解释器所在路径
安装阿里云DNS依赖
pip3 install pyyaml
pip3 install aliyun-python-sdk-core-v3
pip3 install aliyun-python-sdk-alidns==2.0.6
修改要运行的 主 python 文件,在第一行增加以下内容
#! /usr/bin/python3
-
#!
这个符号叫做Shebang
或者Sha-bang
-
Shebang
通常在Unix
系统脚本的中 第一行开头 使用 - 指明 执行这个脚本文件 的 解释程序
骤2;先找的python这个文件的路径
上传到服务器上
步骤;给文件一个可以执行权限
修改 主 python 文件 的文件权限,增加执行权限
$ chmod +x dns.py
步骤;运行测试
root@192:~/python_dns# python3 dns.py
获取到IPv4地址:xxxxxxxxx
IPv4地址没变
IPv4地址没变
IPv4地址没变
IPv4地址没变
IPv4地址没变
添加Crontab的使用
配置计划任务每天执行
一、Crontab的安装
1、Debian下面安装Crontab
apt-get install cron //大部分情况下Debian都已安装。
/etc/init.d/cron restart //重启Crontab
二、Crontab使用方法
1、查看crontab定时执行任务列表
crontab -l
1
2、添加crontab定时执行任务
crontab -e
————————————————文章来源:https://www.toymoban.com/news/detail-455076.html
0 9 * * 1 python3 /root/python_dns/dns.py > dns.log #每周一早上9点执行这个python
装。
/etc/init.d/cron restart //重启Crontab
二、Crontab使用方法
1、查看crontab定时执行任务列表
crontab -l
1
2、添加crontab定时执行任务
crontab -e
————————————————
0 9 * * 1 python3 /root/python_dns/dns.py > dns.log #每周一早上9点执行这个python
[外链图片转存中…(img-yVBcSUP9-1662623656428)]文章来源地址https://www.toymoban.com/news/detail-455076.html
到了这里,关于利用Python+阿里云实现DDNS(动态域名解析)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!