树莓派自动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)