System.Net.Http 无法建立SSL监听 cURL error 77 的故障处理

Emby-Server(Jellyfin) 是一个优秀的家用媒体服务器,使用微软Net.Core 框架,可实现跨平台运行,在使用Centos 7 调试过程中,遇到SSL连接无法被监听的情况,导致电影图片和介绍信息无法正常获取,日志信息如下:

[2019-09-07 16:22:05.378 +08:00] [ERR] Error in "TheMovieDb"
System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
   at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---

根据日志信息,得出结论为 TheMovieDB 网站无法建立SSL监听,但不清楚具体原因,通过百度 得知网站地址为 https://www.themoviedb.org/

手工尝试在服务器上用curl请求是否能正常访问,得到以下错误提示:
curl: (77) error setting certificate verify locations:
CAfile: /etc/ssl/certs/ca-certificates.crt


看来是服务器自身也因SSL证书问题而导致https网站无法正常访问,可初步判断emby-server也调用了系统的curl库。
随后换了一台服务器做测试,访问则正常,在输出的详细日志中,正常的请求则多了一条信息
Initializing NSS with certpath: sql:etc/pki/nssdb


继续检查curl 版本,发现有问题的服务器 libcurl 库版本为 7.64.1 下图所示,而工作正常的服务器 libcurl 版本为 7.29.0,还包含了NSS,LIBIDN等扩展


继续检查,发现有问题的服务器系统RPM包版本为 7.29.0 ,并不是 7.64.1 版本,看来可能是系统肯能是加载了错误的动态库。


继续检查,使用ldconfig -p | grep libcurl  可看到系统使用了多个libcurl库文件路径,其中2个为 /usr/local/lib 路径


随后想起来在之前的一个软件调试中,手工编译过libcurl 并编辑 /etc/ld.so.conf 加载了/usr/local/lib 库文件查找路径。
重新编辑 /etc/ld.so.conf 配置文件,取消/usr/local/lib 查找路径并冲执行 ldconfig 
处理后,curl 重新使用了正确的libcurl库版本 7.29.0 并已能正确访问网站。

作者: Su

等待完善