通过阿里云实现DDNS解析

1、准备工作

  • Python 2.7
  • curl
  • Access Key ID
  • Access Key Secret
  • 账号ID
  • windows环境需要iconv

1.1、python安装

由于阿里云python SDK使用Python2.7编写。所以环境请准备Python2.7.X,使用Python3.0将会报错

1.1.1、Windows

至官网下载Python2.7.x版本下载安装即可。

1.2、阿里云SDK安装

1
pip install aliyun-python-sdk-alidns

1.3、Windows环境下curl安装

curl官网下载,windows版本下载地址

1.3.1、解决Windows环境下curl乱码的问题

如题,在Windows环境下控制台输出是乱码,解决方法是下载iconv下载地址

接下来,需要安装并设置环境变量,最后输入命令

1
cur -s ip.cn | iconv -f utf-8 -t gbk

2、关键信息

通过脚本更新DNS记录需要向个关键的信息,如下:

  1. 一级域名(你的域名)
  2. 主机记录(二级域名)
  3. 记录类型 (你的本地IP地址)
  4. 记录ID (这个解析记录的ID)
  5. 记录TTL (记录有效生存时间)

2.1、完整脚本

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# -*- coding: UTF-8 -*-

import json
import os
import re
import sys
from datetime import datetime

from aliyunsdkalidns.request.v20150109 import UpdateDomainRecordRequest, DescribeDomainRecordsRequest, \
DescribeDomainRecordInfoRequest
from aliyunsdkcore import client

#请填写你的Access Key ID,阿里云控制台获取
access_key_id = "XXXXXXXXXXXX"

#请填写你的Access Key Secret,阿里云控制台获取
access_Key_secret = "XXXXXXXXXXXX"

#请填写你的账号ID,阿里云控制台获取
account_id = "XXXXXXXX"

#如果选择yes,则运行程序后仅现实域名信息,并不会更新记录,用于获取解析记录ID。
#如果选择NO,则运行程序后不显示域名信息,仅更新记录
i_dont_know_record_id = 'no'

#请填写你的一级域名
rc_domain = 'XXXXXX.XXXXX'

#请填写你的主机记录
rc_rr = 'XXXXXXX'

#请填写你的记录类型,DDNS请填写A,表示A记录
rc_type = 'A'

#请填写主机记录ID,需要通过解析记录来获取,也就是check_records返回值
rc_record_id = 'XXXXXXXXXX'

#请填写解析有效生存时间TTL,单位:秒。
rc_ttl = '600'

#请填写返还内容格式,json,xml
rc_format = 'json'


def my_ip():
get_ip_method = os.popen('curl -s ip.cn | iconv -f utf-8 -t gbk')
get_ip_responses = get_ip_method.readlines()[0]
get_ip_pattern = re.compile(r'\d+\.\d+\.\d+\.\d+')
get_ip_value = get_ip_pattern.findall(get_ip_responses)[0]
return get_ip_value


def check_records(dns_domain):
clt = client.AcsClient(access_key_id, access_Key_secret, 'cn-hangzhou')
request = DescribeDomainRecordsRequest.DescribeDomainRecordsRequest()
request.set_DomainName(dns_domain)
request.set_accept_format(rc_format)
result = clt.do_action(request)
return result


def old_ip():
clt = client.AcsClient(access_key_id, access_Key_secret, 'cn-hangzhou')
request = DescribeDomainRecordInfoRequest.DescribeDomainRecordInfoRequest()
request.set_RecordId(rc_record_id)
request.set_accept_format(rc_format)
result = clt.do_action(request)
result = json.JSONDecoder().decode(result)
result = result['Value']
return result


def update_dns(dns_rr, dns_type, dns_value, dns_record_id, dns_ttl, dns_format):
clt = client.AcsClient(access_key_id, access_Key_secret, 'cn-hangzhou')
request = UpdateDomainRecordRequest.UpdateDomainRecordRequest()
request.set_RR(dns_rr)
request.set_Type(dns_type)
request.set_Value(dns_value)
request.set_RecordId(dns_record_id)
request.set_TTL(dns_ttl)
request.set_accept_format(dns_format)
result = clt.do_action(request)
return result

def write_to_file():
time_now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
current_script_path = sys.path[7]
print current_script_path
log_file = current_script_path + '/' + 'aliyun_ddns_log.txt'
write = open(log_file, 'a')
write.write(time_now + ' ' + str(rc_value_old) + '------>' + str(rc_value) + '\n' )
write.close()
return


if i_dont_know_record_id == 'yes':
print check_records(rc_domain)
elif i_dont_know_record_id == 'no':
rc_value = my_ip()
rc_value_old = old_ip()
if rc_value_old == rc_value:
print 'The specified value of parameter Value is the same as old'
else:
print update_dns(rc_rr, rc_type, rc_value, rc_record_id, rc_ttl, rc_format)
write_to_file()