Windows的Docker CE-无法建立SSL连接.根据验证步骤,远程证书无效
我在调用内部https url时遇到SSL问题(例如 https://sample/demoapi/api/item/)来自容器化的.net核心2.2 API.在容器外运行时,API可以正常运行.
I am having an SSL issue when calling internal https url (like https://sample/demoapi/api/item/) from a containerized .net core 2.2 API. The API works fine when run outside of container.
注意:当将Docker Thin Linux VM中的ssl文件夹安装到容器时,该容器可以完美地工作.docker run -itd -p 5011:80 -v/etc/ssl/certs:/etc/ssl/certs
Note: The container works perfect when mounting the ssl folder from the Docker thin Linux VM to the container. docker run -itd -p 5011:80 -v /etc/ssl/certs:/etc/ssl/certs
信息Windows版本:Win 10适用于Windows CE的Docker版本:Docker CE 2.0.0.3(不是最新版本.从具有最新Docker CE的容器中调用URL时,我遇到DNS名称解析问题.发现Docker 2.0.0.3正常工作)Docker在Windows 10计算机上运行,而不在VM上运行.运行Linux主机和容器.我已经按照以下解决方法将ssl证书复制并更新到了容器上,但是没有用. Linux docker:System.Security.Authentication.AuthenticationException:根据验证程序,远程证书无效如何添加CA根证书在docker图片中?
Information Windows Version: Win 10 Docker for windows CE Version: Docker CE 2.0.0.3 (not the latest. I have DNS name resolution issue when calling a URL from a container with the latest docker CE. Docker 2.0.0.3 is the one found working without issues) Docker is running on windows 10 machine not on VM. Running Linux host and containers. I have followed the following resolutions to copy and update the ssl certificate onto the container but didn't work. Linux docker: System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure How do I add a CA root certificate inside a docker image?
重现此问题的步骤:
-
创建一个示例.net核心api,并按如下所示调用https服务.
Create a sample .net core api and call an https service as follows.
尝试{var client = new HttpClient();var resp =等待客户端.GetAsync(" https://test.com ");数据=等待resp.Content.ReadAsStringAsync();}catch(异常e){数据= e.StackTrace +-" + e.Message +-" + e.InnerException;}
try { var client = new HttpClient(); var resp = await client.GetAsync("https://test.com"); data = await resp.Content.ReadAsStringAsync(); } catch(Exception e) { data = e.StackTrace + "- " + e.Message + " - " + e.InnerException; }
按上述指定发布应用程序应用程序类型:.net core 2.2 api发布配置:目标框架:.netcoreapp2.2部署方式:设备齐全目标运行时间:linux-x64
Publish the application as specified above Application type: .net core 2.2 api Publish configuration: Target framework: .netcoreapp2.2 Deployment method: self-contained Target run time: linux-x64
使用docker文件构建映像从mcr.microsoft.com/dotnet/core/aspnet:2.2 AS运行时COPY Publish/app/复制./certf.crt/usr/local/share/ca-certificates/certf.crt运行chmod 644/usr/local/share/ca-certificates/certf.crt&&更新证书ENTRYPOINT ["dotnet","app/testapp1.dll"]
Build image using the docker file FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime COPY Publish/ app/ COPY ./certf.crt /usr/local/share/ca-certificates/certf.crt RUN chmod 644 /usr/local/share/ca-certificates/certf.crt && update-ca-certificates ENTRYPOINT ["dotnet", "app/testapp1.dll"]
运行docker命令-docker run -itd -p 5011:80 --name demoapi demoapi
Run docker command - docker run -itd -p 5011:80 --name demoapi demoapi
收到错误:在System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream,SslClientAuthenticationOptions sslOptions,CancellationToken cancelledToken)在System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage请求,CancellationToken cancelToken)在System.Neting.Tasks.ValueTask1.get_Result()在System.Threading.Tasks.ValueTask1.get_Result()在在System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1 creationTask)在System.Threading.Tasks.ValueTask1.get_Result()在System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage请求,布尔值doRequestAuth,CancellationToken cancelledToken)在System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage请求,CancellationToken cancelToken)在System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task1 sendTask,HttpRequestMessage request,CancellationTokenSource cts,Boolean disposeCts)处位于demoapiapp1.Controllers.ValuesController.Get(Int32 id)在C:\ dev \ Controllers \ ItemsController.cs:第41行-----无法建立SSL连接,请参阅内部异常.< --------------------> System.Security.Authentication.AuthenticationException:根据验证过程,远程证书无效.在System.Net.Security.SslState.StartSendBlob(System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken消息,AsyncProtocolRequest asyncRequest)上的System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken消息,AsyncProtocolRequest asyncRequest,ExceptionDispatchInfo异常)]传入,位于System.Net.Security.SslState.ProcessReceivedBlob(Byte []缓冲区的Int32计数,AsyncProtocolRequest asyncRequest),位于System.Net.Security.SslState.StartReadFrame(Byte []缓冲区,Int32 readBytes,位于System.Net.Security.SslState.StartReceiveBlob(Byte []缓冲区的AsyncProtocolRequest asyncRequest),位于System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken消息,AsyncProtocolRequest asyncRequest)的System.Net.Security.SslState.StartSendBlob(Byte []缓冲区,AsyncProtocolRequest asyncRequest).Byte []传入,Int32计数,AsyncProtocolRequest asyncRequest),位于System.Net.Security.SslState.ProcessReceivedBlob(ByteSystem.Net.Security.SslState.StartReadFrame()的[]缓冲区,Int32计数,AsyncProtocolRequest asyncRequest)(System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)的[]缓冲区,Int32计数,AsyncProtocolRequest asyncRequest)---结束从上一个引发异常的位置开始的堆栈跟踪的位置--- System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)的System.Net.Security.SslState.ThrowIfExceptional()在System.Net.Security.SslStream处的System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult)处.<>在System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult处)的c.b__47_1(IAsyncResult iar),Func2 endFunction,Action1 endAction,Task`1 promise,布尔值requireSynchronization)---从上一个引发异常的位置开始的堆栈结束跟踪---在System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream,SslClientAuthenticationOptions sslOptions,CancellationToken cancellingToken)
Error received: at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Threading.Tasks.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask1 creationTask) at System.Threading.Tasks.ValueTask1.get_Result() at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at demoapiapp1.Controllers.ValuesController.Get(Int32 id) in C:\dev\Controllers\ItemsController.cs:line 41 ----- 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.PartialFrameCallback(AsyncProtocolRequest asyncRequest) --- End of stack trace from previous location where exception was thrown --- at System.Net.Security.SslState.ThrowIfExceptional() at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result) at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult) at System.Net.Security.SslStream.<>c.b__47_1(IAsyncResult iar) at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task`1 promise, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
找到了问题并解决了.发布此内容可帮助遇到相同问题的任何人.
Found the problem and resolved it. Posting this to help anyone who experience the same problem.
我使用了错误的证书.要使用的证书是证书颁发机构证书(根证书),但我使用了颁发给系统的证书.我从链中生成了根证书,并使用上面引用的"stakoverlow"分辨率将其导入到容器中.
I used wrong certificate. The certificate to be used is the certificate authority certificate (root certificate) but I used the certificate issued to the system. I generated the root certificate from the chain and imported to container using the 'stakoverlow' resolution referenced above.
解决方案:ca证书名为ca-cert.crt.在Dockerfile中添加了以下几行.
Resolution: The ca certificate is named as ca-cert.crt. Added the following lines the Dockerfile.
COPY ca-cert.crt /usr/local/share/ca-certificates/ca-cert.crt
RUN chmod 644 /usr/local/share/ca-certificates/ca-cert.crt && update-ca-certificates