У меня есть два проекта веб-API ASP.NET Core 8 на C# с именами FrontEnd
и DataLayer
. DataLayer
подключается к базе данных и FrontEnds
подключается к DataLayer
.
И проекты, и база данных находятся в Docker в локальной среде разработки.
Решение содержит:
В докере я запускаю оба проекта. Основная идея — работа с SSL
по нескольким причинам, поэтому переход на http невозможен. Я работаю в Visual Studio 2022 в Windows и докеры работают Debian bookworm
.
В моем файле etc/hosts
я настроил:
127.0.0.1 FrontEnd
127.0.0.1 DataLayer
Итак, когда я использую REST
Клиент, оба проекта выполняются OK
со следующими URL-адресами:
https://FrontEnd:8083/
https://DataLayer:8081/
Я создал два самоподписанных сертификата с помощью openssl с помощью следующей команды в каталоге с именем certs
внутри моего решения:
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"
и я использую следующий файл компоновки докера:
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
Я настроил свой DataLayer appsettings.json
со следующей конфигурацией Kestrel:
"Kestrel": {
"Endpoints": {
"Https": {
"Url": "https://*:8081",
"Certificate": {
"Path": "/etc/ssl/certs/DataLayer.crt",
"KeyPath": "/etc/ssl/private/DataLayer.key"
}
}
}
},
а для FrontEnd я использую следующий URL:
https://DataLayer:8081
Таким способом, который я только что описал, приходится часто сталкиваться с сертификатом и именем CN, и через некоторое время я просто пропускаю ошибку сертификата, но теперь я получаю следующую ошибку внутри внутреннего исключения, когда RestSharp подключается к уровню данных:
Соединение отклонено (уровень данных: 8081)
Обновление: контейнеры в одной группе/сервисе разные:
Также добавлено
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
на вызов RestSharp.
Ping
от frontend container
до datalayer container
это OK
Чего мне здесь не хватает? Любой комментарий, ответ или идея будут оценены по достоинству.
заранее спасибо
@Charlieface хороший вопрос! Они разные, сгруппированы в один композиторский сервис. Я добавил ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13; на звонок, но сообщение то же самое.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
не делайте этого никогда. Все, что он делает, это ограничивает количество протоколов, которые вы можете использовать, но не включает то, что недоступно. И TLS вряд ли здесь проблема, вероятно, потому, что они находятся в разных контейнерах, поэтому 127.0.0.1 — неправильный адрес. Вам необходимо определить IP-адреса контейнеров, чтобы они могли общаться друг с другом.
Все в моем вопросе в порядке, я просто добавил имя хоста в свою композицию докера, чтобы определить внутренний IP-адрес контейнеров, например:
networks:
marketApp:
aliases:
- DataLayer
и сертификат примет это в той же сети.
Это один и тот же контейнер или разные контейнеры? Отказ в соединении звучит так, будто это проблема с брандмауэром, поэтому, вероятно, даже не доходит до TLS.