【IPV6从入门到起飞】3-域名解析动态IPV6(阿里云)

【IPV6从入门到起飞】3-域名解析动态IPV6(阿里云)

  • [1 回顾以及背景](#1 回顾以及背景)
  • [2 Linux下Python动态修改域名解析 AAAA](#2 Linux下Python动态修改域名解析 AAAA)
    • [2.1 创建用户获得权限](#2.1 创建用户获得权限)
    • [2.2 创建IPV6记录](#2.2 创建IPV6记录)
    • [2.3 调试API](#2.3 调试API)
    • [2.4 编写动态获取并修改的Python代码](#2.4 编写动态获取并修改的Python代码)
    • [2.5 进程守护](#2.5 进程守护)
    • [2.6 实际效果](#2.6 实际效果)
      • [2.6.1 正常运行](#2.6.1 正常运行)
      • [2.6.2 动态修改域名记录](#2.6.2 动态修改域名记录)
      • [2.6.3 断网恢复修改](#2.6.3 断网恢复修改)
  • [3 使用DDNS-Go动态解析IPV6](#3 使用DDNS-Go动态解析IPV6)

1 回顾以及背景

在上节我们有讲到,可以通过隧道、CPE、路由器、手机获取我们的IPV6地址,但是很长,没办法记得住,而且是可变的,所以需要想个办法方便记住而且不会因为IPV6变了而乱了阵脚。

这种操作叫做 域名解析动态IPV6 ,简单来说就是,如果电脑的IPV6发生改变,那就需要将域名记录的IPV6同步修改,这样我们只需要访问我们的熟悉的域名,就能指向该电脑。

下面通过几种方法实现我们的方案。

但是前提:你得先有个域名!怎么整的我不管,我是从阿里云买的,这玩意也不贵。

https://wanwang.aliyun.com/domain/searchresult

2 Linux下Python动态修改域名解析 AAAA

2.1 创建用户获得权限

a、前往阿里云控制台的 RAM访问控制 获得 AccessKey IDSercet 不要泄露哦

b、给这个用户分配对应的权限 domain

2.2 创建IPV6记录

给你的域名先绑一个AAAA的记录,这个是你电脑的IPV6

2.3 调试API

在阿里云的OpenAPI 调试一下,尝试修改域名解析记录

然后在导出api实例,在python进行调试

2.4 编写动态获取并修改的Python代码

  • 须知:电脑可能会有多个IPV6

  • 功能以及流程:

    a、每5分钟(可以自己调整速率)获取阿里云上对应解析的记录

    b、获取本机(Linux)上的IPV6,保留24开头的IP(目的是过滤掉fe开头的IP),可按需修改,有的IPV6是20开头

    c、如果阿里云上解析的记录与本机的一致,则不修改,否则提交修改记录

    d、使用了try-except,有效避免断网时无法请求或无法提交导致的错误

  • 安装python包

powershell 复制代码
pip install alibabacloud_alidns20150109==3.5.5
  • python代码:
    记得修改为你的ID、SECRET、顶级域名、二级域名
python 复制代码
import os
import sys
import subprocess
import time
import socket
from typing import List
import netifaces
from datetime import datetime

from alibabacloud_alidns20150109.client import Client as Alidns20150109Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_alidns20150109 import models as alidns_20150109_models
from alibabacloud_tea_util import models as util_models
from alibabacloud_tea_util.client import Client as UtilClient

class AlibabaCloudStaticGlobal:
    # 类变量(静态变量)
    recordId = ""
    analyzeType = ""
    domainValue = ""
    # domainValueTemp = ""
    httpRequestCode = 0

    ACCESS_KEY_ID = "xxxxxxxxxxxxxxxxxxxxxxxx"              #(这个记得修改)
    ACCESS_KEY_SECRET = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"    #(这个记得修改)
    DNS_DOMAIN_1_LEVEL = "xxxxxx.xxx"  # 顶级域名			 (这个记得修改)
    DOMAIN_2_LEVEL = "xxx"  # 二级域名                       (这个记得修改)


class Sample:
    def __init__(self):
        pass

    @staticmethod
    def create_client() -> Alidns20150109Client:
        """
        使用AK&SK初始化账号Client
        @return: Client
        @throws Exception
        """
        # 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
        # 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378659.html。
        config = open_api_models.Config(
            # 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。,
            access_key_id=AlibabaCloudStaticGlobal.ACCESS_KEY_ID,
            # 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。,
            access_key_secret=AlibabaCloudStaticGlobal.ACCESS_KEY_SECRET
        )
        # Endpoint 请参考 https://api.aliyun.com/product/Alidns
        config.endpoint = f'dns.aliyuncs.com'
        return Alidns20150109Client(config)

    @staticmethod
    def changeDomain(
            args: List[str],
    ) -> None:
        client = Sample.create_client()
        update_domain_record_request = alidns_20150109_models.UpdateDomainRecordRequest(
            record_id=AlibabaCloudStaticGlobal.recordId,
            rr=AlibabaCloudStaticGlobal.DOMAIN_2_LEVEL,
            type=AlibabaCloudStaticGlobal.analyzeType,
            value=AlibabaCloudStaticGlobal.domainValue
        )
        runtime = util_models.RuntimeOptions()
        try:
            # 复制代码运行请自行打印 API 的返回值
            result = client.update_domain_record_with_options(update_domain_record_request, runtime)
            print("域名更新成功")
            AlibabaCloudStaticGlobal.httpRequestCode = result.status_code
        except Exception as error:
            # 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            # 错误 message
            print(error.message)
            # 诊断地址
            print(error.data.get("Recommend"))
            UtilClient.assert_as_string(error.message)
            AlibabaCloudStaticGlobal.httpRequestCode = 400

    @staticmethod
    def getdomainlist(
            args: List[str],
    ) -> None:
        client = Sample.create_client()
        describe_domain_records_request = alidns_20150109_models.DescribeDomainRecordsRequest(
            domain_name=AlibabaCloudStaticGlobal.DNS_DOMAIN_1_LEVEL
        )
        runtime = util_models.RuntimeOptions()
        try:
            # 复制代码运行请自行打印 API 的返回值
            result = client.describe_domain_records_with_options(describe_domain_records_request, runtime)
            if result.status_code == 200:
                AlibabaCloudStaticGlobal.httpRequestCode = 400
                for item in result.body.domain_records.record:
                    if item.rr == AlibabaCloudStaticGlobal.DOMAIN_2_LEVEL:
                        print("找到二级域名:", AlibabaCloudStaticGlobal.DOMAIN_2_LEVEL)
                        AlibabaCloudStaticGlobal.httpRequestCode = 200
                        # print("记录ID为:", item.record_id)
                        AlibabaCloudStaticGlobal.recordId = item.record_id
                        # print("解析类型为:", item.type)
                        AlibabaCloudStaticGlobal.analyzeType = item.type
                        print("记录值为:", item.value)
                        AlibabaCloudStaticGlobal.domainValue = item.value


        except Exception as error:
            # 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            # 错误 message
            print(error.message)
            # 诊断地址
            print(error.data.get("Recommend"))
            UtilClient.assert_as_string(error.message)
            AlibabaCloudStaticGlobal.httpRequestCode = 400


# 使用网络服务api接口获取当前IP地址并切片 ,windows和linux都好用
def getIpv6_url():
    url_ipv6 = []
    rets = subprocess.getoutput('curl http://ifconfig.io')
    # print("retult = " + rets + "\r\n")
    ret_list = rets.split('\n')
    # Log("list1=%s" %ret_list)
    print("last list=%s" % ret_list[-1])
    if ret_list[-1].startswith('24'):
        url_ipv6.append(ret_list[-1])
    return url_ipv6


def get_ipv6_addresses_windows():
    # 获取所有的网络接口
    addresses = socket.getaddrinfo(socket.gethostname(), None, socket.AF_INET6)

    # 提取并打印 IPv6 地址
    ipv6_addresses = set()
    print(ipv6_addresses)
    for addr in addresses:
        if addr[4][0].startswith('24'):  # 过滤fe80
            ipv6_addresses.add(addr[4][0])
    return ipv6_addresses


def get_ipv6_addresses_linux():
    ipv6_addresses = set()
    for interface in netifaces.interfaces():
        addrs = netifaces.ifaddresses(interface)
        if netifaces.AF_INET6 in addrs:
            for link in addrs[netifaces.AF_INET6]:
                if link['addr'].startswith('24'):  # 过滤fe80
                    ipv6_addresses.add(link['addr'])
    return ipv6_addresses


if __name__ == '__main__':

    while True:
        time.sleep(60 * 5)  # 延时
        print("\n")
        # 格式化输出
        current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        print("当前时间:", current_time)
        try:
            jumpRefreshFlag = 0
            Sample.getdomainlist(sys.argv[1:])
            if AlibabaCloudStaticGlobal.httpRequestCode == 200:
                nowIpv6List = get_ipv6_addresses_linux()
                if len(nowIpv6List) == 0:
                    print("[warning] 找不到IPV6")
                    continue
                for addr in nowIpv6List:
                    if AlibabaCloudStaticGlobal.domainValue == addr:
                        print("域名记录一致,不用修改")
                        jumpRefreshFlag = 1
                if jumpRefreshFlag == 1:
                    continue

                print("域名记录不一致,要修改")
                newIpv6 = nowIpv6List.pop()
                print("[" + AlibabaCloudStaticGlobal.domainValue + "]--->[" + newIpv6 + "]")
                AlibabaCloudStaticGlobal.domainValue = newIpv6
                Sample.changeDomain(sys.argv[1:])

            else:
                print(AlibabaCloudStaticGlobal.httpRequestCode)
        except Exception as e:
            # 处理其他所有异常
            print(f"An unexpected error occurred: {e}")

2.5 进程守护

可以考虑使用宝塔上的进程守护管理器来运行程序,还可以看日志

2.6 实际效果

2.6.1 正常运行

2.6.2 动态修改域名记录

2.6.3 断网恢复修改

3 使用DDNS-Go动态解析IPV6

关于DDNS-Go,在这里我不是很想再按照什么教程抄一遍,我觉得以下这篇写得挺好的,大家可以参考一下:

超好用的动态域名解析工具------DDNS-Go

相关推荐
Jay_2725 分钟前
python项目如何创建docker环境
开发语言·python·docker
老胖闲聊44 分钟前
Python Django完整教程与代码示例
数据库·python·django
爬虫程序猿1 小时前
利用 Python 爬虫获取淘宝商品详情
开发语言·爬虫·python
noravinsc1 小时前
django paramiko 跳转登录
后端·python·django
声声codeGrandMaster1 小时前
Django之表格上传
后端·python·django
Antonio9151 小时前
【Linux】 Linux 进程控制
linux·运维·服务器
元直数字电路验证1 小时前
Python数据分析及可视化中常用的6个库及函数(一)
python·numpy
waterHBO1 小时前
一个小小的 flask app, 几个小工具,拼凑一下
javascript·vscode·python·flask·web app·agent mode·vibe coding
智商不够_熬夜来凑1 小时前
anaconda安装playwright
开发语言·python
溜溜刘@♞1 小时前
python变量
python