DDNS全名:Dynamic Domain Name Server(动态域名服务)
通过获取到IP地址映射到一个固定的域名解析服务上,实时,定时同步刷新
实现动态IP解析到域名
DDNS 是什么技术
DDNS 是动态 DNS 的缩写,它是一项技术,可以让您使用一个域名访问您家庭网络中的设备,而无需使用家庭网络的内部 IP 地址。这样,您就可以随时随地通过互联网访问家庭网络中的设备,比如智能家居控制器或媒体服务器。
动态IP
常见动态公网IP:手机流量,家用宽带
每次手机重启下飞行模式,在打开流量查询公网IP就会发生变化,家庭宽带也一样,重启下光猫盒子公网IP发生变化,既动态IP
DDNS
域名解析到IP上,如IP发生变化,得手动去重新修改IP解析,这个时候就需要DDNS来免去手动了
域名服务商
这里我用得dnspod
简单实现效果图
定时任务运行脚本,或者添加线程循环运行脚本,脚本在文章末尾
步骤-1
例我域名:a.com
自己域名手动添加一条A解析
,主机记录自定义一个,这里填得ddns,也就是ddns.a.com,记录IP先随便填一个,线路国内,因为业务只在国内
ddns.a.com
后续用这条记录,来完成DDNS
步骤-2
创建一个API
并记录下ID,和Token,Token只有在创建时完整显示一次
注意复制保存
步骤-3
利用API,修改刚才添加得ddns.a.com A解析IP值
均为POST请求
获取ID等接口 | 更新记录 |
---|---|
https://dnsapi.cn/Record.List | https://dnsapi.cn/Record.Ddns |
获取 record_id 和 domain_id 值 Json数据 | 通过获取到得值 设置更新记录 |
所需请求信息,返回json数据,取record_id 和 domain_id 的值
POST /Record.List HTTP/1.1
Host: dnsapi.cn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0
Content-Type: application/x-www-form-urlencoded
login_token=token_id,Token&format=json&domain=a.com
更新动态 DNS 记录
参数名称 | 是否必选 | 描述 |
---|---|---|
domain_id 或 domain | 是 | 分别对应域名ID和域名, 提交其中一个即可。 |
record_id | 是 | 记录ID |
sub_domain | 否 | 主机记录,如 www。 |
record_line | 是 | 记录线路,通过API记录线路获得,中文。比如:默认。 |
record_line_id | 是 | 线路的ID,通过API记录线路获得,英文字符串,比如:‘10=1’。record_line 和 record_line_id 二者传其一即可,系统优先取 record_line_id。 |
value | 否 | IP地址,例如:6.6.6.6。 |
所需请求信息,,通过上一步 获取到得 record_id 和 domain_id 值发送请求,返回json请求
POST /Record.Ddns HTTP/1.1
Host: dnsapi.cn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0
Content-Type: application/x-www-form-urlencoded
login_token=token_id,Token&sub_domain=a.com&format=json&domain_id=域名ID&record_id=获取ID&record_line_id=线路&value=记录IP例如127.0.0.1&domain=域名例如a.com
例子
login_token=
123456,5f31e1db41apq1a19463gqw1f85e5d5364adb&sub_domain=
ddns&format=
json&domain_id=
523426&record_id=
34235721&record_line_id=
7=10&value=
127.0.0.1&domain=
a.com
Python3实现
通过接口获取公网IP,来设置value,IP值,实现获取当前公网IP
def get_ip_addr():
get_ip_aip = "https://www.bt.cn/Api/getIpAddress"
get_http_info = urllib.request.Request(url=get_ip_aip,headers=headers)
run_http = urllib.request.urlopen(get_http_info)
return run_http.read().decode('utf-8')
import urllib.request,json,sys
##DnsPod
#官方参考 >> https://docs.dnspod.cn/api/5f562b21e75cf42d25bf68b6/
#Xs小屋参考 >> https://www.nstns.com/ddns.html
# www.nstns.com
token_id = "123456"
#填入Token 的ID
token_key = "3faae31211a19463fvdsfdafq123db"
#填入 Token
domain = "nstns.cn"
#填入域名
sub_domain = "ddns"
#填入主机记录名
record_line_id = "7=0"
# 7=0 为国内线路
#-------------------------------#
headers = {'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0",'Content-Type': "application/x-www-form-urlencoded"}
def get_info_id():
get_info = "https://dnsapi.cn/Record.List"
http_data = {'login_token':token_id+','+token_key,'domain':domain,'format':"json",}
get_http_info = urllib.request.Request(url=get_info,headers=headers,data=urllib.parse.urlencode(http_data).encode('utf-8'))
run_http = urllib.request.urlopen(get_http_info)
return run_http.read().decode('utf-8')
def get_ip_addr():
get_ip_aip = "https://www.bt.cn/Api/getIpAddress"
get_http_info = urllib.request.Request(url=get_ip_aip,headers=headers)
run_http = urllib.request.urlopen(get_http_info)
return run_http.read().decode('utf-8')
def api_json():
get_id = json.loads(get_info_id())
api_json_config = {'login_token':token_id+','+token_key,'domain':domain,'domain_id':get_id['domain']['id'],'sub_domain':sub_domain,'record_id':get_id['records'][0]['id'],'record_line_id':record_line_id,'format':'json','value':get_ip_addr()}
url_data = urllib.parse.urlencode(api_json_config).encode('utf-8')
return url_data;
def main():
http_info = urllib.request.Request(url="https://dnsapi.cn/Record.Ddns",headers=headers,data=api_json())
run_http = urllib.request.urlopen(http_info).read().decode('utf-8')
get_status = json.loads(run_http)
print("\u005b\u002b\u005d\u4e3b\u673a\u8bb0\u5f55\u540d\uff1a",get_status['record']['name'],"\n\u005b\u002b\u005d\u8bb0\u5f55\u0049\u0050\uff1a",get_status['record']['value'],"\n\u005b\u002b\u005d"+get_status['status']['message'],"\n\u005b\u002b\u005d\u6dfb\u52a0\u65f6\u95f4\uff1a",get_status['status']['created_at'])
return sys.exit()
if __name__ == '__main__':
get_id = json.loads(get_info_id())
print("\u005b\u002b\u005d\t\u83b7\u53d6\u5230\trecord_id:",get_id['records'][0]['id'])
print("\u005b\u002b\u005d\t\u83b7\u53d6\u5230\tdomain_id:",get_id['domain']['id'])
main()