[{"data":1,"prerenderedAt":396},["ShallowReactive",2],{"post-zh-macos-auto-proxy-discovery-tailscale":3,"surround-zh-blog\u002Fzh\u002Fblog\u002Fmacos-auto-proxy-discovery-tailscale.md":389},{"id":4,"title":5,"body":6,"canonical":33,"category":370,"date":371,"description":372,"extension":373,"image":374,"meta":375,"navigation":376,"path":377,"seo":378,"slug":379,"status":380,"stem":381,"tags":382,"translationSlug":379,"__hash__":388},"blog\u002Fzh\u002Fblog\u002Fmacos-auto-proxy-discovery-tailscale.md","Mac 排错实录：为什么一个叫「自动代理发现」的开关，会让你的 Tailscale 频频超时？",{"type":7,"value":8,"toc":358},"minimark",[9,14,23,26,37,43,50,53,80,83,87,90,124,127,136,139,145,152,154,158,161,166,169,184,187,193,196,200,203,217,220,240,244,247,253,256,258,262,329,331,335,354],[10,11,13],"h2",{"id":12},"_1-起因与结论先行","1. 起因与结论先行",[15,16,17,18,22],"p",{},"今天在 macOS 上折腾 Shadowrocket 的内置 Tailscale 模块时，碰到了一个非常奇怪的现象：",[19,20,21],"strong",{},"同样的 Tailscale 账号和节点配置，在 iPhone 上能够秒连，但在 Mac 上状态始终卡在「未连接」","。",[15,24,25],{},"打开 Shadowrocket 的 VPN 诊断日志，每次启动内置 Tailscale 模块，5 秒后都会抛出一模一样的报错：",[27,28,34],"pre",{"className":29,"code":31,"language":32,"meta":33},[30],"language-text","failed to fetch control server key: 请求超时。\ncontrol server key fetch failed\n","text","",[35,36,31],"code",{"__ignoreMap":33},[15,38,39,40,22],{},"先给结论：",[19,41,42],{},"问题不在代理节点，也不在 Tailscale 服务端，而是 macOS 的 Wi-Fi 设置里默认开启了「自动代理发现」（Auto Proxy Discovery \u002F WPAD）",[15,44,45,46,49],{},"在家庭 Wi-Fi 或热点环境下，开启这个选项会导致 macOS 的底层网络库（",[35,47,48],{},"NSURLSession","）在发起握手前，强行在局域网内寻找并不存在的 PAC 代理脚本。这一阶段恰好会白白阻塞 5 秒直到报错，从而把 Tailscale 客户端的公钥获取请求硬生生拖到超时。",[15,51,52],{},"在终端执行一行命令将其关闭后，Tailscale 瞬间恢复毫秒级连接：",[27,54,58],{"className":55,"code":56,"language":57,"meta":33,"style":33},"language-sh shiki shiki-themes github-dark","networksetup -setproxyautodiscovery Wi-Fi off\n","sh",[35,59,60],{"__ignoreMap":33},[61,62,65,69,73,77],"span",{"class":63,"line":64},"line",1,[61,66,68],{"class":67},"svObZ","networksetup",[61,70,72],{"class":71},"sDLfK"," -setproxyautodiscovery",[61,74,76],{"class":75},"sU2Wk"," Wi-Fi",[61,78,79],{"class":75}," off\n",[81,82],"hr",{},[10,84,86],{"id":85},"_2-核心认知为什么之前的思路走不通","2. 核心认知：为什么之前的思路走不通",[15,88,89],{},"排查初期，我按常规经验试了两个方向，但都走了弯路：",[91,92,93,100,114],"ol",{},[94,95,96,99],"li",{},[19,97,98],{},"怀疑是 Tailscale Auth Key 过期","：在 Tailscale 控制台检查密钥状态，虽然旧 Key 确实需要保持有效，但此时连服务器公钥都没拉下来，根本还没走到服务端校验 Key 的阶段。",[94,101,102,105,106,109,110,113],{},[19,103,104],{},"怀疑是 DNS 虚拟 IP 污染","：Shadowrocket 通常会将域名解析为 198.18.x.x 的保留地址用于路由接管。我在配置中给 ",[35,107,108],{},"controlplane.tailscale.com"," 加上了 ",[35,111,112],{},"always-real-ip","，DNS 也确实拿到了公网 IP，但启动仍然固定在 5 秒后超时。",[94,115,116,119,120,123],{},[19,117,118],{},"命令行 curl 正常，迷惑性极强","：在终端单独执行 ",[35,121,122],{},"curl https:\u002F\u002Fcontrolplane.tailscale.com\u002Fkey","，几乎瞬间就能拿到响应，甚至在普通浏览器里访问也畅通无阻。",[15,125,126],{},"为什么命令行 curl 能通，而 Shadowrocket 内置的 Tailscale 却报超时？",[15,128,129,130,133,134,22],{},"关键在于运行上下文的不同：普通 curl 走的是标准用户态进程网络栈；而 Shadowrocket 在 macOS 上是以 ",[35,131,132],{},"MacPacketTunnel","（Network Extension）系统扩展运行的，其内部初始化 Tailscale 时调用了系统的 ",[35,135,48],{},[15,137,138],{},"通过读取 macOS unified log 的详细日志，终于捕获到了真凶：",[27,140,143],{"className":141,"code":142,"language":32,"meta":33},[30],"MacPacketTunnel: proxy:start_resolve\nMacPacketTunnel: unresolved proxies, waiting for resolution\nMacPacketTunnel: nw_proxy_resolver_create_parsed_array [C11.1.1 proxy pac] Evaluation error: NSURLErrorDomain: -1003\n",[35,144,142],{"__ignoreMap":33},[15,146,147,148,151],{},"请求刚发出去，根本还没碰到底层 TCP 握手，就被系统拦下来去执行 WPAD 代理自动发现了。在普通宽带环境下，局域网根本没有配置 WPAD 服务器，系统只能干等 5 秒超时，抛出 ",[35,149,150],{},"-1003"," 错误后才放弃。而 Tailscale 获取公钥的超时预算刚好也是 5 秒，直接被整整耗死。",[81,153],{},[10,155,157],{"id":156},"_3-完整复现步骤","3. 完整复现步骤",[15,159,160],{},"如果你也遇到了类似的神秘 5 秒超时，可以通过以下确定性步骤进行检查与修复。",[162,163,165],"h3",{"id":164},"step-1-检查-wi-fi-的自动代理发现状态","Step 1: 检查 Wi-Fi 的自动代理发现状态",[15,167,168],{},"打开终端，执行：",[27,170,172],{"className":55,"code":171,"language":57,"meta":33,"style":33},"networksetup -getproxyautodiscovery Wi-Fi\n",[35,173,174],{"__ignoreMap":33},[61,175,176,178,181],{"class":63,"line":64},[61,177,68],{"class":67},[61,179,180],{"class":71}," -getproxyautodiscovery",[61,182,183],{"class":75}," Wi-Fi\n",[15,185,186],{},"如果输出为：",[27,188,191],{"className":189,"code":190,"language":32,"meta":33},[30],"Auto Proxy Discovery: On\n",[35,192,190],{"__ignoreMap":33},[15,194,195],{},"说明该网络接口开启了自动代理探测。",[162,197,199],{"id":198},"step-2-命令行关闭自动代理发现","Step 2: 命令行关闭自动代理发现",[15,201,202],{},"无需重启电脑，直接在终端执行：",[27,204,205],{"className":55,"code":56,"language":57,"meta":33,"style":33},[35,206,207],{"__ignoreMap":33},[61,208,209,211,213,215],{"class":63,"line":64},[61,210,68],{"class":67},[61,212,72],{"class":71},[61,214,76],{"class":75},[61,216,79],{"class":75},[15,218,219],{},"再次核对状态：",[27,221,223],{"className":55,"code":222,"language":57,"meta":33,"style":33},"networksetup -getproxyautodiscovery Wi-Fi\n# 预期输出：Auto Proxy Discovery: Off\n",[35,224,225,233],{"__ignoreMap":33},[61,226,227,229,231],{"class":63,"line":64},[61,228,68],{"class":67},[61,230,180],{"class":71},[61,232,183],{"class":75},[61,234,236],{"class":63,"line":235},2,[61,237,239],{"class":238},"sAwPA","# 预期输出：Auto Proxy Discovery: Off\n",[162,241,243],{"id":242},"step-3-重载模块验证效果","Step 3: 重载模块验证效果",[15,245,246],{},"回到 Shadowrocket 中，将 Tailscale 模块重新开关一次。查看诊断日志，原先卡顿 5 秒的环节瞬间变为：",[27,248,251],{"className":249,"code":250,"language":32,"meta":33},[30],"tailscale_client_new: initialised\ntailscale: connected to network\n",[35,252,250],{"__ignoreMap":33},[15,254,255],{},"状态立即变为“已连接”，整个握手耗时从超时失败变为毫秒级通过。",[81,257],{},[10,259,261],{"id":260},"_4-踩坑记录与排错清单","4. 踩坑记录与排错清单",[263,264,265,281],"table",{},[266,267,268],"thead",{},[269,270,271,275,278],"tr",{},[272,273,274],"th",{},"现象 \u002F 假象",[272,276,277],{},"真实原因",[272,279,280],{},"正确应对",[282,283,284,303,314],"tbody",{},[269,285,286,294,300],{},[287,288,289,290,293],"td",{},"终端 ",[35,291,292],{},"curl"," 顺畅，但应用内部请求超时",[287,295,296,297,299],{},"curl 不一定触发系统的 WPAD 异步代理查找，而 Extension \u002F App 内的 ",[35,298,48],{}," 严格遵循系统代理查找流程",[287,301,302],{},"不要只用 curl 下结论，排查 Extension 问题需结合系统 unified log",[269,304,305,308,311],{},[287,306,307],{},"怀疑是本地代理软件把流量阻断了",[287,309,310],{},"WPAD 是「向局域网索取代理脚本」的协议，与本地运行的 HTTP\u002FSOCKS 代理并不冲突",[287,312,313],{},"关闭 WPAD 仅停止局域网广播，现有代理分流规则不受任何影响",[269,315,316,323,326],{},[287,317,318,319,322],{},"报错 ",[35,320,321],{},"invalid key"," 与超时混杂",[287,324,325],{},"之前可能存在过期 Auth Key 与 WPAD 超时的双重问题叠加",[287,327,328],{},"先解决网络层的 5 秒超时，再核对 Tailscale 控制台有效的 Reusable Auth Key",[81,330],{},[10,332,334],{"id":333},"_5-小结与适用边界","5. 小结与适用边界",[336,337,338,348],"ul",{},[94,339,340,343,344,347],{},[19,341,342],{},"最佳适用场景","：个人 MacBook、家用网络、移动办公热点，以及本机常驻 Shadowrocket、Surge 或 Clash 等分流工具的开发环境。在这些场景下，系统默认的「自动代理发现」不仅毫无用处，反而经常成为阻断特定网络组件（尤其是 Network Extension）的隐形杀手，保持 ",[35,345,346],{},"Off"," 是最推荐的设定。",[94,349,350,353],{},[19,351,352],{},"不适用场景","：部分跨国企业或大型高校内网，若网络管理员明确通过 DHCP Option 252 统一下发内部代理分流策略，则关闭后可能会导致部分内网资源无法访问。即便是这类环境，通常也建议由管理员直接提供固定的 PAC URL（自动代理配置）手动填入，而不是开启全网广播发现。",[355,356,357],"style",{},"html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}",{"title":33,"searchDepth":235,"depth":235,"links":359},[360,361,362,368,369],{"id":12,"depth":235,"text":13},{"id":85,"depth":235,"text":86},{"id":156,"depth":235,"text":157,"children":363},[364,366,367],{"id":164,"depth":365,"text":165},3,{"id":198,"depth":365,"text":199},{"id":242,"depth":365,"text":243},{"id":260,"depth":235,"text":261},{"id":333,"depth":235,"text":334},"coder","2026-11-08","排查 macOS 上 Shadowrocket 内置 Tailscale 频繁报错请求超时的全过程：定位 NSURLSession 阻塞在 WPAD 代理自动发现（-1003）的底层机制，以及一键终端修复命令。","md",null,{},true,"\u002Fzh\u002Fblog\u002Fmacos-auto-proxy-discovery-tailscale",{"title":5,"description":372},"macos-auto-proxy-discovery-tailscale","publish","zh\u002Fblog\u002Fmacos-auto-proxy-discovery-tailscale",[383,384,385,386,387],"macOS","Tailscale","Shadowrocket","Network","WPAD","uMmKmFG55sdZE9mD4MltgCMyQn4EBGuivdA4xNzHePM",[374,390],{"title":391,"path":392,"stem":393,"slug":394,"date":395,"children":-1},"找回 Chrome 消失的「Ask Gemini」：修改 Local State 避坑指南与底层机制","\u002Fzh\u002Fblog\u002Frestore-chrome-ask-gemini-by-modifying-local-state","zh\u002Fblog\u002Frestore-chrome-ask-gemini-by-modifying-local-state","restore-chrome-ask-gemini-by-modifying-local-state","2026-11-05",1794153561173]