当前位置: 首页 > 工具软件 > dnspod-python > 使用案例 >

树莓派 raspberrypi-dnspod

张建树
2023-12-01

dnspod.py 是基于 DNSPod 服务的动态 DNS 脚本,用于检测 IP 变化并更新至 DNSPod。支持 Linux 设备,包括树莓派(Raspberry Pi)。

raspberrypi-dnspod

dnspod.py 是基于 DNSPod 服务的动态 DNS 脚本,用于检测 IP 变化并更新至 DNSPod。支持 Linux 设备,包括树莓派(Raspberry Pi)。
如果域名没有解析的情况下会根据配置添加解析记录! 如果在局域网可以使用局域网连接,外网就用外网域名连接

Prerequisites

  1. python
  2. pyyaml
  3. 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

  1. */10 表示每 10 分钟执行一次 dnspod.py
  2. 如果未添加过解析记录会自动添加
  3. loc_sub_domain 解析到局域网IP地址 例如:local.xxxxx.com
  4. 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()
 类似资料: