python配合阿里云域名解析实现DDNS功能

前置工作

  1. 安装阿里模块
    1
    2
    pip install aliyun-python-sdk-core-v3 
    pip install aliyun-python-sdk-alidns==3.0.1
  2. 阿里云获取 AccessKey

实现代码

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
72
73
74
75
76
77
78
79
80
81
82
83
84
import os
import socket
from aliyunsdkcore.client import AcsClient
from aliyunsdkalidns.request.v20150109.DescribeSubDomainRecordsRequest import DescribeSubDomainRecordsRequest
from aliyunsdkalidns.request.v20150109.DeleteSubDomainRecordsRequest import DeleteSubDomainRecordsRequest
from urllib.request import urlopen
import json


class DnsController:
access_key_id = ""
access_key_secret = ""

region = ""
# 时区
record_type = "A"

domain = "langzihan.top"
name_ipv4 = ["p330"]

def __init__(self):
self.client = AcsClient(
self.access_key_id,
self.access_key_secret,
self.region
)

# 添加新的域名解析记录
def add(self, DomainName, RR, Type, Value):
from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest
request = AddDomainRecordRequest()
request.set_accept_format('json')
request.set_DomainName(DomainName)
request.set_RR(RR)
request.set_Type(Type)
request.set_Value(Value)
response = self.client.do_action_with_exception(request)

# 实现ddns
def update_target_dns(self, ip_address):
request = DescribeSubDomainRecordsRequest()
request.set_accept_format('json')
request.set_DomainName(self.domain)

for item in self.name_ipv4:
request.set_SubDomain(item + '.' + self.domain)
response = self.client.do_action_with_exception(request)
domain_list = json.loads(response)

if domain_list['TotalCount'] == 0:
self.add(self.domain, item, self.record_type, ip_address)
else:
if domain_list['DomainRecords']['Record'][0]['Value'].strip() != ip_address.strip():
request = DeleteSubDomainRecordsRequest()
request.set_accept_format('json')
request.set_DomainName(self.domain)
request.set_RR(item)
response = self.client.do_action_with_exception(request)
self.add(self.domain, item, self.record_type, ip_address)


def main():
root_path = '.'
log_path = root_path + '/ip_log.log'
fa = open(log_path, 'a', encoding='utf-8')
cur_ip = socket.gethostbyname(socket.gethostname())
if not os.path.isfile(log_path) and fa.read().strip() == '':
fa.write(cur_ip + '##')
DnsController().update_target_dns(cur_ip)
fa.close()
return 0

with open(log_path, 'r', encoding='utf-8') as fr:
old_ip = fr.read().strip('##').split('##')[-1]
if old_ip != cur_ip or old_ip is None:
# print('old:', old_ip)
fa.write(cur_ip + '##')
DnsController().update_target_dns(cur_ip)

fa.close()


if __name__ == '__main__':
main()