前言

首先得有一个域名而且是使用阿里云的云解析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

安全建议

  • 使用具备最小权限的 RAM 用户密钥,限制到 alidns 相关操作。
  • 不要把密钥硬编码在公开仓库;本地私有使用请注意权限控制。
最后修改:2025 年 10 月 26 日
如果觉得我的文章对你有用,请随意赞赏