什么是 DDNS?

DDNS(Dynamic Domain Name Server,动态域名服务)是将用户的动态IP地址映射到一个固定的域名解析服务上,用户每次连接网络的时候客户端程序就会通过信息传递把该主机的动态IP地址传送给位于服务商主机上的服务器程序,服务器程序负责提供DNS服务并实现动态域名解析

DDNS的使用场景分析

在中国,面向社会的服务器是需要备案的,而备案的时候是需要使用一个固定的公网ip备案的。因此很多人想要使用DDNS实现网站搭建的小伙伴就要失望了(说的就是我)。

但是这里面有一个细节,面向社会提供服务的需要备案,那么不提供服务且有意阻止社会人员访问服务器的应用场景,如个人计算服务器、私人云盘(如群辉的家庭云服务),就不需要备案了。

用python实现DDNS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from aliyunsdkcore.client import AcsClient
from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest
import json
import subprocess
import re

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


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


# 获取recordid
def get_recordid(client):
request = DescribeDomainRecordsRequest()
request.set_accept_format('json')
request.set_DomainName("discover304.top") #\TODO 传你的域名
response = client.do_action_with_exception(request)
response = str(response, encoding='utf-8')
result = json.loads(response)
recordid = result["DomainRecords"]["Record"][0]["RecordId"]
return 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


# 函数调用
def run_result(client, priority, ttl, record_type, value, rr, record_id):
if get_local_ip() == get_internet_ip():
print("解析地址未发生变化,不修改!")
pass
else:
result = update_record(client, priority, ttl, record_type, value, rr, record_id)
result = json.loads(result)
print("已更新解析地址,新的RecordId是:%s" % result["RecordId"])


if __name__ == '__main__':
# \TODO 这儿传你的accessKeyId、accessSecret和区域ID(region_id)
client = AcsClient('xxxx', 'xxxx', 'cn-beijing')
record_id = get_recordid(client)
ip = get_local_ip()
run_result(client, "5", "600", "AAAA", ip, "@", record_id)

参考

  • https://zhidao.baidu.com/question/630978248482699204.html
  • https://www.cnblogs.com/fanzhiping/p/13062142.html