【问题标题】:"dotnet restore" fails with "SSL peer certificate or SSH remote key was not OK"“dotnet restore”因“SSL 对等证书或 SSH 远程密钥不正常”而失败
【发布时间】:2016-10-16 17:59:18
【问题描述】:

我刚刚按照这里的程序进行了操作: 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 证书却没有运气。 我尝试过的版本:

  • 1.0.0-preview1-002702
  • 1.0.0-preview2-003100

我已经使用 .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 core 使用 libcurl,但显然没有使用 .curlrc

编辑:21/06/2016

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

深入研究 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 core 使用了 libcurl nss 构建(只是因为他们的 development page 讲述了 openssl 版本(并且它们是互斥的)。顺便说一下,我尝试使用 libcurl 的 nss 构建并且 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);

然后将 System.Net.Http.dll 替换为禁用 ssl 证书检查。 不安全,但暂时解除对我的阻止。

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

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

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

  • libcurl 构建时没有任何默认证书捆绑路径。 curlconfig --ca 返回一个空字符串。而且它不会读取CURL_CA_BUNDLE 环境变量或.curlrc 文件。
  • System.Net.Http(dotnet-core)既不设置 ca 默认值,也不禁用证书验证。

【问题讨论】:

    标签: .net ssl-certificate ubuntu-14.04 dotnet-cli


    【解决方案1】:

    place where the certificates are imported from 当前重定向到an under construction/outage page。维护完成后,再试一次。我认为这对 Mozilla 或 mozroots 维护者来说都是一个小错误。您在控制台输出中看到的只是堆栈跟踪或Couldn't retrieve the file using the supplied information.,具体取决于您的 mozroot 构建。

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

    我之所以这么说,是因为我还没有找到一个安全的好方法来推荐这样做。我肯定会将适当的 mozroots 证书烘焙到我构建的下一个 mono+dotnet docker 映像中。

    较新的 mozroot 版本具有命令行参数来替换证书数据端点。现在将使用a web.archive.org copy 代替mozroots --url ...。看看我是否可以只使用thisthis,或者来自Mozilla 的官方mercurial repo 的另一个certdata.txt

    【讨论】:

    • 您先运行 mozroots,然后运行 ​​certmgr,对吗?我正在使用带有 (patch-diff.githubusercontent.com/raw/mono/mono/pull/2771.patch) 补丁的 Mono 4.4.0.182;基于此 docker 映像 (hub.docker.com/r/2020ip/dotnet-mono/~/dockerfile) 该补丁仅用于处理空 Tls 流,但不是证书验证。您可以检查从该 debian jessie 构建中提取的 libcurl 版本。以后再看时,我会检查版本。
    • 在我的构建脚本中,为了在构建映像时接受,我将( yes | certmgr -ssl -m https://api.nuget.org ) \ 作为 dockerfile 的一部分。它为我添加了一个颁发给 *.vo.msecnd.net 的证书(以及一堆废话,包括 api.nuget.org)。但是,我也有( yes | certmgr -ssl -m https://www.nuget.org ) \ ,它添加了 nuget.org...
    • 我都在使用。看到 docker 文件中的“FROM microsoft/dotnet:1.0.0-preview1”行了吗?将 Mono 用于 nuget.exe 和其他未移植到 dotnet RC 2 / Preview 1 的 .NET 可执行文件。
    • 以前,我会从 mono 和 dotnet 获得“SSL 对等证书或 SSH 远程密钥不正常”,可能都源于 github.com/curl/curl/blob/master/lib/strerror.c 第 191 行;两者都使用 libcurl。
    【解决方案2】:

    打开 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 帮助我保持解决此问题的动力。

    【讨论】:

      【解决方案3】:

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

      • docker system prune --volumes.

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-20
        • 2022-07-19
        • 2014-05-31
        • 2014-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-30
        相关资源
        最近更新 更多