前言
首先得有一个域名而且是使用阿里云的云解析dns服务,
然后你的IP必须是公网IP,或者是校园网那种绑定宽带账号后代理拨号的(经过nat转换之后依旧能够通过公网ip+端口访问到本地的主机)不然解析了也没用。
本文章讲怎样通过阿里云的SDK来添加修改域名解析,检查本机IP与解析的IP是否一致,不一致自动修改解析,达到动态解析的目的,主要用于家庭宽带这些动态IP的地方。
开启路由器端口映射
需要开启路由器或者光猫的upnp(推荐)或者DMZ,方便从外网直接访问到本地的主机。
此外,upnp和DMZ二选一即可,不能同时开,不然可能会丢包,影响网络。upnp是自动的安全一些,我们还可以自己通过指令或者软件修改upnp列表以达到开启制定端口的映射。可以参考这篇文章:
安装阿里云的SDK
电脑的pip版本不同,可能有所变化(pip/pip3)。
pip3 install aliyun-python-sdk-core-v3
pip3 install aliyun-python-sdk-alidns获取accessKeyId和accessSecret
可以在阿里云控制台个人中心直接获取,但是一般建议使用RAM角色来进行权限控制,这样这个accessKey和accessSecret就只能操作域名,不能操作其他的资源,相对会比较安全。关于RAM快速入门:https://help.aliyun.com/zh/ram/getting-started/
源码下载
程序原版
这个程序版权属于zeruns,大家可以去看他的博客:https://blog.zeruns.tech
gitee:https://gitee.com/zeruns/aliddns_Python
github:https://github.com/zeruns/-Python-aliddns_ipv4-ipv6
将源码中的aliddns.py文件下载下来。
一般只需要修改10-16行中的对应内容即可。里面写得很详细了。
脚本优化1
由于zeruns写的脚本只有单个ip识别网址,当网址不可用时,会造成ddns服务中断。
因此对脚本进行了修改,增加了识别网址,并且将接口列表改成更易扩展的数组形式(按顺序遍历所有可用接口),以便随时增加/删除接口吗?我可以把获取逻辑封装成函数,代码更简洁且更易维护。
下载:
github:https://github.com/tianlingzi/Python-aliyunddns
本站:
工作原理
脚本通过通用函数
get_public_ip(endpoints, version, timeout, retries)逐个接口获取公网 IP:- IPv4:使用正则与区间校验过滤合法地址。
- IPv6:使用
ipaddress.IPv6Address校验合法性。 - 每个接口请求使用
urlopen(..., timeout=10),避免卡住;失败会自动切换到下一个接口;三者都失败后根据重试次数进行循环。
获取到 IP 后,调用 AliDNS API 管理解析记录:
- 使用
DescribeSubDomainRecordsRequest查询现有记录。 - 无记录:
AddDomainRecordRequest新建。 - 有一条且值不同:
UpdateDomainRecordRequest修改。 - 多条记录:
DeleteSubDomainRecordsRequest清理子域名后再新建。
- 使用
- 记录类型:IPv4 使用
A,IPv6 使用AAAA。
使用方法
Windows(在脚本目录):
- 运行:
python aliyunddns.py
- 运行:
Linux:
- 运行:
python3 /path/to/aliyunddns.py - 如你将脚本重命名为
aliddns.py,运行时请替换对应路径与文件名。
- 运行:
多子域名示例
同时解析多个子域名:
name1_ipv4 = "www,home,@"name1_ipv6 = "nas,router"
@代表根记录(即主域名本身)。
定时任务示例
- Windows 任务计划程序:创建“基本任务”,触发器选择每 5 分钟,操作选择“启动程序”,程序为
python,参数填写脚本路径如d:\vscode\aliyunddns\aliyunddns.py。 Linux
crontab:crontab -e,添加:*/5 * * * * /usr/bin/python3 /path/to/aliyunddns.py >> /var/log/aliyunddns.log 2>&1
常见问题
NameError: name 'get_public_ip' is not defined:- 请确认你使用的是最新版脚本,且未在调用前删除或移动该函数定义。
获取接口卡住不切换:
- 脚本已对所有接口设置
timeout,你可按需调整timeout值(默认 10 秒)。
- 脚本已对所有接口设置
解析失败或权限报错:
- 确认
accessKeyId/accessSecret正确,RAM 用户具备 AliDNS 相关权限(建议最小权限)。
- 确认
IPv6 无法获取:
- 确认设备具有公网 IPv6,或替换/增加
ipv6_endpoints。
- 确认设备具有公网 IPv6,或替换/增加
安全建议
- 使用具备最小权限的 RAM 用户密钥,限制到
alidns相关操作。 - 不要把密钥硬编码在公开仓库;本地私有使用请注意权限控制。