c# - 两个 docker 容器之间的 Dotnet SSL 错误

标签 c# .net docker ssl docker-compose

我有一个问题,我使用 docker-compose for Visual Studio 运行多个容器。容器托管在默认网络上,可以使用 host.docker.internal 从内部访问。在暴露和映射的端口 42000 , 4200142002 .问题是当一个容器(运行计划作业)想要通过使用 TLS 调用另一个容器中的 API 时。我在 C# 中收到此错误:

System.Net.Http.HttpRequestException: 'The SSL connection could not be established, see inner exception.'
AuthenticationException: The remote certificate is invalid according to the validation procedure.
默认开发证书使用以下方式安装到容器上
    volumes:
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https
docker-compose.override.yml .
这是docker-compose.yml
version: '3.4'

services:
  portalpro:
    image: ${DOCKER_REGISTRY-}portalpro
    build:
      context: .
      dockerfile: src/PortalProV2/Dockerfile

  external-web-api:
    image: ${DOCKER_REGISTRY-}external-web-api
    build:
      context: .
      dockerfile: src/PortalPro.External.WebApi/Dockerfile

  scheduler:
    image: ${DOCKER_REGISTRY-}scheduler
    build:
      context: .
      dockerfile: src/Scheduler/Dockerfile
这是docker-compose.override.yml
version: '3.4'

services:
  portalpro:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
      # other app config values
    volumes:
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https
      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets
    ports:
      - "40000:80"
      - "42000:443"

  external-web-api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
      # other app config values
    volumes:
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https
      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets
    ports:
      - "40002:80"
      - "42002:443"

  scheduler:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
      # other app config values
    volumes:
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https
      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets
    ports:
      - "40001:80"
      - "42001:443"
这是 Dockerfile 之一,其他类似:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1.5-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

# ENV - some env var setup

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["PortalProV2/PortalProV2.csproj", "PortalProV2/"]
RUN dotnet restore "PortalProV2/PortalProV2.csproj"
COPY . .
WORKDIR "/src/PortalProV2"
RUN dotnet build "PortalProV2.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "PortalProV2.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "PortalProV2.dll"]
我可以从本地主机调用容器。他们可以调用其他受信任的服务。只是 docker 到 docker 的通信中断了。
我还在 docker 容器中运行了 mssql,并且可以使用 host.docker.internal,1433 从内部访问它。 .
我尝试使用 openssl 生成本地自签名证书,其中 SAN=host.docker.internal 和 localhost,然后在主机上安装、信任,并使用 update-ca-certificates 将证书安装到容器中,但这失败了。
我也尝试过使用dotnet dev-certs生成证书并信任它,但这是通常的方式,它也失败了。openssl s_client -connect host.docker.internal:42000从容器内返回这些错误:
CONNECTED(00000003)
depth=0 CN = localhost
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = localhost
verify error:num=21:unable to verify the first certificate
verify return:1
...
curl -X GET https://host.docker.internal:42000/index.html返回
curl: (7) Failed to connect to host.docker.internal port 443: Connection refused
root@4b4b805a4250:/app# curl -X GET https://host.docker.internal:42000/index.html
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
Docker 在 WSL2 上的 Windows 上运行。 Linux 容器。
当然,一定有一些我遗漏的东西,一些明显的东西,因为我找到的所有解决方案似乎在这里都不起作用。
我敢肯定有人有 dotnet docker 到 docker 的通信,它一定很常见,所以也许群众的智慧可以帮助这里迷失的灵魂?

最佳答案

dotnet 开发证书仅在作为 localhost 访问时才有效。因此不支持容器到容器的通信。
所以不幸的是,没有简单的解决方法。
一种解决方法是创建您自己的 CA 证书和服务证书,告诉 Kestrel 使用这些证书而不是默认的开发证书,并让每个服务都信任您的 CA 证书。关于此 GitHub issue 的更多信息.

关于c# - 两个 docker 容器之间的 Dotnet SSL 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67109850/

相关文章:

c# - 使用 MonoTouch 的异步请求

c# - 向用户添加 2fa 身份验证器

.net - VB6 HTTP 请求到 VB.Net 2.0 的转换

c# - 如何在Winform中显示欢迎画面?

linux - 对于 Docker,应用程序会在主机内核更新时停止工作吗?

c# - Crystal Reports c# VS 2012 - 无法将图片添加到我的报告,不显示?

c# - 注释会减慢编译语言的速度吗?

asp.net - EF6、MVC 5 和 Oracle 数据库

docker - 如何连接到 OpenDJ LDAP 服务器 (Docker)

Docker Windows 容器和 NFS 卷