Dernière mise à jour

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.