title: Dotnet SSL error between two docker containers
body: <p>I have a problem where I am running several containers using docker-compose for Visual Studio. The containers are hosted on the default network and are reachable from within using <code>host.docker.internal</code> on the exposed and mapped ports <code>42000</code>, <code>42001</code> and <code>42002</code>. The problem is when one container (that runs scheduled jobs) wants to call an API in another container through using TLS. I am getting this error in C#:</p>
  <pre><code>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.
  </code></pre>
  <p>The default development certificates are mounted onto the containers using</p>
  <pre><code>    volumes:
        - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https
  </code></pre>
  <p>in <code>docker-compose.override.yml</code>.</p>
  <p>This is the <code>docker-compose.yml</code></p>
  <pre><code>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
  </code></pre>
  <p>This is the <code>docker-compose.override.yml</code></p>
  <pre><code>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:
        - &quot;40000:80&quot;
        - &quot;42000:443&quot;
  
    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:
        - &quot;40002:80&quot;
        - &quot;42002:443&quot;
  
    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:
        - &quot;40001:80&quot;
        - &quot;42001:443&quot;
  </code></pre>
  <p>This is one of the Dockerfiles, the others are similar:</p>
  <pre><code>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 [&quot;PortalProV2/PortalProV2.csproj&quot;, &quot;PortalProV2/&quot;]
  RUN dotnet restore &quot;PortalProV2/PortalProV2.csproj&quot;
  COPY . .
  WORKDIR &quot;/src/PortalProV2&quot;
  RUN dotnet build &quot;PortalProV2.csproj&quot; -c Release -o /app/build
  
  FROM build AS publish
  RUN dotnet publish &quot;PortalProV2.csproj&quot; -c Release -o /app/publish
  
  FROM base AS final
  WORKDIR /app
  COPY --from=publish /app/publish .
  ENTRYPOINT [&quot;dotnet&quot;, &quot;PortalProV2.dll&quot;]
  </code></pre>
  <p>I can call the containers from localhost. They can call other trusted services. It's just that docker to docker communication is broken.</p>
  <p>I also have mssql running in a docker container, and it is reachable from within using <code>host.docker.internal,1433</code>.</p>
  <p>I have tried to use openssl to generate a local self-signed certificate with SAN=host.docker.internal and localhost, and then install, trust on the host machine, and also install the certificates to the containers using <code>update-ca-certificates</code>, but this failed.</p>
  <p>I have also tried to use <code>dotnet dev-certs</code> to generate the certificate and trust it, but it's the usual way, and it failed too.</p>
  <p><code>openssl s_client -connect host.docker.internal:42000</code> from within the container returns these errors:</p>
  <pre><code>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
  ...
  </code></pre>
  <p><code>curl -X GET https://host.docker.internal:42000/index.html</code> returns</p>
  <pre><code>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.
  </code></pre>
  <p>Docker is running on Windows on WSL2. Linux containers.</p>
  <p>Surely there must be something that I am missing, some obvious thing, since all of the solutions I am finding don't seem to work here.</p>
  <p>I am sure someone has had dotnet docker to docker communication, it must be pretty common, so maybe the wisdom of the crowd could help a lost soul here?</p>