Configuration SSL des connexions avec SQL Server 2019 sur Linux

Introduction

Modifier le port de SQL Server installé dans une zone WAN/DMZ n'est pas suffisant d'un point de vue sécurité, cela diminue les attaques potentielles mais n'empêche pas des outils de "snif" de lire les paquets TCP.

Architecture Linux SQL Server 2019

En utilisant tcpdump, il est facile de capturer les paquets réseaux TDS puis de lire le contenu de ces paquets (requêtes et réponses) avec WireShark par exemple :

root@vps$ tcpdump -nnXSs 0 'port 35027' -w mssql.pcap
mssql.pcap (lecture avec  Wireshark)
SQL Batch (Request)  Response TDS
===================  ================
S.E.L.E.C.T. .T.     0.9.1...a.d.v.e.
O.P. .(.1.0.0.0.     n.t.u.r.e.-.w.o.
). .[.B.u.s.i.n.     r.k.s.\.s.a.m.e.
e.s.s.E.n.t.i.t.     e.r.0...........
y.I.D.]..... . .     ..z.........8.P.
 . . . .,.[.N.a.     r.o.d.u.c.t.i.o.
                     n. .T.e.c.h.n.i.
...                  c.i.a.n. .-. .W.
                     ...
e.]..... . .F.R.
O.M. .[.A.d.v.e.
n.t.u.r.e.W.o.r.
k.s.]...[.H.u.m.
a.n.R.e.s.o.u.r.
c.e.s.]...[.E.m.
p.l.o.y.e.e.].

Les requêtes, les noms des tables et colonnes, les données envoyées et reçues sont dans un format lisible.

Voyons comment encrypter les paquets avec SSL / TLS 1.2 pour SQL Server sous Linux. L'encryption est initiée et forcée par le serveur SQL Server avec un certificat auto-signé (self-signed certificate) : c'est la méthode la plus simple, il n'y a pas utilité de validation du certificat serveur par une autorité pour les connexions, méthode qui implique alors une configuration à faire sur les clients.

openssl

Vérifier la version d'OpenSSL installée sur le système :

mssql@vps$ which openssl
          
/usr/bin/openssl
          
mssql@vps$ openssl version
          
OpenSSL 1.1.1  11 Sep 2018

Si pour une raison ou une autre (sécurité etc...) une version spécifique d'OpenSSL, autre que la version système, doit être utilisée : dans le répertoire /opt/mssql/lib/ créér les liens symboliques libcrypto.so et libssl.so vers les librairies de la bonne version d'openssl.

Génération des certificats

En tant que root, avec OpenSSL, générer les certificats dans le répertoire où vous souhaitez les installer :

root@vps$ cd /software/mssql/mssql-2019-ctp3/ssl

root@vps$ openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=vps.mydomain.com' \
            -keyout mssql.key \
            -out mssql.pem \
            -days 365
  • Le paramètre CN doit être le nom complet du serveur hôte (host fully-qualified name - FQN).
  • Les certificats ont une validité d'1 an ici (-days 365)

La sortie doit ressembler à ceci :

Generating a RSA private key
........................................................+++++
..........................................................+++++
writing new private key to 'mssql.key'

Si le message d'erreur ci-dessous est affiché :

Can't load /root/.rnd into RNG
140480710107584:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:88:Filename=/root/.rnd

Commenter la ligne suivante dans le fichier /etc/ssl/openssl.cnf :

/etc/ssl/openssl.cnf
# RANDFILE              = $ENV::HOME/.rnd

Modifier le propriétaire à mssql et appliquer les permissions adéquates pour ces certificats :

root@vps$ chown mssql:mssql mssql.pem mssql.key
          
root@vps$ chmod 600 mssql.pem mssql.key

Configuration SQL Server avec mssql-conf

Lorsque l'encryption est initiée par le moteur SQL Server, appliquer les paramètres suivants avec l'utilitaire mssql-conf.

mssql@vps$ /opt/mssql/bin/mssql-conf set network.tlscert /software/mssql/mssql-2019-ctp3/ssl/mssql.pem 
mssql@vps$ /opt/mssql/bin/mssql-conf set network.tlskey /software/mssql/mssql-2019-ctp3/ssl/mssql.key 
mssql@vps$ /opt/mssql/bin/mssql-conf set network.tlsprotocols 1.2 
mssql@vps$ /opt/mssql/bin/mssql-conf set network.forceencryption 1

Le service mssql-server est redémarré :

mssql@vps$ sudo systemctl restart mssql-server

Dans le fichier de log de SQL Server, si il n'y aucun souci de configuration, les informations ci-dessous sont consignées :

2019-06-01 14:09:35.51 Server      Successfully initialized the TLS configuration.
Allowed TLS protocol versions are ['1.2'].
Allowed TLS ciphers are ['ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:!DHE-RSA-AES256-GCM-SHA384:!DHE-RSA-AES128-GCM-SHA256:!DHE-RSA-AES256-SHA:!DHE-RSA-AES128-SHA'].

Vérification des connexions en SSL / TLS 1.2

En utilisant sqlcmd, SQL Server Management Studio 18, ODBC... l'encryption est maintenant forcée par le serveur.

La vue sys.dm_exec_connections confirme l'encryption :

mssql@vps$ sqlcmd -Usa -S vps
        
select encrypt_option from sys.dm_exec_connections where session_id=64
go
        
encrypt_option
----------------------------------------
TRUE
ODBC Test de connexion avec encryption

Une nouvelle capture des paquets avec tcpdump montre maintenant le protocole TLS 1.2 avec des données encryptées

root@vps$ tcpdump -nnXSs 0 'port 35027' -w mssql.pcap
Wireshark capture TLS 1.2 Protocol

Conclusion

Les étapes pour implémenter l'encryption SSL/TLS 1.2 pour SQL Server sous Linux sont très simples, on pourrait même dire plus simples que sous Windows.

Le port est modifié, l'encryption SSL/TLS pour les connexions client/serveur est implémentée : maintenant SQL Server / Linux dans la zone WAN/DMZ est bien plus sécurisé.