关于后端:国产化之银河麒麟netcore31访问https服务的两个问题

10次阅读

共计 2533 个字符,预计需要花费 7 分钟才能阅读完成。

背景

某个我的项目须要实现根底软件全副国产化,其中操作系统指定河汉麒麟,数据库应用达梦 V8,CPU 平台的范畴包含 x64、龙芯、飞腾、鲲鹏等。

思考到这些根底产品对.NETCore 的反对,最终抉择了 3.1 版本。次要起因就是龙芯搞了自研 CPU 架构,用户量不够大,.NET 官网并没有专门针对龙芯的反对,而龙芯团队只对.netcore3.1 做了适配(目前.net6 适配测试中),至于其它的国产 CPU 则是基于 Arm64 和 x64 的,.NET 官网都有反对。

环境

  • 主机操作系统:Windows 10
  • 虚拟化工具:QEMU
  • 虚拟机 CPU:cortex-a53(ARMv8 架构,反对 Arm64)
  • 虚拟机操作系统:河汉麒麟 v4(未装置桌面)

问题

问题一:无奈验证 xxx 的由 yyy 颁发的证书

这个谬误是在开发环境呈现的,通过 wget 申请 https 服务时抛出异样:

具体谬误提醒如图所示,应用 HttpClient 发动申请一样会报错,这是因为装置的操作系统没有自带根 CA 证书。装置 ca-certificates 就能够解决:

sudo apt-get install -y ca-certificates

至于错误信息中的倡议:应用 ”–no-check-certificate”。应用 https 就是为了平安,间接忽视就好了。

问题二:The SSL connnection could not be established

这个谬误是在生产环境呈现的,曾经排除第一个问题。

谬误的关键词还有:AuthenticationException: The remote cert is invalid according to the validation procedure. 简略点说就是:被拜访服务的证书有效。

这里先贴出解决方案,一会再说起因。减少一个环境变量:

export DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER = 0

倡议还是把它写到 /etc/profile 中,而后用 source /etc/profile 失效。

上面来剖析下这个问题产生的起因

在微软的官网文档中能够找到对于这个配置的阐明:

https://docs.microsoft.com/en…

https://docs.microsoft.com/zh…

大略就是说.NET Core 2.1 之后,HttpClient 外部默认应用新写的 SocketsHttpHandler,然而也容许切换到之前的旧 Handler,在 Linux 上之前应用的是 CurlHandler,从这个名字上看应该是应用了 libcurl 这个库,这个库应用 C 语言写的,.NET 调用的时候会有一点性能损失,所以起初.NET 摈弃了 libcurl,本人实现了 Http 网络栈的解决,也就是 SocketsHttpHandler。通过设置环境变量,将 Http 网络栈的解决回退到了 CurlHandler。

那么为什么 CurlHandler 能够,SocketsHttpHandler 却不行呢?

在 dotnet 的 github 仓库中有一些对于这个谬误的 issue:

https://github.com/dotnet/run…
https://github.com/dotnet/run…

我这里总结外围问题就是 SocketsHttpHandler 验证证书域名的问题,证书的域名中大小写混合、蕴含下划线、应用通配符等等会导致异样,有些问题能够通过修复 SocketsHttpHandler 解决,有些问题是因为依赖了 OpenSSL,比方 OpenSSL 认为域名不应该蕴含下划线,.NET 这边遇到此类的域名就会报错,.NET 也不会被动去解决。另外文中还提到旧版本的 OpenSSL 是没问题的,新版本的 OpenSSL 才这样,因为开发者认为新版本的做法更标准。.NETCore 依赖的 OpenSSL 版本能够在这里找到:https://docs.microsoft.com/zh-cn/dotnet/core/install/linux-ubuntu#dependenciesDocs

至于我遇到的是哪个问题,因为在本地环境没有遇到这个问题,生产环境是他人去保护的,上线后也不不便去搞,所以临时无奈定位到具体起因。猜测可能有两个起因:生产环境的 OpenSSL 相干库版本比拟新,而开发环境的 OpenSSL 库版本比拟旧;生产环境用到的证书域名不标准,测试环境用到的证书域名标准。

还有为什么应用了 CurlHandler 就没有问题呢?因为我这里的 curl 没有依赖 openssl,在河汉麒麟 v4 中,curl 依赖的是 gnutls(SSL support is provided by GnuTLS.),如果曾经装置了 curl 能够应用这个命令看它依赖的包:apt-cache depends curl 我这里显示的是:

curl
  依赖: libc6
  依赖: libcurl3-gnutls
  依赖: zlib1g

如果没有装置 curl,能够看看 libcurl3-gnutls 这个包是否存在:dpkg -s libcurl3-gnutls,如果存在这个包,则会显示它的详细信息。

最初如果你想晓得本人遇到了什么谬误,能够通过下边的代码来获取:

var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => {if (errors == SslPolicyErrors.None)
    {return true;}

    // todo: 在这里输入 errors 到日志

    throw new AuthenticationException($"Ssl certificate validation failed when trying to connect to {message.RequestUri}, Error: {errors}.");
}

var client = new HttpClient(httpClientHandler);

以上就是本文的次要内容了,如有问题,欢送反馈。

播种更多架构常识,请关注微信公众号 萤火架构。原创内容,转载请注明出处。

正文完
 0