Activation du TLS sur SQL Server dans un container Docker orchestré par Docker-Compose
Dernièrement lors d’une migration .Net 6 vers .Net 8 j’ai eu à faire un changement de comportement sur un de mes conteneurs Docker SQL Server. L’encryption est maintenant activée par défaut.
Ce changement de comportement lors du passage de .Net 6 à 8 se traduit coté client par l’erreur suivante :
A connection was successfully established with the server, but then an error occurred during the pre-login handshake
Plutot que de passer ce paramètre à faux, je décide de mettre en place la configuration pour activer l’encryption.
De base mon conteneur mssql était configuré directement dans mon fichier docker-compose-yml. Ce fichier contient également la création du conteneur pour une API ASP.NET 8
version: '3.4'
services:
sqldb:
image: mcr.microsoft.com/mssql/server:2019-latest
environment:
- ACCEPT_EULA=Y
ports:
- "1440:1433"
myDotnetApi:
image: ${DOCKER_REGISTRY-}mydotnetapi
build:
context: .
dockerfile: mydotnetapi/Dockerfile
ports:
- "5000:80"
- "5001:443"
depends_on:
- sqldb
volumes:
- C:/hostpath/:/app/containerpath
Après quelques essais infructueux je m’apperçoie que l’on ne peut passer directement les certificats à sql server dans ce type de configuration via les variables d’environnements. On se retrouve confronté à une erreur de chargement de certificat au démarrage du conteneur sqlserver :
The server could not load the certificate it needs to initiate an SSL connection. It returned the following error: 0x80090331. Check certificates to make sure they are valid.
Unable to initialize SSL encryption because a valid certificate could not be found, and it is not possible to create a self-signed certificate.
Error: 17182, Severity: 16, State: 1.
Environements
Je précise que mon post de développement est sous windows 10 avec docker qui tourne sous WSL.. Mon serveur de développement qui héberge pour les tests l’api et le conteneur sql tourne lui sur ubuntu avec docker.
Mise en place de certificat pour SQL Server sur Docker avec Docker Compose
En suivant ces quelques étapes vous pourrez mettre en place l’encryption de la connexion à votre sql server dockerisé.
Etape 1 Génération du certificat depuis le host
Il suffit de suivre la documentation Microsoft pour la génération de certificat SSL avec OpenSSL :
openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=mydotnetapi.com' -keyout ./mssql/certs/mssql.key -out ./mssql/certs/mssql.pem -days 365
Création de la configuration SQL Server pour le support du TLS
Créer un fichier mssql.conf
[EULA]
accepteula = Y
[network]
tlscert = /certs/mssql.pem
tlskey = /certs/mssql.key
tlsprotocols = 1.2
forceencryption = 0
Etape 3 Création du Dockerfile pour le container MSSQL
Le problème de chargement de certificat évoqué plus haut est lié à une problématique de droit sur ces derniers, il faut donc faire un chmod sur les certificats pour affecter les bons droits.
FROM mcr.microsoft.com/mssql/server:2019-latest
COPY --chown=mssql --chmod=440 certs/mssql.pem /certs/
COPY --chown=mssql --chmod=400 certs/mssql.key /certs/
COPY --chown=mssql mssql.conf /var/opt/mssql/mssql.conf
Etape 4 Modification du docker-compose.yml
version: '3.4'
services:
sqldb:
container_name: sqlserver
build:
context: mssql/
dockerfile: Dockerfile
restart: always
environment:
ports:
- "1440:1433"
myDotnetApi:
...
volumes:
msdata:
name: "mssql"
En cas d’erreur de build docker-compose
Si vous rencontrez l’erreur suivante sur votre host linux en rebuildant votre container :
failed to build : the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled
Vous pouvez exécuter les comanndes suivantes pour définir les variables d’environnement sur le host
Linux
export DOCKER_BUILDKIT=1 # or configure in daemon.json
export COMPOSE_DOCKER_CLI_BUILD=1
Windows
setx DOCKER_BUILDKIT 1 # or configure in daemon.json
setx COMPOSE_DOCKER_CLI_BUILD 1
Merci de m’avoir lu et bonne journée.