I'm trying to use Ocelot (Api gateway) + consul + my web api (.Net 5) via HTTPS in docker;
MY_SECRET_PROJECT_PATH\LicenseServiceWebApi> dotnet dev-certs https --clean
Cleaning HTTPS development certificates from the machine. A prompt might get displayed to confirm the removal of some of the certificates.
HTTPS development certificates successfully removed from the machine.
MY_SECRET_PROJECT_PATH\LicenseServiceWebApi> dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\aspnetdev.pfx -p <водкабалалайка>
The HTTPS developer certificate was generated successfully.
MY_SECRET_PROJECT_PATH\LicenseServiceWebApi> dotnet dev-certs https --trust
Trusting the HTTPS development certificate was requested. A confirmation prompt will be displayed if the certificate was not previously trusted. Click yes on the prompt to trust the certificate.
A valid HTTPS certificate is already present.
version: '3'
services:
license-service-web-api-01:
image: license-service-web-api
container_name: license-service-01
build:
context: .
dockerfile: Services/LicenseServiceWebApi/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:9001;http://+:9000
- ASPNETCORE_Kestrel__Certificates__Default__Password=${Kestrel_Certificate_Password}
- ASPNETCORE_Kestrel__Certificates__Default__Path=/root/.aspnet/https/aspnetdev.pfx
volumes:
- ${USERPROFILE}\.aspnet\https:/root/.aspnet/https/:ro
ports:
- 9000:9000
- 9001:9001
depends_on:
- consul
gateway:
image: gateway
container_name: gateway
build:
context: .
dockerfile: ApiGateway/gateway/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:5001;http://+:5000
- ASPNETCORE_Kestrel__Certificates__Default__Password=${Kestrel_Certificate_Password}
- ASPNETCORE_Kestrel__Certificates__Default__Path=/root/.aspnet/https/aspnetdev.pfx
volumes:
- ${USERPROFILE}\.aspnet\https:/root/.aspnet/https/:ro
ports:
- 5001:5001
- 5000:5000
depends_on:
- consul
consul:
image: consul
container_name: consul
command: agent -server -ui -node=server-1 -bootstrap-expect=1 -client=0.0.0.0
environment:
- 'CONSUL_LOCAL_CONFIG= {"connect": {"enabled": true}}'
ports:
- 8500:8500
{
"Routes": [
{
"SwaggerKey": "License Service",
"DownstreamPathTemplate": "/api/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "license-service-web-api-01",
"Port": 9000
}
],
"UpstreamHttpMethod": [ "Put", "Post", "GET" ],
"UpstreamPathTemplate": "/{everything}",
"LoadBalancerOptions": {
"Type": "LeastConnection"
},
"FileCacheOption": {
"TtlSeconds": 30
}
},
{
"DownstreamPathTemplate": "/swagger/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "license-service-web-api-01",
"Port": 9000
}
],
"UpstreamPathTemplate": "/swagger/{everything}",
"FileCacheOption": {
"TtlSeconds": 666
}
}
],
"SwaggerEndPoints": [
{
"Key": "License Service",
"Config": [
{
"Name": "License Service API",
"Version": "v1",
"Service": {
"Name": "License Service",
"Path": "/swagger/v1/swagger.json"
}
}
]
}
]
}
Name Command State Ports
----------------------------------------------------------------------------------------------------------------------------------------------------------
consul docker-entrypoint.sh agent ... Up 8300/tcp, 8301/tcp, 8301/udp, 8302/tcp, 8302/udp, 0.0.0.0:8500->8500/tcp, 8600/tcp, 8600/udp
gateway dotnet gateway.dll Up 443/tcp, 0.0.0.0:5000->5000/tcp, 0.0.0.0:5001->5001/tcp
license-service-01 dotnet LicenseServiceWebAp ... Up 443/tcp, 0.0.0.0:9000->9000/tcp, 0.0.0.0:9001->9001/tcp
PS C:\Users\tim> curl http://localhost:9000/api/HealthCheck/GetMachineName
StatusCode : 200
StatusDescription : OK
Content : MachineName=2a429d520129
RawContent : HTTP/1.1 200 OK
PS C:\Users\tim> curl https://localhost:9001/api/HealthCheck/GetMachineName
StatusCode : 200
StatusDescription : OK
Content : MachineName=2a429d520129
RawContent : HTTP/1.1 200 OK
PS C:\Users\tim> curl http://localhost:5000/HealthCheck/GetMachineName
StatusCode : 200
StatusDescription : OK
Content : MachineName=2a429d520129
RawContent : HTTP/1.1 200 OK
PS C:\Users\tim> curl https://localhost:5001/HealthCheck/GetMachineName
StatusCode : 200
StatusDescription : OK
Content : MachineName=2a429d520129
RawContent : HTTP/1.1 200 OK
I added an https redirect in my service
app.UseHttpsRedirection();
PS C:\Users\tim> curl http://localhost:9000/api/HealthCheck/GetMachineName
StatusCode : 200
StatusDescription : OK
Content : MachineName=345437c4c182
RawContent : HTTP/1.1 200 OK
PS C:\Users\tim> curl https://localhost:9001/api/HealthCheck/GetMachineName
StatusCode : 200
StatusDescription : OK
Content : MachineName=345437c4c182
RawContent : HTTP/1.1 200 OK
PS C:\Users\tim> curl http://localhost:5000/HealthCheck/GetMachineName
curl : Unable to resolve the remote name: 'license-service-web-api-01'
docker-compose logs ..
gateway | info: Ocelot.RateLimit.Middleware.ClientRateLimitMiddleware[0]
gateway | requestId: 0HM6VQAI1UTJU:00000002, previousRequestId: no previous request id, message: EndpointRateLimiting is not enabled for /api/{everything}
gateway | info: Ocelot.Authentication.Middleware.AuthenticationMiddleware[0]
gateway | requestId: 0HM6VQAI1UTJU:00000002, previousRequestId: no previous request id, message: No authentication needed for /HealthCheck/GetMachineName
gateway | info: Ocelot.Authorization.Middleware.AuthorizationMiddleware[0]
gateway | requestId: 0HM6VQAI1UTJU:00000002, previousRequestId: no previous request id, message: /api/{everything} route does not require user to be authorized
gateway | info: Ocelot.Requester.Middleware.HttpRequesterMiddleware[0]
gateway | requestId: 0HM6VQAI1UTJU:00000002, previousRequestId: no previous request id, message: 307 (Temporary Redirect) status code, request uri: http://license-service-web-api-01:9000/api/HealthCheck/GetMachineName
PS C:\Users\tim> curl https://localhost:5001/HealthCheck/GetMachineName
curl : Unable to resolve the remote name: 'license-service-web-api-01'
..The logs are the same
I'm changed configuration file ocelot.json on https and port 9001
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "license-service-web-api-01",
"Port": 9001
}
],
AND
removed line app.UseHttpsRedirection();
in my service
GET https://localhost:5001/WeatherForecast
502
225 ms
Warning: Unable to verify the first certificate
GET /WeatherForecast HTTP/1.1
User-Agent: PostmanRuntime/7.26.8
Accept: */*
Postman-Token: 6cafa9e0-e195-4082-a7d4-daac4f58dff7
Host: localhost:5001
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
HTTP/1.1 502 Bad Gateway
Date: Fri, 05 Mar 2021 14:50:01 GMT
Server: Kestrel
Content-Length: 0
gateway | info: Ocelot.RateLimit.Middleware.ClientRateLimitMiddleware[0]
gateway | requestId: 0HM6VSNQ8J5GI:00000002, previousRequestId: no previous request id, message: EndpointRateLimiting is not enabled for /api/{everything}
gateway | info: Ocelot.Authentication.Middleware.AuthenticationMiddleware[0]
gateway | requestId: 0HM6VSNQ8J5GI:00000002, previousRequestId: no previous request id, message: No authentication needed for /WeatherForecast
gateway | info: Ocelot.Authorization.Middleware.AuthorizationMiddleware[0]
gateway | requestId: 0HM6VSNQ8J5GI:00000002, previousRequestId: no previous request id, message: /api/{everything} route does not require user to be authorized
gateway | warn: Ocelot.Responder.Middleware.ResponderMiddleware[0]
gateway | requestId: 0HM6VSNQ8J5GI:00000002, previousRequestId: no previous request id, message: Error Code: ConnectionToDownstreamServiceError Message: Error connecting to downstream service, exception: System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
gateway | ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure: RemoteCertificateNameMismatch, RemoteCertificateChainErrors
gateway | at System.Net.Security.SslStream.SendAuthResetSignal(ProtocolToken message, ExceptionDispatchInfo exception)
gateway | at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
gateway | at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean async, Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
gateway | --- End of inner exception stack trace ---
gateway | at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean async, Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
gateway | at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
gateway | at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
gateway | at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
gateway | at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
gateway | at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
gateway | at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
gateway | at Ocelot.Requester.HttpClientHttpRequester.GetResponse(HttpContext httpContext) errors found in ResponderMiddleware. Setting error response for request path:/WeatherForecast, request method: GET
you have a ssl error last case. You may 2 options for this issue
best.option you creating your own certificate and then getting it trusted by your local or remote machine.
quick option you can add this line your ocelot.json
"DangerousAcceptAnyServerCertificateValidator": true
you should add networks
tag on your docker-compose file.
like below:
version: '3'
networks:
dockerapi:
driver: bridge
services:
license-service-web-api-01:
image: license-service-web-api
container_name: license-service-01
build:
context: .
dockerfile: Services/LicenseServiceWebApi/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:9001;http://+:9000
- ASPNETCORE_Kestrel__Certificates__Default__Password=${Kestrel_Certificate_Password}
- ASPNETCORE_Kestrel__Certificates__Default__Path=/root/.aspnet/https/aspnetdev.pfx
volumes:
- ${USERPROFILE}\.aspnet\https:/root/.aspnet/https/:ro
ports:
- 9000:9000
- 9001:9001
depends_on:
- consul
networks:
- dockerapi
gateway:
image: gateway
container_name: gateway
build:
context: .
dockerfile: ApiGateway/gateway/Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:5001;http://+:5000
- ASPNETCORE_Kestrel__Certificates__Default__Password=${Kestrel_Certificate_Password}
- ASPNETCORE_Kestrel__Certificates__Default__Path=/root/.aspnet/https/aspnetdev.pfx
volumes:
- ${USERPROFILE}\.aspnet\https:/root/.aspnet/https/:ro
ports:
- 5001:5001
- 5000:5000
depends_on:
- consul
networks:
- dockerapi