Open ajaygoyal opened 8 months ago
Did you install downloaded cert inside your test-app
container?
Could you check the example YAML file and this folder in the .NET examples. This example shows how to use Cosmos DB Emulator with containers and networks. The example, also shows how to download and install certs into your test app, that connects to the Emulator.
Is there a way to make this work without using HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
as a cert validation callback? I am trying to set up effectively the same application as the example, but with the Azure Cosmos DB Migration Tool where I can't make this configuration, and removing that from the example app causes the same RemoteCertificateNameMismatch error.
I am not super confident on my understanding of SSL certificates, but is it possible to use the /GenCert={host name for the service} arg to make this work? I have been following this example from another issue and tried overriding the ./startup.sh
file to use said argument, but at that point the emulator will not start.
This really seem like an oversight. I can't use cosmos emulator in devcontainer because of this simple issue... one thing could be to add the hostname as an alternate name in the certificate.
I got it working without using the HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
.
I inspected the certificate and found out that it does contains alternate subject name, but there a twist, you have to declare a hostname for your service.
docker-compose.yml (good)
version: '3'
services:
cosmos:
image: mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest
hostname: cosmos # <-- required
restart: unless-stopped
ports:
- 8081:8081
networks:
game:
aliases:
- "cosmos.domain" # <-- required
If you don't specifiy a hostname, docker will generate a random one example:
docker-compose.yml (bad)
version: '3'
services:
cosmos:
image: mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest
# hostname: cosmos
restart: unless-stopped
ports:
- 8081:8081
networks:
game:
aliases:
- "cosmos.domain" # <-- required
Note: I tried using the cosmosdbemulatormtls.localhost
but it doesn't work (problably because of the .localhost
at the end).
The hostname doesn't have to be cosmos
, i just choose that name, but if you change it don't forget to update the aliase use in the docker compose file.
docker-compose.yml (alternate config good)
version: '3'
services:
cosmos:
image: mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest
hostname: othername
restart: unless-stopped
ports:
- 8081:8081
networks:
game:
aliases:
- "othername.domain"
Once the cosmos emulator container is started, it take a minute or so to be able to retrieve the certificate.
I'm currently setting up a devcontainer using cosmos emulator and added this in my postCreateCommand.sh
script:
#!/bin/bash
echo "Installing cosmos db emulator ssl certificate"
mkdir /usr/share/ca-certificates/cosmos
for i in {1..60};
do
curl -fsk https://cosmos.domain:8081/_explorer/emulator.pem > /usr/share/ca-certificates/cosmos/emulator.crt
if [ $? -eq 0 ]; then
echo "Cosmos emulator ready"
break
else
echo "Not ready yet..."
sleep 10
fi
done
chmod o+r /usr/share/ca-certificates/cosmos/emulator.crt
echo "cosmos/emulator.crt" >> /etc/ca-certificates.conf
update-ca-certificates
after this, you will need to use the cosmos.domain:8081
(update the port number if your setup use an another port)
appsetings.Development.json
{
// ...
"ConnectionStrings": {
"CosmosConnection": "AccountEndpoint=https://cosmos.domain:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
},
// ...
}
The account key is the default one used by the cosmos emulator, so you can copy-paste the connection string for you use.
Additional information to the post above:
curl is default not installed. So for automation, you need to install curl.
This is the example snippet to the Dockerfile
of the asp.net project
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
RUN apt-get update && apt-get install -y curl
EXPOSE 8080
Credit: https://stackoverflow.com/questions/73678713/how-to-install-curl-from-dockerfile
PS: after add this RUN
line, you need to delete relevant containers and re-pull and build.
But..... I still get SSL error:
The SSL connection could not be established, see inner exception.
InnerException: The remote certificate is invalid according to the validation procedure: RemoteCertificateNameMismatch, RemoteCertificateChainErrors
I'm getting the same as @cdytoby... Any ideas beyond just disabling SSL validation for now?
Okay, so I worked out my problem.
The cosmos.domain
listed as an alias above isn't just "any generic domain" it's literally ".domain".
Seems to me you can summarise that long post into:
hostname
in your compose (not/as well as the container_name
).<hostname>.domain
This will then ensure that you can resolve the emulator with a hostname that is present in the certificate's alternate names
You can probably get all of this from the long answer above, but I missed it so figured I'd share what I learned a bit more concisely.
So following on from my last post, I can go one better.
I don't think you even need the alias, just set the hostname to cosmos.domain
and refer to it through that everywhere else. I'd even recommend leaving out the container_name
so you can't resolve it any other way unless you really like having nicely named containers.
cosmos-db-emulator:
image: mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest
hostname: cosmos.domain # <--- This .domain is the only thing that matters really
environment:
AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE: true
AZURE_COSMOS_EMULATOR_PARTITION_COUNT: 1
networks:
- internal
I have a .net 6 app that needs to connect to cosmos db emulator.
I have below setup:
test-app: env_file:
container_network
cosmosdb_emulator: image: mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator ports:
Downloaded the cert on host using: curl -k https://host.docker.internal:8081/_explorer/emulator.pem > /c/certs/emulatorcert.crt
But application fails to connect to the cosmos with below error:
2023-10-22 20:06:51 ---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. 2023-10-22 20:06:51 ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure: RemoteCertificateNameMismatch
Disabling SSL is not something that we want to do.