Sécuriser PostgreSQL en cloud public avec WireGuard

Sécuriser PostgreSQL en cloud public avec WireGuard

Sommaire

La migration des bases de données vers des environnements cloud publics offre flexibilité et scalabilité, mais expose également les services à de nouvelles menaces.

PostgreSQL, souvent utilisé pour héberger des données critiques, devient une cible de choix si son accès réseau est insuffisamment protégé. Il faut donc garantir la confidentialité des échanges, authentifier les clients et limiter précisément les machines autorisées à se connecter.

WireGuard permet d’établir un tunnel chiffré entre le serveur PostgreSQL et ses clients. Le port de la base n’est alors pas publié sur Internet : il est uniquement accessible depuis le réseau privé du VPN. Cette protection réseau complète les contrôles natifs de PostgreSQL sans les remplacer.

Dans la suite, les exemples utilisent :

  • wg0 comme interface WireGuard ;
  • 10.0.0.1 comme adresse WireGuard du serveur PostgreSQL ;
  • 10.0.0.0/24 comme sous-réseau WireGuard ;
  • 5432 comme port PostgreSQL.

Adaptez ces valeurs à votre configuration.

Prérequis

  • Un VPS Ubuntu intégré à un réseau WireGuard (voir Sécuriser un VPS avec WireGuard).
  • Un client WireGuard autorisé à joindre le VPS.
  • Un accès sudo au VPS.
  • Une règle de pare-feu chez l’hébergeur qui autorise le port UDP de WireGuard, mais pas le port TCP 5432 depuis Internet.

Installation de PostgreSQL

PostgreSQL est disponible dans les dépôts officiels d’Ubuntu. Le paquet installe le serveur et crée un cluster avec une configuration adaptée à la version fournie par la distribution.

sudo apt update
sudo apt install postgresql
sudo systemctl enable --now postgresql

Vérifiez que le service est démarré :

sudo systemctl status postgresql

Localisation des fichiers de configuration

Sur Ubuntu, les fichiers se trouvent généralement dans /etc/postgresql/<version>/main/. Pour éviter de dépendre d’un numéro de version, demandez directement leur emplacement à PostgreSQL :

sudo -u postgres psql -tAc "SHOW config_file;"
sudo -u postgres psql -tAc "SHOW hba_file;"

Le premier fichier configure l’écoute réseau. Le second contrôle quels clients peuvent s’authentifier.

Écoute sur l’interface WireGuard

Par défaut, PostgreSQL n’accepte les connexions TCP que sur l’interface locale. Dans postgresql.conf, affectez à listen_addresses l’adresse WireGuard du serveur et imposez SCRAM pour les futurs mots de passe :

listen_addresses = '10.0.0.1'
password_encryption = 'scram-sha-256'

Vous pouvez ouvrir le fichier avec :

sudoedit "$(sudo -u postgres psql -tAc 'SHOW config_file;')"

Évitez listen_addresses = '*' ou 0.0.0.0 : PostgreSQL écouterait également sur l’interface publique. Les connexions d’administration locales restent possibles par le socket Unix, même si 127.0.0.1 n’apparaît pas dans listen_addresses.

Restriction des clients avec pg_hba.conf

Le fichier pg_hba.conf complète la restriction réseau. Ajoutez la règle suivante avant toute règle distante plus générale :

# TYPE  DATABASE  USER     ADDRESS      METHOD
host    ma_base   monuser  10.0.0.0/24  scram-sha-256

Pour modifier le bon fichier :

sudoedit "$(sudo -u postgres psql -tAc 'SHOW hba_file;')"

Cette ligne autorise uniquement le rôle monuser, sur la base ma_base, depuis le sous-réseau WireGuard, avec une authentification SCRAM-SHA-256. PostgreSQL utilise la première règle qui correspond à une connexion : l’ordre des lignes est donc important. Si aucune règle ne correspond, la connexion est refusée.

Redémarrez ensuite PostgreSQL. Un redémarrage est nécessaire après une modification de listen_addresses :

sudo systemctl restart postgresql

Vérifiez que PostgreSQL écoute uniquement sur l’adresse du tunnel :

sudo ss -ltnp | grep ':5432'

Le résultat doit contenir 10.0.0.1:5432, mais ni 0.0.0.0:5432 ni l’adresse IP publique du VPS.

Vous pouvez également rechercher une erreur de syntaxe dans pg_hba.conf :

sudo -u postgres psql -P pager=off -c \
  "SELECT line_number, error FROM pg_hba_file_rules WHERE error IS NOT NULL;"

La requête ne doit retourner aucune ligne.

