利用CloudXNS的api接口, 来实现动态域名解析, 从而适应IP不固定的情况

安装依赖

centos 下面请执行

yum -y install python-setuptools && easy_install requests

Debian / Ubuntu 下面请执行

sudo apt-get install -y python-pip && sudo pip install requests

下载脚本

wget https://raw.githubusercontent.com/liyuans/CloudXNS-DDNS/master/run.py

修改其中的 api 和自己要解析的域名

1
2
3
api_key ="XXXXXXXXXXXXXXXXXXXX"
api_secret = "XXXXXXXXX"
DOMAIN = "www.liyuans.com"

执行脚本

/usr/bin/env python /root/run.py >/dev/null 2>&1

定期任务

添加 crond 任务,执行脚本每分钟检查本地 ip 并更新到 cloudxns
关于 crontab 如何使用请百度
*/1 * * * * /usr/bin/env python /root/run.py >/dev/null 2>&1

python代码

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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: p0we7
# Email : i@iu.vc

def handle_import_error():
print '\n' + "Import Error:"
print 'Please install the required 3rd-party modules ' + '\033[4;95m' + 'requests' + '\033[0m' + '\n'
import sys
sys.exit()

try:
import requests
except ImportError:
handle_import_error()
import json, time, hashlib, re, syslog
import socket, fcntl, struct
from time import gmtime

method = "web" # web or iface , but interface only support for unix-like
interface = "pppoe0" # if method set iface , then set interface name
# log = "/var/log/messages" # log file

api_key ="XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
api_secret = "XXXXXXXXXX"
DOMAIN = "zuik.ren"

def get_ip(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', ifname[:15]))[20:24])

class XNS(object):
def __init__(self):
super(XNS, self).__init__()

def domainSplit(self, location):
if location == "pre":
return re.search('^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}', DOMAIN).group()
if location == "suf":
return re.search('(?<=\.)([a-zA-Z0-9][-a-zA-Z0-9]{0,62})\.([a-zA-Z0-9][-a-zA-Z0-9]{0,62})+', DOMAIN).group()

def headers(self, method, url, data=None):
request_time = time.strftime("%a, %d %b %Y %H:%M:%S GMT", gmtime())
if method == "GET":
hmac = hashlib.md5(api_key + url + request_time + api_secret).hexdigest()
if method == "PUT":
hmac = hashlib.md5(api_key + url + str(json.dumps(data)) + request_time + api_secret).hexdigest()
headers = {
'API-KEY': api_key,
'API-REQUEST-DATE': request_time,
'API-HMAC': hmac,
'API-FORMAT': 'json'
}
return headers

def getDomainId(self):
url = api_url + "domain"
r = requests.get(url, headers=self.headers("GET", url))
domain = r.json()
for data in domain['data']:
if self.domainSplit("suf") in data['domain']:
return data['id']

def getRecordId(self):
url = api_url + "record/" + self.getDomainId()
r = requests.get(url, headers=self.headers("GET", url))
domain = r.json()
for data in domain['data']:
if self.domainSplit("pre") in data['host']:
return data['record_id']

def putRecord(self):
url = api_url + "record/" + self.getRecordId()
request_data = {
"domain_id": self.getDomainId(),
"host": self.domainSplit("pre"),
"value": get_ip('wlan0'),
"type": "A",
"ttl": 600,
"line_id": 1
}
r = requests.put(url, data=json.dumps(request_data), headers=self.headers("PUT", url, request_data))
return r.json()

if __name__ == '__main__':
requests.packages.urllib3.disable_warnings() # ignore urlib3 warnings
api_url = "https://www.cloudxns.net/api2/"
d = XNS()
result = d.putRecord()
syslog.openlog("xnsCloud", syslog.LOG_PID)
response = result
response_data = response[u'data']
syslog.syslog("Update_Status : " + response[u'message'])
syslog.syslog("Update_IP : " + response_data[u'value'])
syslog.syslog("Domain_name : " + response_data[u'domain_name'])