Fari

Dns

阿里云api实现ipv6的ddns

创建python的虚拟环境

# 创建一个虚拟环境python3 -m venv ipv6_py_env# 激活虚拟环境source ipv6_py_env/bin/activate

获取ipv6地址的脚本

ifconfig | grep -A 10 wlp2s0 | grep 'inet6' | awk '{print $2}' | sed '/fe80/ d'

将上述脚本使用python封装

res = sp.run("ifconfig | grep -A 10 wlp2s0 | grep 'inet6' | awk '{print $2}' | sed '/fe80/ d'", shell=True, capture_output=True, encoding="utf8")ipv6_addrs = res.stdout.split()  # ipv6地址可能有多个,随便用一个即可

完整的python代码(修改自参考中的示例代码)

# -*- coding: utf-8 -*-import osimport sysimport timeimport subprocessfrom loguru import logger as loglog.add("auto_refresh.log")from typing import Listfrom alibabacloud_alidns20150109.client import Client as Alidns20150109Clientfrom alibabacloud_tea_openapi import models as open_api_modelsfrom alibabacloud_alidns20150109 import models as alidns_20150109_modelsfrom alibabacloud_tea_util import models as util_modelsfrom alibabacloud_tea_util.client import Client as UtilClientclass Refresh:    def __init__(self):        pass    @staticmethod    def create_client(        access_key_id: str,        access_key_secret: str,    ) -> Alidns20150109Client:        """        使用AK&SK初始化账号Client        @param access_key_id:        @param access_key_secret:        @return: Client        @throws Exception        """        config = open_api_models.Config(            access_key_id=access_key_id,            access_key_secret=access_key_secret        )        # Endpoint 请参考 https://api.aliyun.com/product/Alidns        config.endpoint = f'alidns.cn-hangzhou.aliyuncs.com'        return Alidns20150109Client(config)    @staticmethod    def update_dns(        new_ip: str    ) -> bool:        # 请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。        # 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取 AccessKey 的方式进行调用,仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378659.html        client = Refresh.create_client("your-ALIBABA_CLOUD_ACCESS_KEY_ID", "your-ALIBABA_CLOUD_ACCESS_KEY_SECRET")        # record_id 可以通过 DescribeDomainRecords 接口拿到, 见 https://next.api.aliyun.com/api/Alidns/2015-01-09/DescribeDomainRecords        update_domain_record_request = alidns_20150109_models.UpdateDomainRecordRequest(            record_id='879766660467119104',            rr='ipv6',            type='AAAA',            value=new_ip        )        runtime = util_models.RuntimeOptions()        try:            # 复制代码运行请自行打印 API 的返回值            client.update_domain_record_with_options(update_domain_record_request, runtime)            return True        except Exception as error:            if "The DNS record already exists" in error.message:                # 说明该条记录已经存在,则无需更新                return True            log.error(error.message)            # 诊断地址            log.error(error.data.get("Recommend"))            UtilClient.assert_as_string(error.message)            return False        return Falseif __name__ == '__main__':    # 检测当前ip是否和上次更新的ip一直,如果不一致则更新dns    pre_ip, cur_ip = None, None    while True:        try:            res = subprocess.run("ifconfig | grep -A 10 wlp2s0 | grep 'inet6' | awk '{print $2}' | sed '/fe80/ d'", shell=True, capture_output=True, encoding="utf8")            if not (res and res.stdout and res.stdout.split()):                raise Exception(f"empty ipv6 address, {res and res.stdout}")        except Exception as e:            log.error(f"get ip error, {e}")            time.sleep(30)            continue        ipv6_addrs = res.stdout.split()        if pre_ip in ipv6_addrs:            time.sleep(1)            continue        else:            cur_ip = ipv6_addrs[-1]            updated = Refresh.update_dns(cur_ip)            if updated:                log.info(f"updated dns, pre: {pre_ip}, new: {cur_ip}")                pre_ip = cur_ip                time.sleep(30)                continue            else:                log.error("update dns fail")                time.sleep(30)                continue

最后执行该文件即可

DNS与CDN相关联系与实现

file

背景:

  1. Client 1 与 business server 3 及DNS A在地理位置上相较于其他更近。
  2. dns缓存均未命中。
  3. Local DNS 默认实现了 edns 协议。(路由查询会携带源client的ip地址)
  4. a.com 域名配置为了 NS 记录方式。

过程解析:

  1. Client 1 向local dns(即本机设置的dns服务器,本例中为 8.8.8.8)发送域名 mail.a.com 的解析请求。
  2. 通过 anycall 技术可以实现一个 8.8.8.8 地址被多个域名解析服务器使用,通过 bgp 协议找到距离 client 1 最近的dns server(本例中为:DNS A) 3.1 DNS A如果未开启转发模式,则会请求根域名服务器,根域名服务器返回域名服务器ip地址(本例中为 com dns server),DNS A请求com dns server,其返回 a.com dns server ip地址【批注1】。DNS A携带client A的源ip(edge协议)访问 a.com dns server,该dns依据 edns 协议,由 client A的ip地址匹配与其地理位置最近的mail.a.com CDN服务器的ip(本例中为 business server A 3.3.3.3)。DNS A将3.3.3.3返回给客户机,客户机再访问该server A。 3.2 DNS A如果开启转发模式,则会根据其配置的转发规则进行转发,具体可参考:https://www.cnblogs.com/qingdaofu/p/7399670.html

【批注1】:我们注册域名后,可以选择将域名解析为 NS 记录(类比 A记录或CNAME记录),其会将该域名授权为 dns 域名解析服务器的域名,我们可以自己实现路由规则。