错误报告 标题 Clash sniff-tls-sni 开启时导致 Gradle/Fabric 依赖下载异常,表现为 Maven/Fabric 仓库 TLS 握手失败 环境信息 - 主机代理:Clash,mixed-port: 7890 - 构建环境:WSL/Linux 子环境 - 构建工具:Gradle 9.2.1 - Mod 工具链:Fabric Loom 1.15.4 - Java:21 - 相关 Clash 配置变更: - 早期:dns.enhanced-mode: fake-ip,experimental.sniff-tls-sni: true - 当前可用:dns.enhanced-mode: redir-host,experimental.sniff-tls-sni: false 问题描述 在使用 Clash 作为主机代理、WSL 通过 127.0.0.1:7890 出网的环境中,Gradle 构建 Fabric 项目时出现网络相关构建失败。失败并非 Java 编译慢或 javac 性能问题,而是依赖解析和构建前置下载阶段异常中断。 该问题在 redir-host + sniff-tls-sni=false 后恢复正常,说明根因与 Clash 的 TLS SNI 嗅探行为高度相关。 具体错误表现 构建期间出现以下典型报错: - Gradle/Fabric 依赖解析失败: - Could not resolve all files for configuration ':modImplementation' - Could not resolve net.fabricmc:fabric-loader:0.18.4 - Could not resolve net.fabricmc.fabric-api:... - 具体网络错误: - Could not GET 'https://maven.fabricmc.net/...pom' - The server may not support the client's requested TLS protocol versions: (TLSv1.2, TLSv1.3) - Remote host terminated the handshake - 早期阶段还出现过: - Network is unreachable - Could not GET 'https://plugins.gradle.org/... - Could not GET 'https://plugins-artifacts.gradle.org/... - Loom 还有一个次要提示: - Previous process has disowned the lock due to abrupt termination - Found existing cache lock file ..., rebuilding loom cache 这说明之前有异常终止留下缓存锁,但这不是主因,只是连带现象。 什么是通的,什么是不通的 问题配置下的网络表现可以分成几类: - 本地代理端口可达: - 127.0.0.1:7890 是通的 - 通过代理访问部分站点是通的: - downloads.gradle.org 可通 - Gradle wrapper zip 下载可成功 - curl 通过代理访问部分 Maven/Fabric 资源可成功 - 普通 JDK HttpURLConnection 通过代理访问 Maven/Fabric 资源也可成功 - Gradle 自身访问特定仓库时不通: - maven.fabricmc.net 通过 Gradle 解析依赖时经常失败 - repo.maven.apache.org 在 Gradle 某些阶段也出现 TLS EOF / handshake termination - plugins.gradle.org / plugins-artifacts.gradle.org 早期阶段出现过失败 - 在 fake-ip 模式下,DNS 表现异常但这不是最终主因: - 域名会解析成 198.18.0.x - 这是 Clash fake-ip-range: 198.18.0.1/16 的正常表现 - --noproxy 直连时常超时 - IPv6 为 Network is unreachable 这些现象说明 fake-ip 会干扰排障,但最终导致 Gradle 失败的关键触发点不是 fake-ip 本身,而是 TLS 路径上的兼容性问题 原因分析 根据现象和配置切换结果,高置信判断如下: - fake-ip 会让 WSL/Java/Gradle 这类开发环境看到虚假的 198.18.0.x 地址,增加排障噪声,但不是最终唯一根因。 - 真正导致构建失败的关键因素是 experimental.sniff-tls-sni: true。 - 当 TLS SNI 嗅探开启时,Gradle 的 HTTPS/TLS 请求在访问 maven.fabricmc.net 等仓库时会被对端提前中止,表现为: - Remote host terminated the handshake - SSLHandshakeException - EOFException - 这不是“整个代理坏了”,因为: - 本地代理端口是通的 - curl 可通 - 普通 JDK HTTP 请求可通 - Gradle wrapper 下载也可通 - 因此问题更像是: - Clash 的 TLS SNI 嗅探 - 当前代理出口链路 - Gradle 使用的 HTTP/TLS 客户端栈 三者组合后出现兼容性问题。 解决结果 将 Clash 调整为以下状态后,构建恢复正常: - dns.enhanced-mode: redir-host - experimental.sniff-tls-sni: false 其中: - redir-host 的作用是减少 fake-ip 对开发环境的干扰 - sniff-tls-sni: false 是本次问题恢复正常的关键变更 结论 本问题不是项目依赖版本错误,也不是 Java 编译性能问题,而是代理层网络行为导致的 Gradle TLS 握手异常。 最终结论如下: - fake-ip 会放大 WSL/Gradle 排障复杂度 - sniff-tls-sni: true 会导致 Gradle 访问 Fabric/Maven 仓库时出现 TLS 握手失败 - 在本环境下,redir-host + 关闭 sniff-tls-sni 是有效修复方案