“dotnet restore”失败并显示“SSL对等证书或SSH远程密钥不正常”

时间:2016-06-15 14:36:31

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

我刚刚按照这里的程序: 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核心使用libcurl,但它显然没有使用.curlrc

编辑:2016年6月21日

尝试用mozroots更新证书数据库,但它没有任何效果。 (即使dotnet核心构建页面提到它,似乎更像是单声道而不是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核心使用了libcurl nss构建(仅仅因为他们的development page讲述了openssl版本(并且它们是互斥的)。顺便说一句,我试图使用nss构建libcurl和dotnet恢复仍然失败。

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

为什么它会在我的机器上而不是在其他地方发生? 它必须与我的libcurl版本相关。

然而,所有这些只是暂时的假设。

编辑22/05/2016:

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

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

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的当前代码中,它仍然不是这样,它更像是两者的混合)。< / p>

对于根本原因,我认为我正在进行特定设置:

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

3 个答案:

答案 0 :(得分: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帮助我保持解决这个问题的动力。

答案 1 :(得分:1)

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

Sadness

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

我不知怎的说,因为我还没有想出一个好的安全方式来推荐它。我肯定会在我构建的下一个mono + dotnet docker图像中加入适当的mozroots证书。

较新的mozroots版本具有命令行参数来替换证书数据端点。暂时使用a web.archive.org copy替代mozroots --url ...。去看看我是否可以使用thisthis代替,或者使用来自Mozilla官方善变回购的另一个certdata.txt

答案 2 :(得分:0)

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

  • docker system prune --volumes。

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