一些场景下需要动态修改 DNS,可以帮助我们在动态 IP 的情况下实现搭建服务器,远程访问本地桌面等功能。阿里云官方虽然没有 DDNS,但是开放了 API。使用 DDNS 需要有公网 IP,如果没有可以使用 NPS 实现内网穿透。本文将介绍 使用 Python 实现阿里云 DDNS 。
1 创建 RAM 用户
进入 RAM 控制台,点击 人员管理 > 用户 > 新建用户。输入登录名称和显示名称后,勾选 编程访问,然后点击确定完成用户创建。
接下来为新建立的用户进行授权。为了安全,仅为用户授予操作域名的权限。点击 人员管理 > 用户。找到刚刚建立的用户,点击添加权限。勾选 管理域名服务的权限 AliyunDomainFullAccess,然后点击确定完成授权。
备注:
用户建立后会自动建立 AccessKey。AccessKeySecret 仅会在建立时显示一次,后续将无法再次查看。如果遗忘只能建立新的 AccessKey。
在 人员管理 > 设置 > 安全设置 \ 高级设置 中可以进行提高安全性和访问便利性的设置。
2 环境设置
安装 阿里云核心SDK 和 阿里云域名SDK
pip install aliyun-python-sdk-core
pip install aliyun-python-sdk-alidns
当 python 有两个版本共存时,使用 pip
安装可能会造成其中一个版本无法使用库,运行时报错
No module named 'aliyunsdkcore'
这样则需要在 pip
前添加 python2 -m
或 python3 -m
,或者使用 pip3
替代 pip
来为 python3
安装库。
3 Python 代码
import os
import json
import urllib.request
import time
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.UpdateDomainRecordRequest import UpdateDomainRecordRequest
AccessKeyId = " "
AccessSecret = " "
ip_dir = "./ip"
RR = " "
Type = "A"
DomainName = " "
while True:
if not os.path.isfile(ip_dir):
print("初始化ip缓存文件")
open(ip_dir,'w')
with urllib.request.urlopen('http://www.3322.org/dyndns/getip') as response:
html = response.read()
ip = str(html, encoding='utf-8').replace("\n","")
with open(ip_dir,'r') as fd:
ip_last=fd.read()
if ip == ip_last:
print("当前ip与缓存ip相同")
else:
print("当前ip "+ip+" 与缓存ip "+ip_last+" 不相同,开始更新DNS")
client = AcsClient(AccessKeyId, AccessSecret , 'cn-hangzhou')
request = DescribeSubDomainRecordsRequest()
request.set_accept_format('json')
request.set_SubDomain(DomainName)
response = client.do_action_with_exception(request)
data = json.loads(str(response, encoding='utf-8'))
for Record in data["DomainRecords"]["Record"]:
if Record["RR"] == RR:
RecordId = Record["RecordId"]
if Record["Value"] == ip:
print("DNS值 "+Record["Value"]+" 与当前ip "+ip+" 相同")
else:
request = UpdateDomainRecordRequest()
request.set_accept_format('json')
request.set_RecordId(RecordId)
request.set_RR(RR)
request.set_Type(Type)
request.set_Value(ip)
response = client.do_action_with_exception(request)
print(str(response, encoding='utf-8'))
print("更新ip缓存")
fd=open(ip_dir,'w')
fd.write(ip)
fd.close()
time.sleep(60)
4 使用 Systemctl 进行守护
建立文件 /etc/systemd/system/ddns.service
,加入下面内容
[Unit]
Description=Aliyun DDNS
After=rc-local.service
[Service]
Type=simple
User=pi
Group=pi
WorkingDirectory=/home/pi/ddns
ExecStart=/usr/bin/python3 ddns.py
StartLimitIntervalSec=0
Restart=always
RestartSec=1
[Install]
WantedBy=multi-user.target
其中 User
、 Group
、 WorkingDirectory
根据实际状况设置。设置完成后就可以使用 Systemctl 的功能控制刚刚编写的 DDNS 程序了。