"dotnet restore" 失败 "SSL peer certificate or SSH remote key was not OK"

"dotnet restore" fails with "SSL peer certificate or SSH remote key was not OK"

我刚刚按照这里的程序操作: https://www.microsoft.com/net/core#ubuntu

这就是dotnet restore

的输出
log  : Restoring packages for /home/test/project.json...
error: Unable to load the service index for source https://api.nuget.org/v3/index.json.
error:   An error occurred while sending the request.
error:   SSL peer certificate or SSH remote key was not OK

我已将相关证书添加到受信任的证书中以使 curl 正常工作,但错误仍然存​​在 dotnet restore

我试图挖掘核心源代码以找出 Nuget 如何检查 SSL 证书,但不幸的是。 我试过的版本:

我使用 .curlrc 配置了 curl :

cacert=/etc/ssl/certs/ca-certificates.crt

它已修复 curl -I https://api.nuget.org 调用。

然而dotnet restore -v Debug仍然失败:

trace: Running restore with 8 concurrent jobs.
trace: Reading project file /home/user/test/project.json.
log  : Restoring packages for /home/user/test/project.json...
trace: Restoring packages for .NETCoreApp,Version=v1.0...
error: Unable to load the service index for source https://api.nuget.org/v3/index.json.
error:   An error occurred while sending the request.
error:   SSL peer certificate or SSH remote key was not OK
trace: System.AggregateException: One or more errors occurred. (Unable to load the service index for source https://api.nuget.org/v3/index.json.) ---> NuGet.Protocol.Core.Types.FatalProtocolException: Unable to load the service index for source https://api.nuget.org/v3/index.json. ---> System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.Http.CurlException: SSL peer certificate or SSH remote key was not OK
trace:    at System.Net.Http.CurlHandler.ThrowIfCURLEError(CURLcode error)

所以 dotnet 核心使用 libcurl 但显然没有使用 .curlrc

编辑:2016 年 6 月 21 日

也尝试用 mozroots 更新证书数据库,但没有任何效果。 (似乎与 mono 的关系比与 dotnetcore 的关系更大,即使 dotnet 核心构建页面提到了它)。

深入研究 corefx 代码后,System.Net.Http 的 Curl 处理程序似乎并未在所有情况下都设置正确的 ssl 选项(如 Simple Curl SSL sample)。

我试过Tyler解决方案:

certmgr -ssl -m https://api.nuget.org

即使我键入 'y', 'yes', '1', 'true' 或其他任何内容,这也不会添加最后一个证书。

mozroots --url https://hg.mozilla.org/mozilla-central/raw-file/tip/security/nss/lib/ckfw/builtins/certdata.txt --sync --import

这有一些作用:

Importing certificates into user store...
194 new root certificates were added to your trust store.
Import process completed.

我不相信 dotnet 核心使用了 libcurl nss 构建(只是因为他们的 development page 讲述了 openssl 版本(并且他们是互斥的)。顺便说一句,我试过使用nss 构建 libcurl 和 dotnet restore 仍然失败。

恕我直言,问题与错误的证书注册无关,但更多的是 curl 内置证书验证未正确禁用(因为证书验证是在 System.Net.Http 中完成的,并且必须提供给客户端代码自定义此验证的能力)。

为什么它发生在我的机器上而不是其他地方? 肯定和我的libcurl版本有关

不过,目前所有这些都只是假设。

编辑 22/05/2016:

通过更彻底地查看代码,尤其是比较 master 分支和 RC2 版本时,很明显 SSL 处理代码仍在发生很大变化。

所以我只是抓取 RC2 代码并修改它以反映 master 分支的作用:

easy.SetCurlOption(Interop.Http.CURLoption.CURLOPT_SSL_VERIFYHOST, 0);

然而,它并没有改变任何东西……但预测是。 所以这里是我使用的代码:

easy.SetCurlOption(Interop.Http.CURLoption.CURLOPT_SSL_VERIFYPEER, 0);

然后用禁用的 ssl 证书检查替换 System.Net.Http.dll。 不安全但暂时解封我。

我没有将其添加为答案,因为它更多的是破解而不是修复。

(真正的解决办法是完全禁用 curl 完成的证书检查,并始终在 .Net 核心中处理它,但在 master 上的当前代码中,情况仍然不是这样,它更像是两者的混合体) .

对于根本原因,我认为我处于特定设置中:

place where the certificates are imported from currently redirects to an under construction/outage page。维护完成后,请重试。我认为这对 Mozilla 或 mozroots 维护者来说有点失误。您在控制台输出中看到的只是堆栈跟踪或 Couldn't retrieve the file using the supplied information.,具体取决于您的 mozroots 构建。

解决方法是以某种方式使用 certmgr 导入正确的 CA 证书,然后导入端点证书(使用 certmgr -ssl -m https://api.nuget.org)。如果缺少证书的 CA,则证书被视为无效。如果证书被认为无效,您可以导入它们,但还原仍然会出现错误,提示证书缺少匹配的颁发者 CA 证书。

我以某种方式说,因为我还没有想出一个安全的好方法来推荐这样做。我肯定会将适当的 mozroots 证书烘焙到我构建的下一个 mono+dotnet docker 图像中。

较新的 mozroots 版本具有命令行参数来替代证书数据端点。打算改用 a web.archive.org copy as a substitute for mozroots --url ... for now. Going to see if I can just use this or maybe this,或者可能是 Mozilla 官方 mercurial 仓库中的另一个 certdata.txt

打开 SSL 丢失的捆绑证书

根本原因openssl.
的缺失配置 如果您 运行 以下命令(或类似命令):

openssl verify /usr/share/ca-certificates/nuget.crt

并且您收到以下结果:

/usr/share/ca-certificates/nuget.crt: C = US, ST = Washington, L = Redmond, O = Microsoft Corporation, OU = Microsoft IT, CN = Microsoft IT SSL SHA2
error 2 at 1 depth lookup:unable to get issuer certificate
140075910137504:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:703:Expecting: TRUSTED CERTIFICATE
140075910137504:error:0B06F009:x509 certificate routines:X509_load_cert_file:PEM lib:by_file.c:162:

这是因为 openssl(dotnet / libcurl 最终依赖于其进行 ssl 检查)不知道在哪里可以找到 ca 包。我在 /etc/ssl/openssl.cnf 中没有看到任何相关参数,所以即使

export OPENSSL_CONF=/etc/ssl/openssl.cnf

对 openssl 验证失败没有帮助。

但是,以下解决了这两个问题(openssl 和 nuget)

export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt

现在 openssl 的输出:

zsh/2 906 [1] # openssl verify /usr/share/ca-certificates/nuget.crt
/usr/share/ca-certificates/nuget.crt: OK

dotnet restore:

zsh 904 # dotnet restore
log  : Restoring packages for /home/user/test/project.json...
info :   GET https://api.nuget.org/v3-flatcontainer/microsoft.netcore.dotnethostresolver/index.json
info :   OK https://api.nuget.org/v3-flatcontainer/microsoft.netcore.dotnethostresolver/index.json 412ms
info :   GET https://api.nuget.org/v3-flatcontainer/microsoft.netcore.dotnethost/index.json
info :   OK https://api.nuget.org/v3-flatcontainer/microsoft.netcore.dotnethost/index.json 409ms
info : Committing restore...
log  : Lock file has not changed. Skipping lock file write. Path: /home/user/test/project.lock.json
log  : /home/user/test/project.json
log  : Restore completed in 4412ms.

NuGet Config files used:
    /home/user/.nuget/NuGet/NuGet.Config

Feeds used:
    https://api.nuget.org/v3/index.json

特别感谢 Tyler 帮助我保持解决此问题的动力。

如果您在 docker 容器中遇到此错误,则 运行

  • docker 系统 p运行e --volumes.

然后停止计算机中的 docker 应用程序。 重新启动您的机器并运行重新启动所有内容。