Sécurisation des connexions PostgreSQL avec la configuration SSL/TLS : Guide complet

Apprenez à sécuriser les connexions PostgreSQL avec le chiffrement SSL/TLS. Ce guide complet couvre la configuration côté serveur et client, y compris la génération de certificats, la modification de `postgresql.conf` et `pg_hba.conf`, et la configuration des clients pour une communication sécurisée et chiffrée. Protégez vos données sensibles en transit et assurez la conformité aux normes de sécurité modernes.

Sécurisation des connexions PostgreSQL avec la configuration SSL/TLS : Guide complet

La configuration SSL/TLS de PostgreSQL comporte deux tâches distinctes. La première est le chiffrement, afin qu'une personne sur le réseau ne puisse pas lire les identifiants ou les résultats de requêtes en transit. La seconde est l'identité, afin que le client sache qu'il communique avec le véritable serveur de base de données et non avec une machine se faisant passer pour lui. De nombreuses configurations réalisent la première partie et oublient accidentellement la seconde.

Cette distinction est importante dans les déploiements réels. sslmode=require chiffre la connexion, mais en soi, il ne vérifie pas complètement le nom d'hôte du serveur. sslmode=verify-full le fait. Si votre application se connecte via un réseau public, un réseau d'entreprise partagé, un overlay Kubernetes que vous ne contrôlez pas entièrement, ou tout environnement où le trafic pourrait être intercepté, verify-full devrait être l'objectif.

Comprendre SSL/TLS dans PostgreSQL

SSL/TLS (Secure Sockets Layer/Transport Layer Security) est un protocole cryptographique conçu pour assurer la sécurité des communications sur un réseau informatique. Appliqué à PostgreSQL, il chiffre les données échangées entre le serveur de base de données et ses clients. Cela empêche les parties non autorisées d'intercepter et de lire des informations sensibles comme les identifiants, les données financières ou les détails personnels.

Les clients PostgreSQL prennent en charge plusieurs modes SSL :

  • sslmode=disable : Utiliser uniquement une connexion simple non chiffrée.
  • sslmode=prefer : Essayer d'abord TLS, puis revenir au TCP simple si TLS n'est pas disponible. C'est pratique, mais cela peut masquer une mauvaise configuration.
  • sslmode=require : Exiger le chiffrement TLS, mais ne pas nécessairement vérifier le nom d'hôte du serveur.
  • sslmode=verify-ca : Exiger TLS et vérifier que le certificat chaîne jusqu'à une CA de confiance.
  • sslmode=verify-full : Exiger TLS, vérifier la CA et vérifier que le nom d'hôte correspond au certificat.

Côté serveur, ssl = on signifie seulement que PostgreSQL est capable d'accepter des connexions TLS. Cela ne force pas chaque client à utiliser TLS. L'application se fait dans pg_hba.conf avec des règles hostssl et en évitant les règles host plus larges qui permettraient aux mêmes utilisateurs et réseaux de se connecter sans TLS.

Prérequis pour la configuration SSL/TLS

Avant de commencer à configurer PostgreSQL pour SSL/TLS, assurez-vous d'avoir les éléments suivants :

  1. OpenSSL installé : La boîte à outils OpenSSL est essentielle pour générer et gérer les certificats SSL. Elle est généralement préinstallée sur les systèmes Linux et macOS. Pour Windows, vous devrez peut-être la télécharger et l'installer séparément.
  2. Accès aux fichiers de configuration PostgreSQL : Vous aurez besoin de privilèges administratifs pour modifier les fichiers postgresql.conf et pg_hba.conf.
  3. Compréhension des autorités de certification (CA) : Bien que vous puissiez créer des certificats auto-signés pour les tests, les environnements de production devraient idéalement utiliser des certificats signés par une autorité de certification (CA) de confiance ou une CA d'entreprise interne.

Configuration SSL/TLS côté serveur

La configuration côté serveur implique l'activation de SSL, la spécification de l'emplacement des certificats et clés SSL, et la configuration de l'authentification client.

1. Génération ou obtention de certificats et clés SSL

