Search code examples
c#dockerssldocker-composeasp.net-core-webapi

Connection refused between Docker containers with SSL in .NET


I have two ASP.NET Core 8 Web API projects in C#, named FrontEnd and DataLayer. DataLayer connects to a database and FrontEnds connects to DataLayer.

Both projects and database are in Docker in local dev environment.

Solution contains:

  • Some files
  • Docker Compose
  • DataLayer API
  • FrontEnd API
  • Other projects like React layer and unit testing

In the docker compose I'm running both projects. Main idea is working with SSL for several reasons, so moving on to http is not an option. I'm working in Visual Studio 2022 in Windows and dockers are running Debian bookworm.

In my etc/hosts file I configured:

127.0.0.1 FrontEnd
127.0.0.1 DataLayer

So when I use a REST Client, both projects are running OK with the following URLs:

https://FrontEnd:8083/
https://DataLayer:8081/

I'd created two certificates self-signed with openssl with the following command in a directory called certs inside my solution:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout DataLayer.key -out DataLayer.crt -subj "/CN=DataLayer"

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout FrontEnd.key -out FrontEnd.crt -subj "/CN=FrontEnd"

and I use the following docker compose file:

version: '3.4'

networks:
  marketApp:
    driver: bridge

services:

  markettooldatalayer:
    image: ${DOCKER_REGISTRY-}markettooldatalayer
    build:
      context: .
      dockerfile: MarketToolDataLayer/Dockerfile
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_HTTP_PORTS=8080
      - ASPNETCORE_HTTPS_PORTS=8081
    ports:
      - "8080:8080"
      - "8081:8081"
    volumes:
      - ${APPDATA}/Microsoft/UserSecrets:/home/app/.microsoft/usersecrets:ro
      - ${APPDATA}/ASP.NET/Https:/home/app/.aspnet/https:ro
      - ./certs/DataLayer.crt:/etc/ssl/certs/DataLayer.crt
      - ./certs/DataLayer.key:/etc/ssl/private/DataLayer.key
      - ./certs/FrontEnd.crt:/etc/ssl/certs/FrontEnd.crt 
    user: root
    networks:
      - marketApp

  markettoolfrontend.server:
    image: ${DOCKER_REGISTRY-}markettoolfrontendserver
    build:
      context: .
      dockerfile: MarketToolFrontEnd/MarketToolFrontEnd.Server/Dockerfile
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_HTTP_PORTS=8082
      - ASPNETCORE_HTTPS_PORTS=8083
    ports:
      - "8082:8082"
      - "8083:8083"
    volumes:
      - ${APPDATA}/Microsoft/UserSecrets:/home/app/.microsoft/usersecrets:ro
      - ${APPDATA}/ASP.NET/Https:/home/app/.aspnet/https:ro
      - ./certs/FrontEnd.crt:/etc/ssl/certs/FrontEnd.crt
      - ./certs/FrontEnd.key:/etc/ssl/private/FrontEnd.key
      - ./certs/DataLayer.crt:/etc/ssl/certs/DataLayer.crt 
    user: root
    networks:
      - marketApp

I'd configured my appsettings.json DataLayer with the following Kestrel configuration:

  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://*:8081",
        "Certificate": {
          "Path": "/etc/ssl/certs/DataLayer.crt",
          "KeyPath": "/etc/ssl/private/DataLayer.key"
        }
      }
    }
  },

and for the FrontEnd, I'm using the following URL:

https://DataLayer:8081

This way I just described is a lot of bumping my head with the certificate and CN Name and after a while I just pass through the certificate error but now I'm getting the following error inside the inner exception when RestSharp connects to the datalayer:

Connection refused (datalayer:8081)

Update: containers are different in one group/service:

enter image description here

Also added

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;

to the call of RestSharp.

Ping from frontend container to datalayer container is OK

What I'm missing here? Any comment or answer or idea will be appreciated.

Thanks in advance


Solution

  • Everything in my question is fine, I just added a hostname in my docker compose to identify the internal IP of the containers, like:

    networks:
      marketApp:
        aliases:
          - DataLayer
    

    and the certificate will take this in the same network.