Intellij/Gradle在公司代理后同步失败

18

我在企业防火墙(Zscaler)背后,该防火墙使用自己的证书重写TLS流量。

当我尝试在Intellij中创建Gradle项目时,即使将CA和中间证书导入到Intellij(通过服务器证书设置页面)和我能想到的所有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-0\173.4301.25\jre64\bin\keytool.exe" -importcert -alias zscaler_root_ca     -keystore "C:\Users\jonathan.bates\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-0\173.4301.25\jre64\lib\security\cacerts" -storepass changeit -file zscaler_root_ca.crt

我需要做其他的事情吗?


1
我还会请求企业IT员工帮忙解决这个问题,因为他们引起了这个问题。 - C-Otto
1
不幸的是,他们不是Java/Gradle开发人员,在我的领域中,代理是不可谈判的。 - Jon Bates
至少要让这个问题变得透明,这样他们就知道代理服务器造成了多大的伤害。 - C-Otto
1
请仔细检查您使用的JRE是否正确,在关于对话框中添加了代理证书,并且该证书确实存在(keytool -list ...). 尝试在设置|工具|服务器证书中启用自动接受不受信任的证书选项。 - Andrey
6个回答

6
公司发布的证书需要包含在Gradle使用的信任库中。如果您安装了多个Java和JRE版本,则解决此问题可能会很困难。首先要确定的是Gradle使用的JRE是什么。有一个答案指出使用Gradle Wrapper可以解决这个问题。 Gradle Wrapper 调用在 gradle.properties 中定义的特定于项目的Java环境。默认情况下,它设置为distributionBase=GRADLE_USER_HOME。要使Gradle构建不受信任的证书,可以按照文档中的说明操作

由于HTTP构建缓存后端的SSL证书是内部提供或自签名证书,因此可能不受信任。

在这种情况下,您可以配置构建JVM环境以信任证书,或将此属性设置为true以禁用验证服务器的身份。

允许与不受信任的服务器通信可在传输期间加密数据,但也更容易被中间人冒充目标服务器并捕获数据。

最好将证书导入Gradle使用的JVM中,这看起来就像您尝试做的事情。如果您想让IntelliJ知道公司证书,可以通过导航到设置 > 工具 > 服务器证书来通过 UI 导入它们。导入组织颁发的证书文件,然后重新尝试构建。

1
是的 - 当我回答我的问题时,我对JVM还很陌生,所以我的答案是垃圾。我会把它删除。事实上,只是JRE没有在其信任存储中拥有正确的证书。现在已经过去很久了,但我猜我只是导入到了错误的JRE中。 - Jon Bates
Gradle出了一些问题,我不知道为什么会停止工作。从Gradle构建脚本中的“wrapper”任务切换到“gradle-wrapper.properties”文件,并在“使用Gradle”下拉菜单中进行设置,我相信这是你提到的原因。我不确定是否在某个时候已经切换了它,但这样做解决了问题。 - bdetweiler

3

这个问题可能与证书有关。为了验证这一点,可以尝试移除 accepted certificates 选项,并勾选 "Accept non-trusted certificates automatically" 选项来解决问题。正如 @Colm Bhandal 的评论所述,这不是一个解决方案,而是一个权宜之计。

enter image description here


这是一种有点危险的方法,如果你被允许断开VPN连接(就像我们一样)。这将允许一个在路径上的攻击者在你断开VPN连接后立即攻击你。你真正想要信任的只有ZScaler根证书。 - Colm Bhandal
1
是的,完全同意。增加了更多相关描述。谢谢! - jfk

2
解决方法:将ZScaler根证书放入IJ中
  1. 打开Google Chrome
  2. 进入设置 -> 安全性 -> 管理证书
  3. 进入“受信任的根证书颁发机构”选项卡
  4. 向下滚动到“ZScaler根CA”项目 - 作为“Z”字开头的单词,它可能会出现在列表的底部或附近
  5. 点击“导出…”
  6. 按照向导的步骤将您的证书导出为.CER文件,并将其保存到计算机上的某个位置
  7. 现在打开IntelliJ(IJ)
  8. 打开设置(Ctrl+Alt+S)
  9. 搜索“cert”以过滤设置并转到“服务器证书”
  10. 点击小加号图标
  11. 浏览到刚才保存的文件并点击OK和设置中的OK

