Intellij/Gradle 企业代理同步失败

Intellij/Gradle sync fails behind Corporate proxy

我在公司防火墙 (Zscaler) 后面,它用自己的证书重写 TLS 流量。

当我尝试在 intellij 中创建一个 Gradle 项目时,我收到以下错误,即使在将 CA 和中间证书导入到 Intellij(通过 Server Certificates 设置页面)和我能想到的每个 Java 个信任商店。

Sync Failed
Download https://services.gradle.org/distributions/gradle-4.0-bin.zip   797ms
Cause: unable to find valid certification path to requested target

我什至将它们导入 Intellij 的私有 JRE,例如

C:\Progra~1\Java\jdk1.8.0_131\bin\keytool.exe -importcert -alias zscaler_root_ca     -keystore C:\Progra~1\Java\jdk1.8.0_131\jre\lib\security\cacerts -storepass changeit -file zscaler_root_ca.crt
C:\Progra~1\Java\jre1.8.0_151\bin\keytool.exe -importcert -alias zscaler_root_ca     -keystore C:\Progra~1\Java\jre1.8.0_151\lib\security\cacerts -storepass changeit -file zscaler_root_ca.crt
"C:\Users\jonathan.bates\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-03.4301.25\jre64\bin\keytool.exe" -importcert -alias zscaler_root_ca     -keystore "C:\Users\jonathan.bates\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-03.4301.25\jre64\lib\security\cacerts" -storepass changeit -file zscaler_root_ca.crt

我还需要做其他事情吗?

我将设置更新为 Auto Import Certificate,它对我有用

Settings -> Tools -> Server Certificates -> Check the box for auto import

公司颁发的证书需要包含在 Gradle 使用的信任库中。对此进行故障排除可能很困难,尤其是当您安装了 Java 的多个版本并安装了 JRE 时。首先要确定的是 JRE Gradle 使用的是什么。有一个答案指出问题已通过使用 Gradle Wrapper 解决。 Gradle Wrapper calls the project specific Java environment which is defined in gradle.properties. By default, it is set to distributionBase=GRADLE_USER_HOME. To get Gradle to build with untrusted certificates one can follow the instructions in the documentation:

The SSL certificate for the HTTP build cache backend may be untrusted since it is internally provisioned or a self-signed certificate.

In such a scenario, you can either configure the build JVM environment to trust the certificate, or set this property to true to disable verification of the server's identity.

Allowing communication with untrusted servers keeps data encrypted during transmission, but makes it easier for a man-in-the-middle to impersonate the intended server and capture data.

最好将证书导入 Gradle 使用的 JVM,这看起来就像您尝试做的那样。如果您希望 IntelliJ 了解公司证书,您可以通过 UI 导航到设置 > 工具 > 服务器证书来导入这些证书。导入您的组织颁发的证书文件并重试构建。

多半与证书有关。要验证这一点,删除选项 accepted certificates 并选中“自动接受不受信任的证书”可能会解决问题。正如@Colm Bhandal 评论的那样,它不是解决方案,而是解决方案。

Do I need to be doing anything else?

是的,可能吧。 JAVA_HOME是一个变量Gradle看着选择Java执行它。 一旦您拥有 Java 及其包含所需证书的信任库,请尝试将 JAVA_HOME 设置为该目录。

对我来说,每个设置似乎都是正确的,上面提到的要检查。 我不知道为什么,但是错误消息:unable to find valid certification path to requested target 消失并且 gradle build 在升级项目的 Gradle 包装器后开始工作: https://docs.gradle.org/6.8.1/userguide/gradle_wrapper.html

关键操作是在“终端”选项卡中 运行 gradlew.bat

