飞羽

Cloudflare worker更新华为DNS解析服务【支持群晖】
鉴于Routeros的DDNS解析脚本不能提取返回Header,而华为DNS可以任意设置TTL,而华为目前没有完整...
扫描右侧二维码阅读全文
20
2022/10

Cloudflare worker更新华为DNS解析服务【支持群晖】

鉴于Routeros的DDNS解析脚本不能提取返回Header,而华为DNS可以任意设置TTL,而华为目前没有完整API,因此借助了Cloudflare Worker,封装了一个API。

视频链接:☺教程和文章更配哦~☺

1、起因

1、想要让DDNS解析快点,需要减小DNS系统的TTL
2、常年使用DNSPOD,但是专业版DNSPOD更改TTL只能更改60,企业版才能改为1
3、想要不受服务器的限制

2、技术分享

  1. 首先需要你拥有一个Cloudflare的账号,没有可以注册一个
  2. 创建worker
    2.1 点击创建服务


2.2 增加一个服务名称,并创建服务

2.3 快速编辑,复制代码,保存

代码我会放到文末,需要的可以自取!!!

  1. 创建完毕,点击发送,可以看到执行内容
  1. 下面介绍一下如何使用
    通过GET提交方式,如下图所示,需要用到账户名、密码、zoneid、recordsetid、要更新IP地址、TTL信息

相关信息获取教程在下面

5. 附加内容

  1. 华为云账户名获取
    1.1 在右上角,找到基本信息,点进去


2.1 账号名就是华为云账户

  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

文章名: 《Cloudflare worker更新华为DNS解析服务【支持群晖】》

文章链接:https://blog.8086k.cn/archives/128/

联系方式:1412981048@qq.com

除特别注明外,文章均为飞羽小随笔原创,转载时请注明本文出处及文章链接
Last modification:October 24th, 2022 at 08:59 pm
如果觉得我的文章对你有用,请随意赞赏

Leave a Comment