python+阿里云实现动态域名解析(DDNS)

前言

最近发现家里的移动宽带能够获取公网ipv6地址了,刚好前段时间配了台win10的机子做家用NAS(只能局域网进行文件共享),现在就想利用这个公网ipv6地址实现外网访问,但是电脑每次重启获取的ipv6地址都是变化的,所以需要实现动态域名解析(DDNS)功能。

具体情况

1、可以获取公网ipv6地址,但是ipv4的地址是内网的;

2、在阿里云买了一个1块钱1年的域名,刚可以利用起来;

3、电脑获取的ipv6地址在每次重启后都会自动变化,直接通过域名解析每次重启后域名访问就不行了。

前期准备

1、一个域名(我直接买的阿里的域名,1块钱1年,需要备案)
2、给域名添加解析记录

3、安装阿里云pythonSDK:

阿里云核心SDK库:pip install aliyun-python-sdk-core

阿里云域名SDK库:pip install aliyun-python-sdk-domain(我在看其他博客的时候有写到这个,但是我没找到怎么使用,所以没有用这个),用的下面这个

阿里云域名库:aliyunsdkalidns.zip(直接pip我没有安装成功,需要的可以百度云下载:https://pan.baidu.com/s/1i9-7xpNzFQGdXiTtjqCXLQ,提取码:pr76)

实现思路

1、获取阿里云的accessKeyId和accessSecret
2、获取当前电脑的公网ipv6地址和域名解析的ipv6地址
3、判断当前点奥的公网ipv6地址和域名解析的ipv6地址是否一直
4、ip不一致时,更新域名解析记录

5、添加win10系统的定时任务执行

实现步骤

获取accessKeyId和accessSecret

这个可以直接在阿里云控制台的个人中心获取,不清楚的可以直接百度

获取本机ipv6地址

1 # 获取本机临时IPv6地址
2 def get_local_ip():
3     child = subprocess.Popen("ipconfig", shell=True, stdout=subprocess.PIPE)
4     out = child.communicate()  # 保存ipconfig中的所有信息
5     ipv6_pattern = '(([a-f0-9]{1,4}:){7}[a-f0-9]{1,4})'
6     m = re.findall(ipv6_pattern, str(out))
7     address = m[1][0]
8     return address

获取域名当前解析ip(利用"nslookup+域名"的方式)

1 # 获取当前域名对应的ip地址
2 def get_internet_ip():
3     child = subprocess.Popen("nslookup nideyuming", shell=True, stdout=subprocess.PIPE)
4     out = child.communicate()  # 保存nslookup获取的所有信息
5     ipv6_pattern = '(([a-f0-9]{1,4}:){7}[a-f0-9]{1,4})'
6     m = re.findall(ipv6_pattern, str(out))
7     address = m[0][0]  # 拿到ipv6地址
8     return address

利用UpdateDomainRecordRequest这个action执行域名解析更新操作,但是在执行这个action的时候需要传RecordId参数,需要先通过DescribeDomainRecordsRequest这个action获得RecordId。

获取RecordId

 1 # 获取recordid
 2 def get_recordid(client):
 3     request = DescribeDomainRecordsRequest()
 4     request.set_accept_format('json')
 5     request.set_DomainName("nideyuming")#这个地方传你的域名信息
 6     response = client.do_action_with_exception(request)
 7     response = str(response, encoding='utf-8')
 8     result = json.loads(response)
 9     recordid = result["DomainRecords"]["Record"][0]["RecordId"]
10     return recordid

更新域名解析

 1 # 更新域名解析
 2 def update_record(client, priority, ttl, record_type, value, rr, record_id):
 3     request = UpdateDomainRecordRequest()
 4     request.set_accept_format('json')
 5     request.set_Priority(priority)
 6     request.set_TTL(ttl)
 7     request.set_Value(value)
 8     request.set_Type(record_type)
 9     request.set_RR(rr)
10     request.set_RecordId(record_id)
11     response = client.do_action_with_exception(request)
12     response = str(response, encoding='utf-8')
13     return response

判断上面2步获取的ip是否相同,如果相同就不需要更新域名解析ip了,如果不同就执行更新操作

执行

 1 # 函数调用
 2 def run_result(client, priority, ttl, record_type, value, rr, record_id):
 3     if get_local_ip() == get_internet_ip():
 4         print("解析地址未发生变化,不修改!")
 5         pass
 6     else:
 7         result = update_record(client, priority, ttl, record_type, value, rr, record_id)
 8         result = json.loads(result)
 9         print("新的RecordId是:%s" % result["RecordId"])
10 
11 
12 if __name__ == '__main__':
13     client = AcsClient('youraccessKeyId', 'youraccessSecret', 'cn-chengdu')
14     record_id = get_recordid(client)
15     ip = get_local_ip()
16     run_result(client, "5", "600", "AAAA", ip, "@", record_id)

为了简单,我把所有代码放到一个.py文件里了,整体代码如下:

完整代码

 1 #!/usr/bin/env python
 2 # coding=utf-8
 3 
 4 from aliyunsdkcore.client import AcsClient
 5 from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequest
 6 from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest
 7 import json
 8 import subprocess
 9 import re
10 
11 
12 # 获取当前域名对应的ip地址
13 def get_internet_ip():
14     child = subprocess.Popen("nslookup nideyuming", shell=True, stdout=subprocess.PIPE)
15     out = child.communicate()  # 保存nslookup获取的所有信息
16     ipv6_pattern = '(([a-f0-9]{1,4}:){7}[a-f0-9]{1,4})'
17     m = re.findall(ipv6_pattern, str(out))
18     address = m[0][0]  # 拿到ipv6地址
19     return address
20 
21 
22 # 获取本机临时IPv6地址
23 def get_local_ip():
24     child = subprocess.Popen("ipconfig", shell=True, stdout=subprocess.PIPE)
25     out = child.communicate()  # 保存ipconfig中的所有信息
26     ipv6_pattern = '(([a-f0-9]{1,4}:){7}[a-f0-9]{1,4})'
27     m = re.findall(ipv6_pattern, str(out))
28     address = m[1][0]
29     return address
30 
31 
32 # 获取recordid
33 def get_recordid(client):
34     request = DescribeDomainRecordsRequest()
35     request.set_accept_format('json')
36     request.set_DomainName("nideyuming")#传你的域名
37     response = client.do_action_with_exception(request)
38     response = str(response, encoding='utf-8')
39     result = json.loads(response)
40     recordid = result["DomainRecords"]["Record"][0]["RecordId"]
41     return recordid
42 
43 
44 # 更新域名解析
45 def update_record(client, priority, ttl, record_type, value, rr, record_id):
46     request = UpdateDomainRecordRequest()
47     request.set_accept_format('json')
48     request.set_Priority(priority)
49     request.set_TTL(ttl)
50     request.set_Value(value)
51     request.set_Type(record_type)
52     request.set_RR(rr)
53     request.set_RecordId(record_id)
54     response = client.do_action_with_exception(request)
55     response = str(response, encoding='utf-8')
56     return response
57 
58 
59 # 函数调用
60 def run_result(client, priority, ttl, record_type, value, rr, record_id):
61     if get_local_ip() == get_internet_ip():
62         print("解析地址未发生变化,不修改!")
63         pass
64     else:
65         result = update_record(client, priority, ttl, record_type, value, rr, record_id)
66         result = json.loads(result)
67         print("已更新解析地址,新的RecordId是:%s" % result["RecordId"])
68 
69 
70 if __name__ == '__main__':
71     client = AcsClient('youraccessKeyId', 'youraccessSecret', 'cn-chengdu')#这儿传你的accessKeyId、accessSecret和区域ID(region_id)
72     record_id = get_recordid(client)
73     ip = get_local_ip()
74     run_result(client, "5", "600", "AAAA", ip, "@", record_id)

以上,执行该.py文件,就会自动更新当前电脑的公网ipv6地址到域名解析

电脑定时执行.py脚本

我配置了1个开机执行的定时任务,一个每天早上9点执行的定时任务。这块儿的资料网上很多,这儿写下2个要注意的点。

1、创建了一个开机自动执行的任务,这儿我最开始选择的只在用户登录是运行,重启电脑后发行没有自动执行,改成不管用户是否登录都有运行就ok了

python+阿里云实现动态域名解析(DDNS)

 

 2、操作里面直接填写python.exe和要执行的.py脚本的据对路径就ok了

python+阿里云实现动态域名解析(DDNS)

 

 以上,重启下电脑,自动执行脚本成功,登录阿里云查看域名解析ip也已经变成本机最新获取的ipv6地址了。

 

 

 

 

 

 

 



 

上一篇:动态IP下群晖搭建DDNS服务


下一篇:通过阿里云实现DDNS解析 python