跳至正文
首页 » 使用 Python 实现阿里云 DDNS

使用 Python 实现阿里云 DDNS

一些场景下需要动态修改 DNS,可以帮助我们在动态 IP 的情况下实现搭建服务器,远程访问本地桌面等功能。阿里云官方虽然没有 DDNS,但是开放了 API。使用 DDNS 需要有公网 IP,如果没有可以使用 NPS 实现内网穿透。本文将介绍 使用 Python 实现阿里云 DDNS 。

使用 Python 实现阿里云 DDNS _ 阿里云 Logo

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 -mpython3 -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

其中 UserGroupWorkingDirectory 根据实际状况设置。设置完成后就可以使用 Systemctl 的功能控制刚刚编写的 DDNS 程序了。

5 参考

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注