就是这样。

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

更详细的讨论

这似乎是IntelliJ(IJ)的普遍问题,不仅针对Gradle任务,而且当IJ尝试连接到任何HTTPS站点时都会出现,正如此用户的评论所指出的:

intellij使用与您的终端不同的密钥库。

在该评论的基础上,我们从JetBrains文档中了解到:

IntelliJ IDEA为可信证书提供了自己的存储。

现在,从JetBrains文档和这个答案中可以得知,一种可行的方法是自动接受所有非受信任的证书。要理解为什么这是一个可行的方法,我们回想起,整个问题最初是由于处于ZScaler后面而导致的。由于您在ZScaler后面,您可以相信拦截所有请求的ZScaler中间服务器将为您阻止任何不可信站点,因此您无需在IJ中担心它。换句话说,在ZScaler将这些证书转发给IJ之前,您已经可以信任它们。

然而,这种方法的问题在于,如果您的组织允许您禁用ZScaler,则禁用ZScaler后,您将不再受到其保护。当您这样做时,您是否会记得恢复IJ设置?也许会,但这将是一项可怕的手动负担。更有可能的是,您可能不会记得,然后有可能您的IJ会连接到不可信任的站点。我不知道完整的安全细节,因此也许还采取了其他措施来减轻这种漏洞,但从表面上看,这对我来说似乎是一种漏洞。例如,攻击者可以为更新您的IntelliJ插件而设置一个虚假的更新站点,并安装一个恶意插件,而您甚至不会知道。现在您的计算机上实际上已经有了病毒,因为每次运行IJ时,插件也会运行,并且可能会做各种坏事。
因此,更安全的方法是直接解决问题:找到ZScaler根证书并将其添加到IJ信任存储中。然后,IJ可以信任该证书以及ZScaler截获您的流量时发出的任何下游证书。
为什么要添加根证书?
值得一提的是,您添加的根证书与当IJ遇到问题时警告您的证书不同。例如,当我尝试“检查更新”时,引起问题的证书是针对“*.google.com”发行的。我相信这些只是ZScaler在截获您的流量时创建的拦截器证书。Google的真实证书由ZScaler用于与Google通信。 "代理"证书是ZScaler生成以与您的计算机交互的证书。由于ZScaler必须为所有可想象的站点生成此类代理证书,因此仅将它们添加到IJ的信任存储中是不够的。而且,这些代理证书似乎具有相当短的有效期-我看到的那个证书在两周后过期。因此,您必须不断地将它们重新添加到IJ的信任存储中。而IJ的信任存储将会被ZScaler创建的所有这些临时证书淹没。这就是为什么要添加根证书的原因。我相信它作为任何这些临时代理证书的最终签名机构。我看到的这个证书将在20多年后才过期。因此,我认为自己还需要一段时间才能再次调整IJ设置。
注:
本答案中给出的解决方法实际上与此答案中给出的解决方法相同,但我正在详细说明如何从Google Chrome设置中获取ZScaler证书,并对我们为什么要做这些事情进行了一些讨论,并与其他替代方法进行了比较。

这对我有用,除了Zscaler证书在“受信任的发布者”下。不确定区别是什么,但如果其他人找不到它,就在那里。 - Alec Petersen

0
我需要做其他的事情吗?
是的,可能需要。 JAVA_HOME 是 Gradle 查找要执行的 Java 的变量。 一旦您拥有带有所需证书的信任存储的 Java,请尝试将 JAVA_HOME 设置为该目录。

0

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

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


4
这是因为IntelliJ使用了与您的终端不同的秘密存储。如果您从终端运行gradlew build,并且证书已安装,则Gradle将获取它所需的依赖项并进行缓存。当您随后从IntelliJ运行时,它已经拥有了所有必要的信息,并且可以从本地缓存中构建。 - Jon Bates

0

我将设置更新为自动导入证书,这对我起作用了。

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

我没有看到这个设置。你是指“自动接受非信任证书”吗? - Stealth Rabbi
当您选择“服务器证书”时,它位于弹出窗口的顶部。 - Niraj Sonawane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接