Création du rôle et de la base

Ouvrez une session locale avec le compte d’administration postgres :

sudo -u postgres psql

Créez un rôle de connexion dédié, définissez son mot de passe sans l’inscrire dans l’historique du terminal, puis créez la base dont il sera propriétaire :

CREATE ROLE monuser LOGIN;
\password monuser

CREATE DATABASE ma_base OWNER monuser;
REVOKE CONNECT ON DATABASE ma_base FROM PUBLIC;
GRANT CONNECT ON DATABASE ma_base TO monuser;

Quittez psql avec \q. Accordez ensuite uniquement les privilèges réellement nécessaires à l’application. N’utilisez pas le superutilisateur postgres pour les connexions applicatives.

Le paramètre password_encryption s’applique au moment où le mot de passe est créé ou modifié. Sur une installation existante, il faut donc redéfinir les anciens mots de passe après le passage à SCRAM-SHA-256.

Configuration d’UFW

La politique entrante d’UFW doit déjà être restrictive, comme dans l’article consacré à WireGuard. Autorisez le port PostgreSQL uniquement sur wg0 et uniquement depuis le sous-réseau du VPN :

sudo ufw allow in on wg0 proto tcp from 10.0.0.0/24 to any port 5432
sudo ufw reload
sudo ufw status verbose

N’ajoutez pas de règle globale telle que sudo ufw allow 5432/tcp. Vérifiez également qu’aucune ancienne règle n’expose ce port sur l’interface publique.

Test de connexion

Sur le poste client, installez uniquement les outils PostgreSQL si nécessaire :

sudo apt update
sudo apt install postgresql-client

Activez le tunnel WireGuard, puis connectez-vous à l’adresse privée du serveur :

psql --host={{IP_WIREGUARD_POSTGRESQL}} \
  --port=5432 \
  --username=monuser \
  --dbname=ma_base \
  --password \
  --command='SELECT version();'

La commande demande le mot de passe et doit afficher la version de PostgreSQL.

Pour valider l’isolation, contrôlez aussi que le port 5432 ne répond pas sur l’adresse IP publique du VPS. Ce second test doit échouer :

nc -vz {{IP_PUBLIQUE_VPS}} 5432

Dépannage

Vérifier le tunnel WireGuard

Sur le client, contrôlez l’établissement du tunnel et la route vers le serveur :

sudo wg show
ping {{IP_WIREGUARD_POSTGRESQL}}

L’absence de réponse au ping n’est pas toujours significative si ICMP est filtré. Testez directement le port :

nc -vz {{IP_WIREGUARD_POSTGRESQL}} 5432
pg_isready --host={{IP_WIREGUARD_POSTGRESQL}} --port=5432

Vérifier PostgreSQL sur le serveur

sudo systemctl status postgresql
sudo ss -ltnp | grep ':5432'
sudo journalctl -u postgresql --since "15 minutes ago"

Une connexion refusée indique généralement que le service n’écoute pas sur la bonne adresse. Un délai d’attente pointe plutôt vers WireGuard, le routage, UFW ou le pare-feu de l’hébergeur.

Vérifier les règles d’accès

sudo ufw status verbose
sudo -u postgres psql -P pager=off -c \
  "SELECT line_number, type, database, user_name, address, auth_method, error FROM pg_hba_file_rules;"

Le message no pg_hba.conf entry signifie que l’adresse source, la base ou le rôle ne correspond à aucune règle. Le message password authentication failed invite à vérifier le mot de passe du rôle et à le redéfinir afin qu’il soit stocké au format SCRAM-SHA-256.

Conclusion

Cette configuration superpose plusieurs contrôles complémentaires :

  • WireGuard chiffre le trafic entre les pairs autorisés ;
  • PostgreSQL écoute uniquement sur l’adresse privée du tunnel ;
  • UFW limite le port 5432 à l’interface et au sous-réseau WireGuard ;
  • pg_hba.conf restreint l’accès à une base, un rôle et un réseau précis ;
  • SCRAM-SHA-256 protège l’authentification par mot de passe.

Le port PostgreSQL reste ainsi invisible depuis Internet tout en étant accessible aux clients du VPN. Cette architecture ne dispense pas d’appliquer les mises à jour de sécurité, de limiter les privilèges SQL, de superviser les connexions et de tester régulièrement les sauvegardes.

Partager :

Articles en relation

Sécuriser un MySQL en cloud public avec Wireguard

Sécuriser un MySQL en cloud public avec Wireguard

La migration des bases de données vers des environnements cloud publics offre flexibilité et scalabilité, mais expose également les services à de nouvelles menaces.

En savoir plus