0. 简单概述
在家里放一个 NAS 服务器,但是宽带的 IP 地址经常改变,一般路由器自带的花生壳域名解析可以解决,如果路由器没有类似功能或者想使用自己的域名,可以尝试使用 DNSPOD API 来实现域名动态解析。
1. 添加记录 在 dnspod 添加域名后并添加一个记录用来解析宽带的 IP 地址,如添加一个记录h
2. 获取信息 1) 域名信息 domain_id
接口文档:https://www.dnspod.cn/docs/domains.html#domain-info
def domain_info(domain):
url = "https://dnsapi.cn/Domain.Info"
data = {
"login_email": LOGIN_EMAIL,
"login_password": LOGIN_PASSWORD,
"format": FORMAT,
"domain": domain
}
r = requests.post(url, data=data, timeout=5)
return r.json()["domain"]
def domain_id(domain):
info = domain_info(domain)
return info["id"]
# 获取 domain_id
print domain_id("greak.net")
2) 记录信息 record_id
、record_line
和value
接口文档:https://www.dnspod.cn/docs/records.html#record-list
def record_info(domain, sub_domain):
url = "https://dnsapi.cn/Record.List"
data = {
"login_email": LOGIN_EMAIL,
"login_password": LOGIN_PASSWORD,
"format": FORMAT,
"domain": domain,
"sub_domain": sub_domain
}
r = requests.post(url, data=data, timeout=5)
return r.json()["records"][0]
def record_data(domain, sub_domain):
info = record_info(domain, sub_domain)
return info["id"], info["line"], info["value"]
# 获取 record_id, record_line, value
rid, line, oldip = record_data("greak.net", "h")
3) 获取最新 IP 地址 接口:http://greak.net/ip
def get_newip():
url = "http://greak.net/ip"
r = requests.get(url, timeout=5)
return r.content.strip()
# 获取 IP 地址
print get_newip()
3. 修改记录 接口文档:https://www.dnspod.cn/docs/records.html#dns
def record_update(domain, sub_domain):
newip = get_newip()
rid, line, oldip = record_data(domain, sub_domain)
if newip == oldip: # 比较新 IP 和现有记录是否一致,如果一致则不需要更新
return "not change"
url = "https://dnsapi.cn/Record.Ddns"
data = {
"login_email": LOGIN_EMAIL,
"login_password": LOGIN_PASSWORD,
"format": FORMAT,
"domain_id": domain_id(domain),
"record_id": rid,
"sub_domain": sub_domain,
"record_line": line,
"value": newip
}
r = requests.post(url, data=data, timeout=5)
return r.json()
# 修改记录
print record_update("greak.net", "h")
4. 定期执行 完整 python 脚本dns.py
#!/usr/bin/env python2
import sys
import os
import json
import time
import requests
LOGIN_EMAIL = "xxxxxx@example.com"
LOGIN_PASSWORD = "xxxxxx"
FORMAT = "json"
def domain_info(domain):
url = "https://dnsapi.cn/Domain.Info"
data = {
"login_email": LOGIN_EMAIL,
"login_password": LOGIN_PASSWORD,
"format": FORMAT,
"domain": domain
}
r = requests.post(url, data=data, timeout=5)
return r.json()["domain"]
def domain_id(domain):
info = domain_info(domain)
return info["id"]
def record_info(domain, sub_domain):
url = "https://dnsapi.cn/Record.List"
data = {
"login_email": LOGIN_EMAIL,
"login_password": LOGIN_PASSWORD,
"format": FORMAT,
"domain": domain,
"sub_domain": sub_domain
}
r = requests.post(url, data=data, timeout=5)
return r.json()["records"][0]
def record_id(domain, sub_domain):
info = record_info(domain, sub_domain)
return info["id"]
def record_line(domain, sub_domain):
info = record_info(domain, sub_domain)
return info["line"]
def record_value(domain, sub_domain):
info = record_info(domain, sub_domain)
return info["value"]
def record_data(domain, sub_domain):
info = record_info(domain, sub_domain)
return info["id"], info["line"], info["value"]
def get_newip():
url = "http://greak.net/ip"
r = requests.get(url, timeout=5)
return r.content.strip()
def record_update(domain, sub_domain):
newip = get_newip()
rid, line, oldip = record_data(domain, sub_domain)
if newip == oldip:
return "not change"
url = "https://dnsapi.cn/Record.Ddns"
data = {
"login_email": LOGIN_EMAIL,
"login_password": LOGIN_PASSWORD,
"format": FORMAT,
"domain_id": domain_id(domain),
"record_id": rid,
"sub_domain": sub_domain,
"record_line": line,
"value": newip
}
r = requests.post(url, data=data, timeout=5)
return r.json()
if __name__ == "__main__":
print time.strftime("%Y/%m/%d %H:%M:%S")
print record_update("greak.net", "h")
添加 cron 计划任务执行
#dns record update
*/1 * * * * root /usr/bin/python /home/debian/dns.py >>/home/debian/dns.log 2>&1
日志输出
2016/05/01 18:17:02
{u'status': {u'message': u'Action completed successful', u'code': u'1', u'created_at': u'2016-05-01 18:17:03'}, u'record': {u'id': 178422498, u'value': u'180.172.158.222', u'name': u'h'}}
# 更新成功
2016/05/01 18:18:02
not change
# 没有变化,无需改变
检查是否生效
$ curl greak.net/ip
180.172.158.222
$ dig h.greak.net | grep "^h.greak.net" | awk '{print $NF}'
180.172.158.222
如果输出的 IP 地址一样就表示生效了,由于存在 dns 缓存, dns 生效需要大概几分钟
注: dnspod 的 api 调用有次数限制,不要频繁调用
原文地址:http://greak.net/2016/05/01/shi-yong-dnspod-apishi-xian-yu-ming-dong-tai-jie-xi/