侧边栏壁纸
博主头像
いちごみるく

行动起来,活在当下

  • 累计撰写 70 篇文章
  • 累计创建 48 个标签
  • 累计收到 55 条评论

目 录CONTENT

文章目录

ddns获取IPV4或IPV6接口

公网 IP 查询接口返回的是服务看到的出口地址,不一定是要发布服务的网卡地址。本文使用有格式说明的接口示例,并在写入 DDNS 前检查返回值。

一、分别获取 IPv4 与 IPv6

ipify 官方文档提供纯文本接口。以下使用 HTTPS,并显式选择地址族;没有 IPv6 出口时,第二条应失败,不能回退成 IPv4 后写入 AAAA。

curl --noproxy '*' -4 --fail --silent --show-error \
  --connect-timeout 5 --max-time 10 https://api.ipify.org
curl --noproxy '*' -6 --fail --silent --show-error \
  --connect-timeout 5 --max-time 10 https://api6.ipify.org

--noproxy '*' 忽略 curl 使用的应用代理设置,不能绕过系统 TUN、路由器透明代理或策略路由。所谓“绕过中国大陆模式”也不能保证接口查询走家庭 WAN。需要在代理规则中明确让查询经目标出口,或使用 DDNS 工具的指定网卡/地址读取功能。curl 手册可核对 -4、-6、--noproxy 与超时参数。

二、写 DNS 前验证结果

自动更新 A/AAAA 前,要确认 HTTP 请求成功、返回值可按所需地址族解析、不是空文本/HTML/错误消息,并与目标服务器的地址和出口一致。一次查询失败时保留已有记录,不要用空值覆盖。

有 Python 3 的 Linux/Bash 环境可以先校验 IPv4 文本:

if ! ip_text=$(curl --noproxy '*' -4 --fail --silent --show-error \
  --connect-timeout 5 --max-time 10 https://api.ipify.org); then
  exit 1
fi
printf '%s' "$ip_text" | python3 -c 'import ipaddress,sys; a=ipaddress.ip_address(sys.stdin.read().strip()); assert a.version == 4; assert a.is_global; print(a)'

IPv6 需用 IPv6 接口并把检查改为 a.version == 6。验证通过才调用 DNS 服务商更新 API;这里没有包含凭据或实际写入命令。API 可用性和结果含义是两个不同问题。

三、出口地址与可入站地址不同

IPv4 若处于 CGNAT/多层 NAT 后,接口返回公网出口,也不意味着自己控制该地址的入站映射。IPv6 接口可能返回当前用于出站的临时隐私地址;给服务发布 AAAA,应选择目标服务接口上合适、稳定且可达的全局地址,不能发布链路本地或 ULA 地址。

DDNS 只更新名称解析,不能自动打开端口、绕过运营商限制或修改防火墙。更新后检查权威 DNS 的 A/AAAA,再从外部按地址族分别连接实际端口;在内网访问成功或接口返回一个 IP,都不足以证明公网服务可达。

选择其他公网 IP 接口时,同样需要核对响应格式、TLS、超时和代理出口,不能将测速页面或未经校验的 HTTP 响应直接用于 DDNS。

0

评论区