Hysteria2 默认仿 Chrome 时,quic-go 把空闲上限改回 30 秒,更长的 idle_timeout 留不住。只关开关、不另写大于 0 的时间,另一处默认仍是 30 秒。这不是封号。当天没有建立隧道。
OpenAI、Anthropic 和 Google 都没有把中国大陆写成这些产品的无条件服务地。从名单外访问可能违反条款,账号可能被限制或停用。改空闲时间不改变名单。本文不写伪造证件、购买或借用账号、手机号和支付卡,也不写如何调整握手外观。起草环境不是大陆宽带。
先把两种 30 秒分开
一个可单独引用的区分:路由规则上的 udp_timeout 关掉的是核心里的 UDP 关联;这里的 30 秒是 Hysteria2 这条 QUIC 连接自己的空闲上限。数字相同,不是同一个计时器。
| 你看到的 | 更像哪一层 | 不要先做的事 |
|---|---|---|
| 出站类型是 hysteria2,长连接在没有新区数据时结束 | QUIC 的 MaxIdleTimeout | 不要先改 AI 账号 |
| 日志里被嗅探成 quic 的 UDP 大约 30 秒被核心关掉 | 规则动作的 udp_timeout | 不要用那一页解释本页的 idle_timeout |
| 页面已经写出国家、地区或 territory | 对方的名单 | 不要加长空闲再试 |
| 握手失败,服务器证书是 Ed25519 | 仿 Chrome 的签名算法列表 | 不要把它记成地区英文 |
规则动作那一处默认值见 大陆代理连上后仍失败。保活和「显示已连接但路径已死」的差别见 VPN 保活与掉线重连。
文档写的是钉死,代码里有两次赋值
2026-11-08 的 GitHub Releases API 仍把最新非预发布标为 v1.14.4,published_at 为 2026-10-24T01:04:25Z。linux-amd64 二进制的修订是 c005f35300ce76427dc285481ec5695f5b179cd2。该标签 go.mod 里的 github.com/sagernet/sing-quic 是 v0.7.2-0.20261020082049-7e0a5869a5f4。同一文件里的 github.com/sagernet/quic-go 是 v0.61.0-sing-box-mod.12,模块代理给出的提交是 80c132feb2112b5d0d88d02f941b1e68e56a2722,时间 2026-10-22T06:27:24Z。
标签 docs/configuration/outbound/hysteria2.md 写:没有关闭仿 Chrome 时,idle_timeout 被固定为 30 秒,max_concurrent_streams 和 initial_packet_size 也被换掉。同一段写,Chrome 不声明支持 Ed25519,服务器若用 Ed25519 证书,握手会失败,应改用 ECDSA 或 RSA。disable_chrome_parrot 的结构示例是 false。
同一标签的 protocol/hysteria2/outbound.go 在 TLS 未启用时返回错误;当天 check 对缺少 tls 的出站退出码为 1,原文是 initialize outbound[0]: TLS required。同一文件把 ChromeParrot 设为 !DisableChromeParrot,因此 JSON 里省略这个布尔值时,仿 Chrome 是打开的。它把配置里的 IdleTimeout 放进 QUIC 选项,但那一步还不是最终值。
sing-quic 的 hysteria/protocol.go 把 DefaultMaxIdleTimeout 写成 30 * time.Second,把 DefaultKeepAlivePeriod 写成 10 * time.Second。hysteria2/client.go 的 NewClient 先用这两个常数填进 quic.Config,再调用 ApplyQUICOptions。quic.go 里,只有 IdleTimeout > 0 才覆盖空闲,只有 KeepAlivePeriod > 0 才覆盖保活。
quic-go 的 config.go 在 ChromeParrot 为真时执行 idleTimeout = chromeMaxIdleTimeout。chrome_parrot.go 把该常数写成 30 * time.Second,旁边的注释是:Chrome 钉死这些值,调用方要求的任何值都会被覆盖。因此:
- 仿 Chrome 开着时,JSON 里的
idle_timeout即使通过了check,也会在populateConfig被改回 30 秒。 - 仿 Chrome 关着、又没有写大于 0 的
idle_timeout时,NewClient留下的仍是那 30 秒常数。 - 两处都做了,本地值才会留下来:
disable_chrome_parrot为true,并且idle_timeout大于 0。
connection.go 的 applyTransportParameters 再取本地空闲和对端宣告值的较小者。同函数把保活间隔设为 min(KeepAlivePeriod, idleTimeout/2)。对端可以报一个更短的空闲。保活包算不算「入站网络活动」,当天没有抓包,不把 10 秒保活写成「所以不会在 30 秒断开」。
Ed25519 只核对了列表,没有做握手。internal/handshake/chrome_client_hello.go 的签名算法有 ECDSA P-256、P-384 和若干 RSA,没有 Ed25519。这和文档那句方向一致。证书到底是哪一种,以你服务器上的证书为准。
check 通过,不等于 2 分钟还在
option/http.go 的 HTTP2Options 有 idle_timeout,QUICOptions 嵌入了它,Hysteria2 出站又嵌入了 QUICOptions。所以下面的键能被解码。127.0.0.1 和这串口令不是一台可用的服务器,只为了让 check 读到字段。
{
"type": "hysteria2",
"tag": "hy2-out",
"server": "127.0.0.1",
"server_port": 443,
"password": "example-not-a-real-password",
"disable_chrome_parrot": true,
"idle_timeout": "2m",
"tls": {
"enabled": true,
"server_name": "example.com"
}
}
当天这份配置的 check 退出码是 0。拿掉 disable_chrome_parrot、只留 idle_timeout 为 2m,退出码仍是 0。check 不做 populateConfig 那一次覆盖。退出码 0 不能证明 2 分钟还在。
文档把仿 Chrome 写成让握手更像 Chrome,从而更难靠握手被认出来。那是字段存在的原因。本文只核对其对空闲和 Ed25519 的副作用,不提供混淆口令、端口跳跃或改握手外观的步骤。把空闲改长,也不等于这条 UDP 路径在你的网络上可用。UDP 和 TCP 的差别见 VPN 用 TCP 还是 UDP。
地区英文仍然停在名单上
空闲上限描述的是握手完成之后、多久没有入站网络活动就关闭连接。quic-go 的 interface.go 把 MaxIdleTimeout 写成这个意思,并写明实际值是本地和对端的较小者;零值在那份注释里也会被设成 30 秒。页面或 API 已经返回国家、地区或 territory 时,连接已经把响应带回来了,加长空闲对不上这个错误。名单的读法见 Claude 与 Gemini 的地区报错和注册 和 API、订阅与支付排查。
公开文件里的法律范围
2026-11-08 请求《关于清理规范互联网网络接入服务市场的通知》的部委网页得到 HTTP 403,正文没有打开。下面沿用该通知(工信部信管函〔2017〕32号)和 2017 年 1 月 24 日答记者问的公开表述:未经批准,不得自行建立或租用专线(含 VPN)等其他信道开展跨境经营活动;答记者问说明,对象是无国际通信业务经营资质而开展跨境电信业务经营的企业或个人,企业办公自用、向依法设置国际通信出入口局的经营者租用,不在该条针对的范围内。本文不判断某种个人使用是否违法,也不写规避执法的做法。
一次断开留下的记录
- 出站
type是不是hysteria2,以及disable_chrome_parrot是省略、false还是true。 idle_timeout的原文。仿 Chrome 仍开着时,不要把这个字符串当成运行中的空闲。- 断开前有没有 HTTP 状态或地区英文。有地区英文就不要记成空闲超时。
check的退出码。它只证明配置能被解码。