Il existe deux principales façons d'obtenir des certificats SSL pour votre serveur PostgreSQL :

  • Certificats auto-signés (pour les tests/développement) : Ceux-ci sont créés à l'aide d'OpenSSL et ne sont pas approuvés par défaut par les clients externes. Ils sont utiles pour la configuration initiale et les tests internes.
  • Certificats d'une autorité de certification (CA) (pour la production) : Obtenez des certificats d'une CA publique de confiance (par exemple, Let's Encrypt, DigiCert) ou d'une CA d'entreprise interne. Cela garantit que les clients peuvent vérifier l'identité du serveur.

Création de certificats auto-signés avec OpenSSL :

C'est une approche courante pour les environnements de développement et internes. Exécutez les commandes suivantes sur votre serveur PostgreSQL ou une machine avec OpenSSL :

  1. Créez un répertoire pour les certificats : Il est de bonne pratique de garder les certificats organisés.

    sudo mkdir -p /etc/postgresql/ssl
    sudo chown postgres:postgres /etc/postgresql/ssl
    cd /etc/postgresql/ssl
    
  2. Générez la clé privée du serveur : Cette clé doit rester secrète.

    sudo openssl genrsa -out server.key 2048
    
  3. Créez une demande de signature de certificat (CSR) du serveur : Elle contient des informations sur votre serveur.

    sudo openssl req -new -key server.key -out server.csr
    

    Utilisez le nom d'hôte auquel vos clients se connecteront, par exemple db01.internal.example.com. Les clients modernes vérifient normalement le Subject Alternative Name (SAN), incluez donc les noms DNS dans la demande de certificat lorsque votre processus CA le prend en charge.

  4. Signez le certificat avec votre propre CA (pour usage interne) :

    • Créez une clé privée et un certificat de CA racine (si vous n'en avez pas) :
      # Générer la clé privée de la CA
      sudo openssl genrsa -des3 -out root.key 2048
      # Créer le certificat de la CA (valide 3650 jours)
      sudo openssl req -new -x509 -days 3650 -key root.key -out root.crt
      
    • Signez la CSR du serveur avec la CA : Cela crée le certificat de serveur de confiance.
      sudo openssl x509 -req -days 365 -in server.csr -CA root.crt -CAkey root.key -set_serial 01 -out server.crt
      
  5. Définissez les permissions : Assurez-vous que l'utilisateur PostgreSQL peut lire ces fichiers.

    sudo chown postgres:postgres server.key server.crt root.crt
    sudo chmod 600 server.key
    sudo chmod 644 server.crt root.crt
    

Utilisation de certificats d'une CA publique/d'entreprise :

Si vous obtenez des certificats d'une CA, vous recevrez généralement :

  • server.crt : Le certificat public de votre serveur.
  • server.key : La clé privée de votre serveur.
  • root.crt (ou similaire) : Le certificat racine de la CA (et potentiellement des certificats intermédiaires).

Placez ces fichiers dans un répertoire sécurisé (par exemple, /etc/postgresql/ssl/) et assurez-vous que l'utilisateur PostgreSQL a les permissions de lecture.

2. Configuration de postgresql.conf

Modifiez votre fichier postgresql.conf (généralement situé dans votre répertoire de données PostgreSQL) pour activer SSL et spécifier les fichiers de certificat.

#------------------------------------------------------------------------------
# SSL
#------------------------------------------------------------------------------

ssl = on

# Ceux-ci sont tous au format PEM, et sont ignorés si la clé/certificat du serveur
# ne sont pas configurés. Par défaut, les fichiers sont censés se trouver dans le
# répertoire de données du serveur. Alternativement, ils peuvent être spécifiés
# comme chemins complets.
ssl_cert_file = '/etc/postgresql/ssl/server.crt'     # (modifier le nom du fichier si nécessaire)
ssl_key_file = '/etc/postgresql/ssl/server.key'      # (modifier le nom du fichier si nécessaire)
ssl_ca_file = '/etc/postgresql/ssl/root.crt'         # (optionnel, pour la vérification du certificat client)

# Optionnel : spécifier la liste de chiffrement si nécessaire
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'

# Optionnel : activer la vérification du certificat client
#ssl_ca_file doit être défini sur un fichier contenant le(s) certificat(s) CA de confiance
#ssl_crl_file = ''
#ssl_crl_dir = ''
  • ssl = on : Active le support SSL sur le serveur.
  • ssl_cert_file : Chemin vers le certificat public du serveur.
  • ssl_key_file : Chemin vers la clé privée du serveur.
  • ssl_ca_file : Chemin vers les certificats CA auxquels PostgreSQL doit faire confiance lors de la vérification des certificats clients. Les clients utilisent leur propre fichier CA, comme sslrootcert, pour vérifier le serveur.

3. Configuration de pg_hba.conf pour l'application de SSL

Le fichier pg_hba.conf contrôle l'authentification des clients. Vous devez modifier les entrées pour appliquer les connexions SSL.

Par défaut, les entrées dans pg_hba.conf ressemblent à ceci :

# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     peer
# Connexions locales IPv4 :
host    all             all             127.0.0.1/32            scram-sha-256
# Connexions locales IPv6 :
host    all             all             ::1/128                 scram-sha-256

Pour appliquer SSL, changez les entrées host en hostssl :

# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     peer
# Connexions locales IPv4 :
hostssl all             all             127.0.0.1/32            scram-sha-256
# Connexions locales IPv6 :
hostssl all             all             ::1/128                 scram-sha-256

# Exemple pour un accès réseau externe - nécessite SSL
hostssl all             app_user        10.20.0.0/16            scram-sha-256
hostssl all             app_user        2001:db8:20::/48        scram-sha-256
  • hostssl : Ce type d'enregistrement nécessite des connexions SSL. Toute tentative de connexion sans SSL sera rejetée.
  • hostnossl : Ce type d'enregistrement interdit explicitement les connexions SSL.
  • host : Autorise les connexions SSL et non SSL. Si une règle host correspondante existe avant ou à la place de votre règle hostssl, les clients peuvent toujours se connecter sans TLS.

Évitez de publier un accès 0.0.0.0/0 sauf s'il y a une raison impérieuse et que d'autres contrôles sont en place. La plupart des bases de données de production ne devraient accepter les connexions que depuis les sous-réseaux d'application, les hôtes bastion, les poolers de connexion ou les plages de réseau privé.

4. Redémarrage du serveur PostgreSQL

Après avoir modifié postgresql.conf et pg_hba.conf, vous devez redémarrer le service PostgreSQL pour que les modifications prennent effet.

# Pour les systèmes utilisant systemd (la plupart des distributions Linux modernes)
sudo systemctl restart postgresql

# Pour les systèmes utilisant init.d
sudo service postgresql restart

Configuration SSL/TLS côté client

Les clients doivent également être configurés pour se connecter de manière sécurisée. Cela implique de spécifier les paramètres de connexion, de fournir éventuellement des certificats clients et de vérifier le certificat du serveur.

1. Paramètres de chaîne de connexion

Lors de la connexion via psql ou toute bibliothèque cliente PostgreSQL, vous pouvez spécifier les paramètres SSL dans la chaîne de connexion ou comme options individuelles.

Connexion SSL de base (authentification du serveur uniquement) :

psql "sslmode=require host=votre_nom_hote_serveur dbname=votre_bd user=votre_utilisateur"
  • sslmode : Contrôle le comportement SSL du client.
    • disable : Autoriser uniquement les connexions non SSL.
    • allow : Autoriser les connexions non SSL, mais préférer SSL si le serveur le supporte.
    • prefer (par défaut) : Préférer SSL, mais autoriser les connexions non SSL si SSL échoue.
    • require : Autoriser uniquement les connexions SSL. Si le serveur ne supporte pas SSL, la connexion échoue.
    • verify-ca : Autoriser uniquement les connexions SSL et vérifier que le certificat du serveur est signé par une CA de confiance. Le paramètre sslrootcert doit être défini.
    • verify-full : Autoriser uniquement les connexions SSL, vérifier le certificat du serveur par rapport à une CA de confiance, et vérifier que le nom d'hôte du serveur correspond au nom commun (CN) ou au Subject Alternative Name (SAN) du certificat.

Vérification du certificat du serveur (verify-ca ou verify-full) :

Pour une sécurité renforcée, les clients doivent vérifier l'identité du serveur. Cela nécessite que le client fasse confiance à la CA qui a signé le certificat du serveur.

  1. Obtenez le certificat CA : Récupérez le fichier root.crt (ou le certificat CA approprié) qui a été utilisé pour signer le certificat du serveur.
  2. Spécifiez sslrootcert : Indiquez au client où trouver ce certificat CA.
psql "sslmode=verify-full host=votre_nom_hote_serveur dbname=votre_bd user=votre_utilisateur sslrootcert=/chemin/vers/votre/root.crt"

C'est la chaîne de connexion que vous devriez tester depuis le même hôte ou conteneur qui exécute l'application. Un échec courant est que psql fonctionne depuis un ordinateur portable d'administrateur parce que le fichier CA s'y trouve, tandis que le conteneur d'application échoue parce que le bundle CA n'a jamais été monté.

2. Certificats clients (authentification mutuelle)

Pour un niveau de sécurité encore plus élevé, vous pouvez implémenter une authentification mutuelle, où le serveur vérifie également l'identité du client à l'aide de certificats clients.

Génération de certificats clients :

Similaire aux certificats serveur, vous aurez besoin d'une clé privée client et d'un certificat client signé par une CA approuvée par le serveur (souvent la même CA que le certificat serveur).

  1. Générez la clé privée client :

    openssl genrsa -des3 -out client.key 2048
    
  2. Créez la CSR client :

    openssl req -new -key client.key -out client.csr
    

    Fournissez les détails, en vous assurant que le Common Name est unique pour le client.

  3. Signez la CSR client avec la CA :

    sudo openssl x509 -req -days 365 -in client.csr -CA root.crt -CAkey root.key -set_serial <numéro_serie_unique> -out client.crt
    
  4. Définissez les permissions :

    chmod 600 client.key
    chmod 644 client.crt
    

Configuration de pg_hba.conf pour l'authentification par certificat client :

Sur le serveur, vous devez configurer pg_hba.conf pour accepter l'authentification par certificat client. Cela utilise souvent la méthode d'authentification cert.

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# Exiger SSL et l'authentification par certificat client pour un utilisateur/bd spécifique
hostssl all             votre_utilisateur       votre_ip_client/32       cert map=votre_cert_map

Vous pourriez également avoir besoin de définir un fichier de mappage de certificats (option cert_map) si vous souhaitez mapper des détails spécifiques du certificat client (comme Subject ou SubjectAltName) aux utilisateurs PostgreSQL. Consultez la documentation PostgreSQL pour une configuration détaillée de l'authentification cert et du mappage de certificats.

Configuration du client pour utiliser les certificats :

Mettez à jour la chaîne de connexion du client pour inclure les chemins vers son certificat et sa clé :

psql "sslmode=verify-full host=votre_nom_hote_serveur dbname=votre_bd user=votre_utilisateur \
sslrootcert=/chemin/vers/votre/root.crt sslcert=/chemin/vers/votre/client.crt sslkey=/chemin/vers/votre/client.key"

Meilleures pratiques et conseils

  • Utilisez sslmode=verify-full : Visez à utiliser verify-full côté client pour réduire le risque d'attaque de l'homme du milieu.
  • Protégez les clés privées : Assurez-vous que les clés privées (fichiers .key) ont des permissions de fichier strictes (par exemple, chmod 600) et ne sont lisibles que par l'utilisateur PostgreSQL sur le serveur et l'utilisateur connecté sur le client.
  • Renouvelez régulièrement les certificats : Les certificats ont des dates d'expiration. Mettez en place un processus pour les renouveler avant leur expiration afin d'éviter les interruptions de connexion.
  • Gestion centralisée des certificats : Pour les déploiements plus importants, envisagez d'utiliser un système de gestion des certificats ou d'automatiser l'émission et le renouvellement des certificats.
  • Surveillez les journaux : Vérifiez les journaux PostgreSQL pour toute erreur liée à SSL lors du démarrage ou des tentatives de connexion.
  • Documentation : Référez-vous à la documentation officielle de PostgreSQL pour les paramètres les plus à jour et les options de configuration avancées spécifiques à votre version de PostgreSQL.

Liste de vérification rapide

Après avoir redémarré PostgreSQL, vérifiez que le serveur écoute avec TLS activé :

SHOW ssl;
SHOW ssl_cert_file;
SHOW ssl_key_file;

Testez ensuite depuis un hôte client :

psql "host=votre_nom_hote_serveur dbname=votre_bd user=votre_utilisateur sslmode=verify-full sslrootcert=/chemin/vers/root.crt"

Dans la session, confirmez que la connexion est chiffrée :

SELECT ssl, version, cipher
FROM pg_stat_ssl
WHERE pid = pg_backend_pid();

Si ssl est faux, vos règles pg_hba.conf n'appliquent pas ce que vous pensez. Si verify-full échoue mais que require fonctionne, le certificat manque probablement du bon nom d'hôte, le client ne fait pas confiance à la CA, ou l'application se connecte par adresse IP alors que le certificat est émis pour un nom DNS.

Une bonne configuration TLS de PostgreSQL n'est pas seulement ssl = on. C'est une chaîne : un certificat avec les bons noms, des clés privées avec des permissions strictes, des règles hostssl qui appliquent réellement TLS, et des clients qui vérifient le serveur au lieu de simplement chiffrer le socket.