鉴于Routeros的DDNS解析脚本不能提取返回Header,而华为DNS可以任意设置TTL,而华为目前没有完整API,因此借助了Cloudflare Worker,封装了一个API。
视频链接:☺教程和文章更配哦~☺
1、起因
1、想要让DDNS解析快点,需要减小DNS系统的TTL
2、常年使用DNSPOD,但是专业版DNSPOD更改TTL只能更改60,企业版才能改为1
3、想要不受服务器的限制
2、技术分享
- 首先需要你拥有一个Cloudflare的账号,没有可以注册一个
- 创建worker
2.1 点击创建服务
2.2 增加一个服务名称,并创建服务
2.3 快速编辑,复制代码,保存
代码我会放到文末,需要的可以自取!!!
- 创建完毕,点击发送,可以看到执行内容
- 下面介绍一下如何使用
通过GET提交方式,如下图所示,需要用到账户名、密码、zoneid、recordsetid、要更新IP地址、TTL信息
相关信息获取教程在下面
5. 附加内容
- 华为云账户名获取
1.1 在右上角,找到基本信息,点进去
2.1 账号名就是华为云账户
- zoneid和recordsetid获取
2.1 首先,找到你的域名,创建一个,如图所示
2.2 点击F12,出现控制台,调整为Network栏
2.3 修改值为某个IP,点击确定,搜索recordsets
2.4 找到如下图的链接
/**
* Example someHost is set up to take in a JSON request
* Replace url with the host you wish to send requests to
* @param {string} url the URL to send the request to
* @param {BodyInit} body the JSON data to send in the request
*/
//iam.ap-southeast-3.myhuaweicloud.com
const someHost = 'https://iam.ap-southeast-3.myhuaweicloud.com';
//const someHost = 'https://iam.myhuaweicloud.com';
const url = someHost + '/v3/auth/tokens';
/**
* gatherResponse awaits and returns a response body as a string.
* Use await gatherResponse(..) in an async function to get the response body
* @param {Response} response
*/
async function gatherResponse(response) {
const { headers } = response;
return headers.get('x-subject-token');
}
async function handleRequest(request) {
const { searchParams } = new URL(request.url);
let name = searchParams.get('name');
let password = searchParams.get('password');
let hwZONEID = searchParams.get('zoneid');
let hwRECORDSETID = searchParams.get('recordsetid');
let hwip = searchParams.get('ip');
let ttl = searchParams.get('ttl');
let requestURL = new URL(request.url)
let path = requestURL.pathname.split('/')[1];
if(name == null){
const ip = request.headers.get("cf-connecting-ip")
return new Response("华为dns更新\n使用方法:https://"+request.url+"?name=华为云账户&password=华为云密码&zoneid=域名zoneid&recordsetid=域名recordsetid&ip=IP地址&ttl=生效时间\n当前ip:"+ip,{status: 200});
}
console.log(name)
const body = {
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"name": name,
"password": password,
"domain": {
"name": name
}
}
}
},
"scope": {
"domain": {
"name": name
}
}
}
};
const init = {
body: JSON.stringify(body),
method: 'POST',
headers: {
'content-type': 'application/json;charset=UTF-8',
},
};
const response = await fetch(url, init);
const results = await gatherResponse(response);
//return new Response(results, init);
ddnsbody={
"records":[hwip],
"ttl":ttl
}
ddnsinit = {
body: JSON.stringify(ddnsbody),
method: 'PUT',
headers: {
'content-type': 'application/json;charset=UTF-8',
'X-Auth-Token': results
},
};
//dns.ap-southeast-3.myhuaweicloud.com
//ddnsurl='https://dns.myhuaweicloud.com/v2/zones/'+hwZONEID+'/recordsets/'+hwRECORDSETID
ddnsurl='https://dns.ap-southeast-3.myhuaweicloud.com/v2/zones/'+hwZONEID+'/recordsets/'+hwRECORDSETID
const myresponse = await fetch(ddnsurl, ddnsinit);
return myresponse;
return new Response(myresponse.text(), init);
//return new Response(results, init);
}
addEventListener('fetch', event => {
return event.respondWith(handleRequest(event.request));
});
群晖支持代码
1. 使用方法
1.1 使用方法很简单,只需要把代码放到worker中,自定义DDNS服务提供商,填写下面内容,保存,如图所示:
https://你的CLOUDFLARE WORKER地址/update?name=__USERNAME__&password=__PASSWORD__&zoneid=你的ZONEID&recordsetid=你的RECORDSETID&ip=__MYIP__&ttl=1
1.2 点击新增,选择服务提供商,填写下面内容即可
/**
* Example someHost is set up to take in a JSON request
* Replace url with the host you wish to send requests to
* @param {string} url the URL to send the request to
* @param {BodyInit} body the JSON data to send in the request
*/
//iam.ap-southeast-3.myhuaweicloud.com
const someHost = 'https://iam.ap-southeast-3.myhuaweicloud.com';
//const someHost = 'https://iam.myhuaweicloud.com';
const url = someHost + '/v3/auth/tokens';
/**
* gatherResponse awaits and returns a response body as a string.
* Use await gatherResponse(..) in an async function to get the response body
* @param {Response} response
*/
async function gatherResponse(response) {
const { headers } = response;
return headers.get('x-subject-token');
}
async function getresponse(response) {
const { headers } = response;
const contentType = headers.get('content-type') || '';
if (contentType.includes('application/json')) {
return JSON.stringify(await response.json());
}
return response.text();
}
async function handleRequest(request) {
const { searchParams } = new URL(request.url);
let name = searchParams.get('name');
let password = searchParams.get('password');
let hwZONEID = searchParams.get('zoneid');
let hwRECORDSETID = searchParams.get('recordsetid');
let hwip = searchParams.get('ip');
let ttl = searchParams.get('ttl');
let requestURL = new URL(request.url)
let path = requestURL.pathname.split('/')[1];
if(name == null){
const ip = request.headers.get("cf-connecting-ip")
return new Response("华为dns更新\n使用方法:https://"+request.url+"?name=华为云账户&password=华为云密码&zoneid=域名zoneid&recordsetid=域名recordsetid&ip=IP地址&ttl=生效时间\n当前ip:"+ip,{status: 200});
}
console.log(name)
const body = {
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"name": name,
"password": password,
"domain": {
"name": name
}
}
}
},
"scope": {
"domain": {
"name": name
}
}
}
};
const init = {
body: JSON.stringify(body),
method: 'POST',
headers: {
'content-type': 'application/json;charset=UTF-8',
},
};
const response = await fetch(url, init);
const results = await gatherResponse(response);
//return new Response(results, init);
ddnsbody={
"records":[hwip],
"ttl":ttl
}
ddnsinit = {
body: JSON.stringify(ddnsbody),
method: 'PUT',
headers: {
'content-type': 'application/json;charset=UTF-8',
'X-Auth-Token': results
},
};
//dns.ap-southeast-3.myhuaweicloud.com
//ddnsurl='https://dns.myhuaweicloud.com/v2/zones/'+hwZONEID+'/recordsets/'+hwRECORDSETID
ddnsurl='https://dns.ap-southeast-3.myhuaweicloud.com/v2/zones/'+hwZONEID+'/recordsets/'+hwRECORDSETID
const myresponse = await fetch(ddnsurl, ddnsinit);
//return myresponse;
const rcode=await getresponse(myresponse);
console.log(rcode);
if(JSON.parse(rcode)['error_code']=='APIGW.0301'){
return new Response("badauth", init);
}
if(JSON.parse(rcode)['code']=='DNS.0302'){
return new Response("nohost", init);
}
if(JSON.parse(rcode)['code']=='DNS.0313'){
return new Response("nohost", init);
}
if(JSON.parse(rcode)['code']=='DNS.0308'){
return new Response("abuse", init);
}
//return rcode;
//return new Response(myresponse.body, init);
//good
return new Response("good", init);
//return new Response(results, init);
}
addEventListener('fetch', event => {
return event.respondWith(handleRequest(event.request));
});
另附PHP版
<?php
function PostMain($url,$data){
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST,1);
curl_setopt($curl, CURLOPT_POSTFIELDS,$data);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
$data = curl_exec($curl);
curl_close($curl);
$arr = explode("\r\n", $data);
$token = explode(":", $arr[9]);
return $token[1];
}
function PutMeth($url,$data,$token){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','X-Auth-Token: '.$token));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
function codeecho($jsoncode,$domain_name){
if(isset($jsoncode['error_code'])){
if($jsoncode['error_code']=='APIGW.0301'){
return "badauth";
}
}
if(isset($jsoncode['code'])){
if($jsoncode['code']=='DNS.0302'){
return "nohost";
}
if($jsoncode['code']=='DNS.0313'){
return "nohost";
}
if($jsoncode['code']=='DNS.0308'){
return "abuse";
}
}
if($jsoncode['name']!=$domain_name."."){
return "nochg";
}
return "good";
}
function ddns($name,$password,$hwip,$ttl,$zoneid,$recordsetid,$domain_name){
$url = "https://iam.myhuaweicloud.com/v3/auth/tokens";
$ddnsurl="https://dns.myhuaweicloud.com/v2/zones/".$zoneid."/recordsets/".$recordsetid;
$loginbody="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"name\":\"".$name."\",\"password\":\"".$password."\" ,\"domain\":{\"name\":\"".$name."\"}}}},\"scope\":{\"domain\":{\"name\":\"".$name."\"}}}}";
$ddnsbody="{\"records\":[\"$hwip\"],\"ttl\":".$ttl."}";
$token=PostMain($url,$loginbody);
$result= PutMeth($ddnsurl,$ddnsbody,$token);
$jsoncode=json_decode($result,true);
return codeecho($jsoncode,$domain_name);
}
function usage(){
echo "<h3>华为dns更新</h3>
<p>使用方法:
http://域名/update.php?name=华为云账户&password=华为云密码&zoneid=域名zoneid&recordsetid=域名recordsetid&ip=IP地址&ttl=生效时间&domain=域名</p>";
}
header("Content-Type: text/html; charset=utf-8");
$myip=$_SERVER["REMOTE_ADDR"];
if (is_array($_GET) && count($_GET) > 0) {
if (isset($_GET['name']) && isset($_GET['name']) && isset($_GET['password']) && isset($_GET['ttl']) && isset($_GET['zoneid']) && isset($_GET['recordsetid']) && isset($_GET['domain'])) {
$name = $_GET['name'];
$password=$_GET['password'];
if(!isset($_GET['ip'])){
$_GET['ip']=$myip;
}
//$_GET['ip']=$myip;
$hwip= $_GET['ip'];
$ttl= $_GET['ttl'];
$zoneid= $_GET['zoneid'];
$recordsetid= $_GET['recordsetid'];
$domain_name=$_GET['domain'];
echo ddns($name,$password,$hwip,$ttl,$zoneid,$recordsetid,$domain_name);
}else{
usage();
echo $myip;
}
}else{
usage();
echo $myip;
}
?>
思路参考的大佬的,在此感谢
直达链接
https://github.com/lllvcs/huaweicloud_ddns