
Sécuriser PostgreSQL en cloud public avec WireGuard
- Charles Fleury
- Sécurité , Base de données
- 21 décembre 2025
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 :
wg0comme interface WireGuard ;10.0.0.1comme adresse WireGuard du serveur PostgreSQL ;10.0.0.0/24comme sous-réseau WireGuard ;5432comme 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
sudoau VPS. - Une règle de pare-feu chez l’hébergeur qui autorise le port UDP de WireGuard, mais pas le port TCP
5432depuis 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.confrestreint 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.
