dnspod.py 是基于 DNSPod 服务的动态 DNS 脚本,用于检测 IP 变化并更新至 DNSPod。支持 Linux 设备,包括树莓派(Raspberry Pi)。
raspberrypi-dnspod
dnspod.py 是基于 DNSPod 服务的动态 DNS 脚本,用于检测 IP 变化并更新至 DNSPod。支持 Linux 设备,包括树莓派(Raspberry Pi)。
如果域名没有解析的情况下会根据配置添加解析记录! 如果在局域网可以使用局域网连接,外网就用外网域名连接
Prerequisites
- python
- pyyaml
- requests
python 的模块可通过 pip install
命令安装。如果未安装 pip,请先安装 pip。
Installation
安装 git 客户端,通过本命令获取 dnspod.py
git clone https://github.com/lowboyteam/raspberrypi-dnspod.git
然后到 dnspod 目录下新建 conf.yaml
文件,根据您的 DNSPod 设置,填入以下内容:
token : <your_api_token> domain: <your_domain> loc_sub_domain : <your_local_domain> web_sub_domain : <your_web_domain>
例如
token : 88888,kkkkkkkkkkkkkkkkkkkkk domain: xxxxx.com loc_sub_domain : local web_sub_domain : web
最后设置 crontab 定时任务
*/10 * * * * cd <path_to_dnspod>; python dnspod.py conf.yaml > /dev/null 2>&1 &
Tips
- */10 表示每 10 分钟执行一次 dnspod.py
- 如果未添加过解析记录会自动添加
- loc_sub_domain 解析到局域网IP地址 例如:local.xxxxx.com
- web_sub_domain 解析到外网IP地址 例如:web.xxxxx.com
Code
#!/usr/bin/env python
# -*- coding:utf8 -*-
import os
import sys
import socket
import re
import requests
import platform
import yaml
reload(sys)
sys.setdefaultencoding("utf8")
#日志记录
def logger():
import logging
LOG_FORMAT = "[%(asctime)s]\t[%(levelname)s]\t[%(message)s]"
LOG_FILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), "log.txt")
logging.basicConfig(format=LOG_FORMAT, level=logging.DEBUG, filename=LOG_FILE)
return logging.getLogger(__name__)
def getopts():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('config', help='config file in yaml')
opts = parser.parse_args()
return opts
#获取内网IP地址
def get_loca_ip_address():
sysstr = platform.system()
try:
if(sysstr == "Windows"):
ip = socket.gethostbyname(socket.gethostname())
elif(sysstr == "Linux"):
ip = os.popen("ifconfig|grep 'inet '|grep -v '127.0'|xargs|awk -F '[ :]' '{print $3}'").readline().rstrip()
return ip
except Exception as e:
logger().error("get_loca_ip_address Error: %s", e)
return None
#获取外网IP地址
def get_web_ip_address():
url = "http://city.ip138.com/ip2city.asp"
try:
r = requests.get(url)
ip = re.search('\d+\.\d+\.\d+\.\d+',r.text).group(0)
return ip
except Exception, e:
logger().error("get_web_ip_address Error: %s", e)
return None
class DNSPod(object):
headers = {"User-Agent": "https://github.com/ybhacker/raspberrypi-dnspod/blob/master/dnspod.py"}
def __init__(self, login_token, domain, loc_sub_domain, web_sub_domain):
self.login_token = login_token
self.domain = domain
self.loc_sub_domain = loc_sub_domain
self.web_sub_domain = web_sub_domain
#获取域名ID
def get_domain_id(self,domain):
data = {"login_token": self.login_token,"format": "json"}
url = "https://dnsapi.cn/Domain.List"
try:
r = requests.post(url, data = data, headers = self.headers)
#print r.json()
if int(r.json()["status"]["code"]) == 1:
logger().info("[Domain.List] OK")
dicts = r.json()["domains"]
for i in dicts:
if i["name"] == domain:
return i["id"]
return None
else:
logger().error("get_domain_id response: %s", r.text)
return None
except Exception, e:
logger().error("get_domain_id Error: %s", e)
return None
#获取指定域名解析记录
def get_record_info(self,domain_id,sub_domain):
data = {"login_token": self.login_token,"domain_id": domain_id,"format": "json"}
url = "https://dnsapi.cn/Record.List"
try:
r = requests.post(url, data = data, headers = self.headers)
#print r.json()
if int(r.json()["status"]["code"]) == 1:
logger().info("[Record.List] OK")
dicts = r.json()["records"]
for i in dicts:
if i["name"] == sub_domain:
return i
return None
else:
logger().error("get_record_info response: %s", r.text)
return None
except Exception, e:
logger().error("get_record_info Error: %s", e)
return None
#添加域名解析记录
def create_record(self,domain_id,sub_domain,value):
data = {
"login_token": self.login_token,
"format": "json",
"domain_id": domain_id,
"sub_domain": sub_domain,
"value":value,
"record_type":"A",
"record_line": "默认"
}
url = "https://dnsapi.cn/Record.Create"
try:
r = requests.post(url, data=data, headers=self.headers)
#print r.json()
if int(r.json()["status"]["code"]) == 1:
logger().info("create_record OK")
return r.json()["record"]["id"]
else:
logger().error("create_record response: %s", r.text)
return None
except Exception, e:
logger().error("create_record Error: %s", e)
return None
#解析域名到IP
def DDns(self,domain_id,record_id, sub_domain, value):
data = {
"login_token": self.login_token,
"format": "json",
"domain_id": domain_id,
"record_id": record_id,
"sub_domain": sub_domain,
"record_line": "默认",
"value":value
}
url = "https://dnsapi.cn/Record.Ddns"
try:
r = requests.post(url, data=data, headers=self.headers)
#print r.json()
if int(r.json()["status"]["code"]) == 1:
logger().info("DDns OK")
return True
else:
logger().error("DDns response: %s", r.text)
return False
except Exception, e:
logger().error("DDns Error: %s", e)
return False
#更新域名解析记录,如果没有就自动创建
def update_record_and_create(self,domain_id,sub_domain,value):
try:
record_info = self.get_record_info(domain_id,sub_domain)
#print(record_info)
if record_info:
record_id = record_info["id"]
if self.DDns(domain_id,record_id,sub_domain,value):
#logger().info("IP changed from '%s' to %s ,%s.%s", record_info["value"], value,sub_domain,self.domain)
print(sub_domain+'.'+self.domain)
return True
else:
record_id = self.create_record(domain_id,sub_domain,value)
if record_id:
#logger().info("Creat Record Succes,record_id = %s,ip = %s ,%s.%s", record_info["value"], value,sub_domain,self.domain)
print(sub_domain+'.'+self.domain)
return True
print("ip changed error!")
return False
except Exception, e:
logger().error("update_record_and_create Error: %s", e)
return False
#开始欢快的奔跑
def run(self):
loc_ip = get_loca_ip_address()
web_ip = get_web_ip_address()
domain_id = self.get_domain_id(self.domain)
if domain_id and loc_ip:
if self.update_record_and_create(domain_id,self.loc_sub_domain,loc_ip) == False:
print("loc ip changed error!")
if domain_id and web_ip:
if self.update_record_and_create(domain_id,self.web_sub_domain,web_ip) == False:
print("web ip changed error!")
if __name__ == '__main__':
print("DnsPod Syn IpAddress V1.0")
print(get_loca_ip_address())
print(get_web_ip_address())
opts = getopts()
conf = yaml.load(open(os.path.join(os.path.dirname(os.path.realpath(__file__)),opts.config), "r"))
#conf = yaml.load(open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'conf.yaml'), "r"))
dnspod = DNSPod(login_token=conf["token"],
domain=conf["domain"],
loc_sub_domain=conf["loc_sub_domain"],
web_sub_domain=conf["web_sub_domain"])
dnspod.run()