
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 = "[email protected]" 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(domai, 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/
1 boboliu 2016-05-01 19:06:47 +08:00 。。。这种文章发来 V2 , B 格略不足的样子(以及论大内网的重要性) |
3 clanned 2016-05-01 20:01:06 +08:00 via Android 这里有 shell 脚本的,可以在 ddwrt 和 openwrt 里跑。 https://github.com/xdtianyu/scripts/tree/master/ddns |
4 Tink PRO 我觉得一句 curl 就搞定了啊 |
5 am241 016-05-01 20:13:37 +08:00 |
6 LazyZhu 2016-05-01 20:20:13 +08:00 |
7 ETiV 2016-05-01 20:22:00 +08:00 via iPhone dnspod 有 token 机制了,设置这种不需要密码了 |
8 tSQghkfhTtQt9mtd 2016-05-01 21:19:52 +08:00 via Android 对于 @CloudXNS 来说只需要 #!/bin/sh API_KEY="" SECRET_KEY="" DATE=$(date) URL_U="https://www.cloudxns.net/api2/ddns" PARAM_BODY="{\"domain\":\"ddns.example.com\"}" HMAC_U=$(echo -n "$API_KEY$URL_U$PARAM_BODY$DATE$SECRET_KEY"|md5sum|cut -d" " -f1) RESULT=$(/opt/bin/curl -k -s $URL_U -X POST -d $PARAM_BODY -H "API-KEY: $API_KEY" -H "API-REQUEST-DATE: $DATE" -H "API-HMAC: $HMAC_U" -H 'Content-Type: application/json') echo $RESULT if [ $(echo -n "$RESULT"|grep -o "message\":\"success\""|wc -l) = 1 ];then echo "$(date) -- Update success" else echo "$(date) -- Update failed" fi |
9 qile1 2016-05-01 22:12:25 +08:00 via Android 这个限制太多,一直没时间弄在自己服务器上基本时时更新的。 |
11 realpg PRO 我觉得 dnspod 这种弱爆了…… 提供一个动态 IP 独立 API 也就是几行代码的事儿 当年 3322 那个接口多好 http://username:[email protected]/update?domain=xxxx.xxxx.net&ip=119.119.119.119 哪怕一个 wget 都能更新 IP |