1. 结论
| 域名 | DNS 记录 | 能否走 IPv4 | 能否走 IPv6 |
|---|---|---|---|
v6.ident.me | 只有 AAAA(IPv6-only) | ❌ 不能 | ✅ 能 |
v4.ident.me | 只有 A(IPv4-only) | ✅ 能 | ❌ 不能 |
ident.me | A + AAAA(双栈) | ✅ 能 | ✅ 能 |
判定原则:一个网址能不能用 IPv4 访问,首先看它有没有 A 记录;没有 A 记录,curl -4在 DNS 阶段就失败。
注意:CMD 不支持反斜杠
\换行,所有命令必须一行内写完。.bat文件里%{http_code}要写成%%{http_code}。
2. 案例:v6.ident.me 三条命令
curl -sk4 --max-time 10 --noproxy "*" -o NUL -w "IPv4: HTTP:%{http_code}\n" https://v6.ident.me/ curl -sk6 --max-time 10 --noproxy "*" -o NUL -w "IPv6: HTTP:%{http_code}\n" https://v6.ident.me/ curl -sk --max-time 10 --noproxy "*" -o NUL -w "DEFAULT: HTTP:%{http_code}\n" https://v6.ident.me/参数解释
| 参数 | 含义 |
|---|---|
-s | 静默模式,不打印进度条 |
-k | 跳过 TLS 证书校验 |
-4 | 强制只走 IPv4(只查 A 记录) |
-6 | 强制只走 IPv6(只查 AAAA 记录) |
不加-4/-6 | 让系统自选地址族 |
--max-time 10 | 整个请求最多等 10 秒 |
--noproxy "*" | 禁止走任何代理(*= 所有主机都不走) |
-o NUL | 丢弃响应正文,只看结果 |
-w "..." | 请求结束后按格式输出信息 |
%{http_code} | HTTP 状态码 |
\n | 换行 |
结果:-4→HTTP:000/ exit 6(无 A 记录);-6和默认 →HTTP:200/ exit 0(走 IPv6 成功)。
3. 强制走 IPv4 / IPv6:–connect-to 与 --resolve
这两个参数都能绕过 DNS,强行指定 curl 连接的目标 IP,区别在于--connect-to作用于 TCP 连接层、--resolve作用于 DNS 解析层;利用它们可以检测某个 IP 上的服务器是否还在提供服务、域名解析到的 A / AAAA 记录哪个是正确的、失败是不是 DNS 解析错误导致的,以及同一个 IP 上不同 SNI(域名)的访问结果是否不同。
命令 A:强制 IPv4(–connect-to)
curl -sk --noproxy "*" --connect-to www.freedidi.com:443:179.253.231.105:443 -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" -o NUL -w "HTTP:%{http_code} size:%{size_download}\n" -m 20 https://www.freedidi.com/参数解释
| 参数 | 含义 |
|---|---|
--connect-to 原域名:原端口:新IP:新端口 | 要连www.freedidi.com:443时,实际拨号到179.253.231.105:443 |
| ↳ 作用层 | TCP 连接层(仍查 DNS,但结果被覆盖) |
| ↳ SNI / Host / 证书校验 | 仍然是www.freedidi.com |
-A "Mozilla/5.0..." | 设置 User-Agent,伪装成 Chrome |
--noproxy "*" | 禁止走代理,强制直连 |
-o NUL | 丢弃响应正文 |
-w "HTTP:%{http_code} size:%{size_download}\n" | 输出状态码 + 下载字节数 |
-m 20 | 总超时 20 秒 |
命令 B:强制 IPv6(–resolve)
curl -sk --noproxy "*" --resolve "www.freedidi.com:443:[2605:52c0:2:6867:be24:11ff:fe13:cff4]" -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" -o NUL -w "HTTP:%{http_code} size:%{size_download}\n" -m 20 https://www.freedidi.com/参数解释
| 参数 | 含义 |
|---|---|
--resolve 域名:端口:IP | 解析该域名时不查 DNS,直接返回指定 IP |
| ↳ 作用层 | DNS 解析层 |
| ↳ IPv6 地址必须加方括号 | 否则冒号被当字段分隔符,导致格式错误 |
| 其余参数 | 与命令 A 相同 |
两者区别
| 参数 | 作用阶段 | 是否查 DNS | 经代理是否有效 |
|---|---|---|---|
--connect-to | TCP 连接层 | ✅ 查(结果被覆盖) | ✅ 有效 |
--resolve | DNS 解析层 | ❌ 不查 | ⚠️ 经代理会被代理 DNS 覆盖,需配--noproxy "*" |
结果解释
| 命令 | 预期结果 | 含义 |
|---|---|---|
--connect-to强制 IPv4 | HTTP:200 | 该 IPv4 地址可用,证明 IPv4 源站正常 |
--connect-to强制 IPv6 | HTTP:200 / 000 | 该 IPv6 地址能否用这个域名访问;000 表示连接失败或该服务器不响应 |
--resolve强制 IPv6 | HTTP:200 / 000 | 取决于该 IPv6 地址当时是否还提供服务;000 表示连接失败或该服务器不响应 |
--resolve配合-4 | HTTP:000 | 可验证域名没有 A 记录,或注入的 IPv4 地址无效 |
000 不等于"服务器坏了",它只是"请求没成功"。具体原因要结合 exit 码:
6=DNS 无记录,7=TCP 连不上,28=超时,35=TLS 失败。
4. 链路地址族检测
curl -sk --ssl-no-revoke -m 15 --noproxy "*" -o NUL -w "IPv4-only host: HTTP:%{http_code}\n" https://v4.ident.me/参数解释
| 参数 | 含义 |
|---|---|
--ssl-no-revoke | 跳过证书吊销检查(Windows curl 参数) |
-m 15 | 限时 15 秒 |
--noproxy "*" | 强制直连 |
-o NUL | 丢弃正文 |
-w | 输出带前缀的状态码 |
目标v4.ident.me只有 A 记录,只能走 IPv4。
curl -sk --ssl-no-revoke -m 15 --noproxy "*" -o NUL -w "IPv6-only host: HTTP:%{http_code}\n" https://v6.ident.me/参数解释:参数与上一条完全相同;目标v6.ident.me只有 AAAA 记录,只能走 IPv6。
判读
| IPv4-only 主机 | IPv6-only 主机 | 结论 |
|---|---|---|
| 200 | 200 | 双栈 |
| 200 | 000 | 仅 IPv4 |
| 000 | 200 | 仅 IPv6 |
| 000 | 000 | 链路不通 |
5. CF 节点主要检测命令
检测 CF 节点是否失效,核心思路是逐层排查:DNS → TCP 端口 → TLS 握手 → SNI 封锁。
5.1 基础连通性
curl --noproxy "*" -4 -sS -o NUL -w "HTTP:%{http_code}\n" -m 12 https://<你的CF域名>/参数解释
| 参数 | 含义 |
|---|---|
--noproxy "*" | 禁止走代理,强制直连 |
-4 | 强制只走 IPv4 |
-sS | -s静默 +-S保留错误信息 |
-o NUL | 丢弃响应正文 |
-w "HTTP:%{http_code}\n" | 只输出状态码 |
-m 12 | 限时 12 秒 |
结果:200可用;000失败,需逐层往下排查。
5.2 DNS 查询(换公共 DNS 排除污染)
nslookup -type=A <你的CF域名> 223.5.5.5 nslookup -type=A <你的CF域名> 8.8.8.8参数解释
| 参数 | 含义 |
|---|---|
nslookup | 系统自带 DNS 查询工具 |
-type=A | 只查 A 记录(IPv4 地址) |
-type=AAAA | 只查 AAAA 记录(IPv6 地址) |
| 最后的 IP | 指定用这个公共 DNS 查询,不写则用本机默认 |
5.3 TCP 端口探测
Test-NetConnection-ComputerName <你的CF域名>-Port 443参数解释
| 参数 | 含义 |
|---|---|
Test-NetConnection | PowerShell 自带网络测试命令,无需安装 |
-ComputerName | 要测试的主机名或 IP |
-Port | 要测试的端口 |
看TcpTestSucceeded | True= 端口能建连;False= 端口不通 |
别看PingSucceeded | ping 走 ICMP,与 TCP 是两条路,不可互推 |
5.4 TLS 层测试
curl --noproxy "*" -4 -sv -o NUL -m 12 https://<你的CF域名>/参数解释
| 参数 | 含义 |
|---|---|
-v | verbose 详细模式,打印完整连接过程 |
--noproxy "*" | 强制直连 |
-4 | 强制 IPv4 |
-o NUL | 丢弃正文 |
-m 12 | 限时 12 秒 |
| 正常结果 | 输出HTTP/1.1 200或 301/302 |
| TLS 失败 | 出现Recv failure: Connection was reset→ 疑似 SNI 封锁 |
5.5 SNI 对照实验(核心)
固定 IP,只换 SNI 里的域名,看结果是否翻转:
curl.exe --noproxy "*" -4 -sS -o NUL -w "A=http=%{http_code}\n" --resolve <你的CF域名>:443:<CF的IP> https://<你的CF域名>/ curl.exe --noproxy "*" -4 -sS -o NUL -w "B=http=%{http_code}\n" --resolve <另一个CF域名>:443:<CF的IP> https://<另一个CF域名>/ curl.exe --noproxy "*" -4 -sS -o NUL -w "C=http=%{http_code}\n" --resolve www.cloudflare.com:443:<CF的IP> https://www.cloudflare.com/参数解释
| 参数 | 含义 |
|---|---|
curl.exe | 明确调用真正的 curl(PowerShell 里curl是别名,参数不同) |
--resolve 域名:443:IP | 把域名强行解析到同一 IP,唯一变量只剩 SNI |
-w "A=http=%{http_code}\n" | 输出带标记的状态码,便于区分三条结果 |
| 其余参数 | 强制直连、强制 IPv4、静默保留错误、丢弃正文 |
判读
| A(你的域名) | B(同类域名) | C(干净域名) | 结论 |
|---|---|---|---|
| 000 | 200 | 200 | A 的 SNI 被针对性封锁 |
| 000 | 000 | 200 | 该 IP 整体有问题 |
| 000 | 000 | 000 | 本机网络出口有问题 |
| 200 | 200 | 200 | 全部正常 |
6. 通用测试模板(修改位置已标中文)
强制 IPv4 / IPv6
curl -sk4 --max-time 10 --noproxy "*" -o NUL -w "forced IPv4: HTTP:%{http_code} IP:%{remote_ip}\n" https://<要测的域名>/ curl -sk6 --max-time 10 --noproxy "*" -o NUL -w "forced IPv6: HTTP:%{http_code} IP:%{remote_ip}\n" https://<要测的域名>/参数解释:-4只查 A 记录只走 IPv4,-6只查 AAAA 记录只走 IPv6,都是硬性限定、失败不会回退;其余参数同上,%{remote_ip}可验证是否真走了指定地址族。
指定 IP 绕过 DNS
curl -sk --max-time 10 --noproxy "*" --resolve "<要测的域名>:443:<IPv4地址>" -o NUL -w "HTTP:%{http_code} IP:%{remote_ip}\n" https://<要测的域名>/ curl -sk --max-time 10 --noproxy "*" --resolve "<要测的域名>:443:[<IPv6地址>]" -o NUL -w "HTTP:%{http_code} IP:%{remote_ip}\n" https://<要测的域名>/参数解释:--resolve "域名:443:IP"不查 DNS、直接把解析结果写死为指定 IP;IPv6 地址要加方括号;其余参数同上。
指定 IP 并强制地址族
curl -sk4 --max-time 10 --noproxy "*" --connect-to <要测的域名>:443:<IPv4地址>:443 -o NUL -w "HTTP:%{http_code} IP:%{remote_ip}\n" https://<要测的域名>/ curl -sk6 --max-time 10 --noproxy "*" --connect-to <要测的域名>:443:[<IPv6地址>]:443 -o NUL -w "HTTP:%{http_code} IP:%{remote_ip}\n" https://<要测的域名>/参数解释:--connect-to 域名:443:IP:443在 TCP 层把拨号目标换成指定 IP,但 SNI / Host 仍是原域名;叠加-4/-6同时锁定地址族,是严格程度最高的对照写法。
7. IPv6 本地地址 ≠ 公网 IPv6 出口
IPv6 地址按用途分为几类:
| 类型 | 前缀 | 能否访问公网 |
|---|---|---|
| 链路本地地址 | fe80::/10 | ❌ 只在同一局域网内通信 |
| 唯一本地地址 | fc00::/7(常见fd00::/8) | ❌ 类似 IPv4 私网地址 |
| 全球单播地址 | 2000::/3 | ✅ 真正的公网 IPv6 |
ipconfig里看到fe80::开头的链路本地地址,或 VMware/VirtualBox 虚拟网卡分配的 IPv6,并不代表本机能访问 AAAA-only 网站,因为这些地址只在本地网段有效,无法穿过路由器到达公网。
真正能用的 IPv6 必须同时满足:① 属于全球单播地址(2xxx::或3xxx::开头);② 运营商或上级网络确实把 IPv6 流量路由到公网。判断标准:
curl -sk6 --noproxy "*" https://v6.ident.me/参数解释:-6强制只走 IPv6,-s静默,-k跳过证书校验,--noproxy "*"强制直连。能返回 200 才说明本机可以访问 AAAA-only 网站。
8. DNS 查询命令(通用版)
nslookup -type=A <要查的域名> nslookup -type=AAAA <要查的域名> nslookup -type=A <要查的域名> 1.1.1.1 nslookup -type=AAAA <要查的域名> 1.1.1.1参数解释
| 参数 | 含义 |
|---|---|
-type=A | 只查 A 记录(IPv4 地址) |
-type=AAAA | 只查 AAAA 记录(IPv6 地址) |
| 最后的 IP | 指定使用的 DNS 服务器,不写则用本机默认 |
结果:正常返回对应 IP;提示"没有可以使用的 address (A)记录"则说明无 A 记录(AAAA 同理)。
为什么要指定公共 DNS
本地 DNS 可能被污染、缓存错误或劫持,换1.1.1.1/8.8.8.8/223.5.5.5等公共 DNS 再查一次:
| 情况 | 结论 |
|---|---|
| 结果一致 | 域名记录本身就是这样 |
| 结果不一致 | 本地 DNS 有问题 |