使用python实现阿里云动态域名解析DDNS

前言

前置条件

1、域名是在阿里云购买的
2、地址必须是公网地址,不然加了解析也没有用

简介

通过阿里云提供的SDK,然后自己编写程序新增或者修改域名的解析,达到动态解析域名的目的;主要应用于pppoe拨号的环境,比如家里设置了服务器,但是外网地址经常变化的场景;再比如公司的pppoe网关,需要建立vpn的场景。

安装阿里云SDK

需要安装两个SDK库,一个是阿里云核心SDK库,一个是阿里云域名SDK库;
阿里云核心SDK库:pip install aliyun-python-sdk-core
阿里云域名SDK库:pip install aliyun-python-sdk-domain
阿里云SDK帮助

关于调试

阿里云提供一个在线调试,支持在线调试好之后,再复制回来本地即可。使用调试平台需要先登录。在线调试平台
API的模块名称都可以通过帮助文档查询

设计思路

一、获取阿里云的accessKeyId和accessSecret
二、获取外网ip
三、判断外网ip是否与之前一致
四、外网ip不一致时,新增或者更新域名解析记录

详细步骤

获取accessKeyId和accessSecret

可以在阿里云控制台个人中心直接获取,但是一般建议使用RAM角色来进行权限控制,这样这个accessKey和accessSecret就只能操作域名,不能操作其他的资源,相对会比较安全。关于RAM快速入门,请点击链接
获取到accessKeyId和accessSecret之后,填入相对应的函数中即可:

from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from hwx_function import *
import os
import time

client = AcsClient('<accessKeyId>', '<accessSecret>', 'cn-hangzhou')

获取外网IP

通过网络上面的外网ip的API获取,可以使用多个,我这里只是列举了一个,具体代码如下:

def get_internet_ip():
    with urllib.request.urlopen('http://www.3322.org/dyndns/getip') as response:
        html = response.read()
        ip = str(html, encoding='utf-8').replace("\n", "")
    return ip

判断IP是否一致

因为阿里云不允许修改相同的解析,所以需要比对IP是否一致;因为把上一次解析的IP写入文件,所以只需要读取出来,跟本次得到的外网IP相比较,一致则不修改解析记录,不一致则修改解析记录。关于域名解析操作的代码,下面会有解释。

    with open("./ip", 'r') as f:
        old_ip = f.read()
    if ip == old_ip:
        print("noupdate"+"\nnew_ip:"+ip+"\nold_ip:"+old_ip)
    else:
        #print("update"+"\nnew_ip:"+ip+"\nold_ip:"+old_ip)
        wirte_to_file("./ip",ip)
        des_relsult = Describe_SubDomain_Records(client,"A","www.huangwx.cn")
        #判断子域名解析记录查询结果,TotalCount为0表示不存在这个子域名的解析记录,需要新增一个
        if des_relsult["TotalCount"] == 0:
            add_relsult = add_record(client,"5","600","A",ip,"www","huangwx.cn")
            record_id = add_relsult["RecordId"]
            print("域名解析新增成功!")
        #判断子域名解析记录查询结果,TotalCount为1表示存在这个子域名的解析记录,需要更新解析记录,更新记录需要用到RecordId,这个在查询函数中有返回des_relsult["DomainRecords"]["Record"][0]["RecordId"]
        elif des_relsult["TotalCount"] == 1:
            record_id = des_relsult["DomainRecords"]["Record"][0]["RecordId"]
            update_record(client,"5","600","A",ip,"sz",record_id)
            print("域名解析更新成功!")
        else:
            record_id = 0
            print("存在两个子域名解析记录值,请核查删除后再操作!")
        path = './RecordId'
        wirte_to_file(path,record_id)

域名解析记录操作

域名解析记录不存在时,就新增解析记录,如果已经存在,则修改解析记录;所以这里还需要用到查询子域名解析记录的API;

子域名解析记录查询

Describe_SubDomain_Records(client,"A","sz.huangwx.cn")
这个函数会返回一大堆东西,但是目前我们需要使用的就两个,一个是解析记录的数量,一个就是RecordId,RecordId修改域名解析时需要用到;

#这个是函数
def Describe_SubDomain_Records(client,record_type,subdomain):
    request = DescribeSubDomainRecordsRequest()
    request.set_accept_format('json')

    request.set_Type(record_type)
    request.set_SubDomain(subdomain)

    response = client.do_action_with_exception(request)
    response = str(response, encoding='utf-8')
    relsult = json.loads(response)
    return relsult
    
#以下是函数调用以及说明
des_relsult = Describe_SubDomain_Records(client,"A","www.huangwx.cn")
des_relsult["TotalCount"]:解析记录的数量,0表示解析记录不存在,1表示有一条解析记录
des_relsult["DomainRecords"]["Record"][0]["RecordId"]:当des_relsult["TotalCount"]为1时,会返回这个RecordId,后续的修改域名解析记录中需要用到

新增域名解析记录

如果域名解析记录不存在时,就需要新增域名解析记录,新增域名解析记录比较简单,直接填写参数即可

def add_record(client,priority,ttl,record_type,value,rr,domainname):
    request = AddDomainRecordRequest()
    request.set_accept_format('json')

    request.set_Priority(priority)
    request.set_TTL(ttl)
    request.set_Value(value)
    request.set_Type(record_type)
    request.set_RR(rr)
    request.set_DomainName(domainname)

    response = client.do_action_with_exception(request)
    response = str(response, encoding='utf-8')
    relsult = json.loads(response)
    return relsult

#函数调用
add_relsult = add_record(client,"5","600","A",ip,"www","huangwx.cn")
record_id = add_relsult["RecordId"]#同样会返回一个RecordId,修改的时候也可以直接调用

更新域名解析记录

如果域名解析记录已存在,则不能使用新增,而是更新域名解析记录。更新的时候需要用到RecordId,这个一般查询的时候就会有返回,直接使用即可

def update_record(client,priority,ttl,record_type,value,rr,record_id):
    request = UpdateDomainRecordRequest()
    request.set_accept_format('json')

    request.set_Priority(priority)
    request.set_TTL(ttl)
    request.set_Value(value)
    request.set_Type(record_type)
    request.set_RR(rr)
    request.set_RecordId(record_id)

    response = client.do_action_with_exception(request)
    response = str(response, encoding='utf-8')
    return response

#函数调用
record_id = des_relsult["DomainRecords"]["Record"][0]["RecordId"]
update_record(client,"5","600","A",ip,"sz",record_id)

再加个循环或者定时任务即可定时更新域名解析记录了

总结

1、阿里云函数的使用依赖于阿里云的SDK库,所以这个一定要安装好
2、新增解析记录的时候,可以把RecordId存储在本地文件,下次直接判断文件是否存在即可,不用每次都调用查询API

阿里云时间

1.2000代金券,长期有效:2000
2.高性能拼着买,2折起:高性能ECS
3.个人博客:薇小站

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269