春风得意马蹄疾 记录技术,分享生活
随笔: 35 分类: 15 评论: 2 阅读: 7,327

IPv6 动态前缀下实现 DDNS 自动更新域名解析

📅 发表于 2026-06-18 01:32:02 👁 阅读 63 次 💬 评论 0

问题背景

我的服务器托管在联通家庭宽带下,没有公网 IPv4 地址,只能通过 IPv6 访问。博客域名 xiaoajun.cn 通过 AAAA 记录指向服务器 IPv6 地址。

最近发现博客突然无法访问,排查后发现是联通光猫重启后 IPv6 前缀发生了变化——从 2408:8270:103a:89f0::/64 变成了 2408:8270:1039:4500::/64,导致 DNS 解析的旧 IPv6 地址失效。

更麻烦的是,联通家用宽带使用的是 PrefixDelegation(前缀委托),IPv6 前缀会不定期变化,每次变化都需要手动更新 DNS 记录,非常不方便。

排查过程

第一步:检查 IPv6 连通性

# 查看服务器 IPv6 地址
ip -6 addr show enp2s0f0

# 测试外网连通性
ping6 -c 3 2400:3200::1

发现服务器有 IPv6 地址但外网不通,traceroute 显示第一跳就超时。

第二步:检查光猫配置

登录光猫管理后台,查看 WAN 口信息,发现光猫获取到的新前缀与服务器上配置的旧前缀不一致:

  • 光猫新前缀:2408:8270:1039:4500::/60
  • 服务器旧前缀:2408:8270:103a:89f0::/64

前缀变了!这就是博客无法访问的根因。

第三步:改为自动获取 IPv6

服务器原本是手动配置的 IPv6 地址,需要改为自动获取:

# 修改 NetworkManager 为自动获取
nmcli con mod "有线连接 1" ipv6.method auto
nmcli con up "有线连接 1"

# 开启 RA 接受(接受路由器通告)
sysctl -w net.ipv6.conf.enp2s0f0.accept_ra=2
echo "net.ipv6.conf.enp2s0f0.accept_ra=2" >> /etc/sysctl.conf

解决方案:华为云 DNS API 自动化 DDNS

自动获取 IPv6 后,服务器能跟随光猫前缀变化。但还需要一个机制在 IPv6 变化时自动更新域名解析。

技术选型

  • 华为云 DNS SDK:使用 huaweicloudsdkdns Python SDK 操作 DNS 记录
  • 华为云 AK/SK 认证:通过访问密钥调用 API
  • Cron 定时任务:每 5 分钟检测一次 IPv6 变化

核心脚本逻辑

#!/usr/bin/env python3
import re, subprocess, os
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkdns.v2 import DnsClient
from huaweicloudsdkdns.v2 import UpdateRecordSetRequest, UpdateRecordSetReq
from huaweicloudsdkcore.region.region import Region

AK = 'your_access_key'
SK = 'your_secret_key'
ZONE_ID = 'your_zone_id'
RECORDS = {
    'xiaoajun.cn.': 'record_id_1',
    'www.xiaoajun.cn.': 'record_id_2',
}

def get_ipv6():
    """获取 mngtmpaddr 类型 IPv6(相对稳定)"""
    result = subprocess.run(
        ['ip', '-6', 'addr', 'show', 'enp2s0f0'],
        capture_output=True, text=True
    )
    for line in result.stdout.split('\n'):
        if 'global' in line and 'mngtmpaddr' in line:
            match = re.search(r'inet6\s+([\da-f:]+)/', line)
            if match:
                return match.group(1)
    return None

def update_dns(ipv6):
    credentials = BasicCredentials(AK, SK)
    client = DnsClient.new_builder() \
        .with_credentials(credentials) \
        .with_region(Region(id='cn-north-4',
                   endpoint='dns.cn-north-4.myhuaweicloud.com')) \
        .build()
    
    for domain, record_id in RECORDS.items():
        request = UpdateRecordSetRequest()
        request.zone_id = ZONE_ID
        request.recordset_id = record_id
        body = UpdateRecordSetReq()
        body.records = [ipv6]
        body.ttl = 600
        request.body = body
        response = client.update_record_set(request)
        print(f'{domain} -> {ipv6} ({response.status})')

if __name__ == '__main__':
    ipv6 = get_ipv6()
    if ipv6:
        update_dns(ipv6)

Cron 定时任务

# 每5分钟检查一次 IPv6 变化并自动更新 DNS
*/5 * * * * /usr/bin/python3 /usr/local/bin/ddns-auto.py

验证效果

重启光猫后,IPv6 前缀再次变化(1035:2120 → 1036:7c30),DDNS 脚本在 2 秒内自动检测到变化并更新了华为云 DNS 记录:

2026-06-17 23:02:09 [INFO] IPv6 变化: 2408:8270:1035:2120:... -> 2408:8270:1036:7c30:...
2026-06-17 23:02:10 [OK] xiaoajun.cn. -> 2408:8270:1036:7c30:... (status=ACTIVE)
2026-06-17 23:02:10 [OK] www.xiaoajun.cn. -> 2408:8270:1036:7c30:... (status=ACTIVE)

DNS 记录在华为云控制台中也确认已更新为 ACTIVE 状态。

总结

通过 自动获取 IPv6 + 华为云 DNS API + Cron 定时任务 这套方案,彻底解决了家庭宽带 IPv6 前缀动态变化导致的域名解析失效问题。整个过程完全自动化,无需人工干预。

关键步骤回顾:

  1. 服务器 IPv6 改为自动获取(NetworkManager auto)
  2. 开启 RA 接受(sysctl accept_ra=2)
  3. 获取华为云 Access Key(AK/SK)
  4. 编写 Python DDNS 更新脚本
  5. 设置 Cron 定时任务每 5 分钟执行

以后再也不用担心光猫重启导致博客无法访问了!

📂 分类:服务器维护
评论 (0)
技术分享者 · 记录成长的每一步
✨ 特效 ON