树莓派自动DDNS更新(DNSPOD)
手头上的树莓派4通过WIFI连接网络,因为是DHCP分配一个公网IP,所以想直接解析到固定域名上,避免每次链接的时候都要手动去看分配的IP。 此处使用的是dnspod家的服务,可以实现秒级解析。程序是python3写的,使用crontab的@reboot
功能(如下,注意path
路径)实现开机启动后获取IP并自动上报。为了方便查看和记录,也添加了将IP推送到telegram的功能(自建telegram机器人的教程,点击这里查看)。
@reboot /usr/bin/python3 /path/AutoDNS.py
Python3脚本如下,需要申请dnspod的login_token才能使用api,步骤参考官方教程。注意!此token只会出现一次,一定要复制下来保存好,并确保不会泄露。假设已经在dnspod里面解析过了raspi.domain.com,并且通过curl 'https://dnsapi.cn/Domain.List' -d 'login_token=<login_token>&format=json'
获取了domain_id,通过curl 'https://dnsapi.cn/Record.List' -d 'login_token=<login_token>&format=json&domain_id=<domain_id>'
获取了raspi.domain.com的domain_id。
import requests import netifaces import telebot import time import sys # 等待10秒钟以便系统有足够的时间从路由器获取ip地址 time.sleep(10) # 根据dnspod的api标准,需要添加User-Agent才能保证不会被封号,格式为:程序名称/版本号 (邮件地址) headers = {'User-Agent': 'RasPi Auto DDNS/1.0.0 (email@domain.com)'} # 使用netifaces获取wifi被分配的IP,如果是网线则wlan0变成eth0,如果拿不到IP则退出程序 try: wlan_ip = netifaces.ifaddresses('wlan0')[2][0]['addr'] except: sys.exit(0) # 从dnspod里得到上次的IP,需要已经解析过次级域名,以raspi.domain.com为例。 url_list = 'https://dnsapi.cn/Record.List' data_list = { 'login_token': '123456,4aacc7629e9c7gh58b253cby97f43cdc', 'format': 'json', 'domain_id': '12345678', 'sub_domain': 'raspi', 'record_type': 'A' } data_dns = requests.post(url=url_list, data=data_list, headers=headers).json() list_ip = data_dns["records"][0]["value"] # 对比此前的IP和现在获取的IP一致,不一致则更改dnspod里面的记录 if wlan_ip != list_ip: url_modify = 'https://dnsapi.cn/Record.Modify' data_modify = { 'login_token': '123456,4aacc7629e9c7gh58b253cby97f43cdc', 'format': 'json', 'domain_id': '12345678', 'record_id': '123456789', 'sub_domain': 'raspi', 'value': wlan_ip, 'record_type': 'A', 'record_line': '\u9ED8\u8BA4' } response_modify = requests.post(url=url_modify, data=data_modify, headers=headers) # 将信息推送到telegram上以便查看记录。如果不需要,可以从此处删除剩下的所有代码。 TOKEN = '1689581149:AAGYVVjEHsaNjsnT8eQpWyshwr2o4PqU7u8' tb = telebot.TeleBot(TOKEN) text = "The DNS ip is: " + list_ip + " The IP of RasPi is: " + wlan_ip tb.send_message(387980691, text) else: # 将信息推送到telegram上以便查看记录。 TOKEN = '1689581149:AAGYVVjEHsaNjsnT8eQpWyshwr2o4PqU7u8' tb = telebot.TeleBot(TOKEN) text = "The IP of RasPi does not change: " + wlan_ip tb.send_message(387980691, text)