修复:将 ZScaler 根证书放入 IJ

  1. 打开GoogleChrome
  2. 转到设置 -> 安全 -> 管理证书
  3. 转到“受信任的根证书颁发机构”选项卡
  4. 向下滚动到“ZScaler Root CA”项 - 作为“Z”字,它可能位于列表底部附近或底部
  5. 点击“导出...”
  6. 按照向导的步骤将证书导出为 .CER 文件并将其保存到计算机上的某个位置
  7. 现在打开 IntelliJ (IJ)
  8. 打开设置(Ctrl+Alt+S)
  9. 搜索“证书”以过滤设置并转到“服务器证书”
  10. 点击小 + 图标
  11. 浏览到您刚刚保存的文件,然后在设置中再次点击“确定”和“确定”

应该可以了。

注意: 假设您使用 Google Chrome ZScaler 根证书已经存储在 Chrome 的信任库中.如果您不是这种情况,希望您能找到另一种获取 ZScaler 根证书的方法。最坏的情况:您可以随时询问您的 IT 部门。我确定谁是管理 ZScaler 的人,应该知道如何为您获取证书。

更详细的讨论

这似乎是 IntelliJ (IJ) 的一个普遍问题,不仅针对 Gradle 任务,而且当 IJ 尝试连接到任何 HTTPS 站点时,正如 [=12= 的评论所指出的那样]:

intellij uses a different secret store to your terminal.

扩展该评论​​,我们注意到 JetBrains documentation

IntelliJ IDEA provides its own storage for trusted certificates.

现在,根据该 JetBrains 文档和 ,一种可行的方法是简单地自动接受所有不受信任的证书。要理解为什么这是一个 OK 方法,我们记得整个问题首先是由 ZScaler 背后造成的。由于你在 ZScaler 后面,你可以相信拦截你所有请求的 ZScaler 中间服务器会为你阻止任何不可信的站点,所以你不需要在 IJ 中担心它。换句话说,当 ZScaler 将这些证书转发给 IJ 时,您已经可以信任它们了。

但是,当您的组织允许您禁用 ZScaler 时,该方法就会出现问题。在这种情况下,如果您禁用 ZScaler,那么您将不再受到它的保护。当你这样做时,你会记得恢复你的 IJ 设置吗?也许吧,但这样做会是一个可怕的体力负担。更有可能的是,您可能不会记得,然后您的 IJ 可能会连接到不可信的站点。我不知道完整的安全细节,所以也许采取了一些其他措施来缓解这种漏洞,但从表面上看,这对我来说似乎是一个漏洞。例如,攻击者可能会设置一个虚假的更新站点来更新您的某个 IntelliJ 插件,然后安装一个恶意插件,而您甚至都不知道。现在你的机器上实际上已经感染了病毒,因为每当你 运行 IJ 时,插件 运行 也会出现,并且可能会做各种坏事。

因此,更安全的方法是找到问题的根源,从字面上看:找到 ZScaler 根证书并将其添加到 IJ 信任库中。然后 IJ 可以信任该证书,以及 ZScaler 在拦截您的流量时颁发的任何下游证书。

为什么是根证书?

值得一提的是,您添加的根证书与IJ在您遇到问题时警告您的证书不同。例如。当我尝试“检查更新”时,导致问题的证书被颁发给“*.google.com”。我相信这些只是 ZScaler 在拦截您的流量时创建的拦截器证书。 ZScaler 使用 Google 的真实证书与 Google 进行通信。 “代理”证书是 ZScaler 生成的与您的机器对话的证书。由于 ZScaler 必须为所有可以想象的站点生成这样的代理证书,因此仅将它们添加到 IJ 中的信任库是不够的。不仅如此,这些代理证书的保质期似乎很短——我看到的那个在两周后就过期了。因此,您必须不断将它们重新添加到 IJ 信任库中。然后 IJ 信任库就会被 ZScaler 创建的所有这些临时证书弄得乱七八糟。这就是您要添加根证书的原因。我相信它充当任何分发的临时代理证书的最终签署机构。而我看到的那个 20 多年都不会过期。所以我不认为自己必须 fiddle 再次使用 IJ 设置一段时间。

备注

本质上,此答案中给出的修复实际上与 相同,但我正在扩展如何从 Google Chrome 设置中实际获取 ZScaler 证书,我会讨论我们为什么要做我们正在做的事情,以及与替代方案的比较。