Aller au contenu

Installer et sécuriser PostgreSQL auto-hébergé sur Debian

Installer et sécuriser PostgreSQL auto-hébergé sur Debian

Section intitulée « Installer et sécuriser PostgreSQL auto-hébergé sur Debian »

Un PostgreSQL auto-hébergé sur Debian stable sort du paquet dans un état honorable : écoute sur la boucle locale, mots de passe hachés correctement, aucun compte par défaut joignable à distance. Ce qui le dégrade ensuite, c’est l’ouverture au réseau faite à la hâte, le rôle applicatif propriétaire de tout, et la sauvegarde que personne n’a jamais restaurée. Cette page couvre l’instance qu’on exploite soi-même ; la base managée a sa propre page, sécuriser les bases de données managées cloud.

→ Lire l’explication complète de la marmotte

Le compromis central tient en une phrase : l’auto-hébergement donne la maîtrise complète (configuration, emplacement des données, calendrier des mises à jour) et facture en retour toute l’exploitation, c’est-à-dire les sauvegardes, les correctifs, la supervision et la reprise. La position défendue ici : ce choix ne se justifie que si quatre choses existent avant la première donnée de production. Trois rôles distincts, un pg_hba.conf sans trust ni md5, des clients en sslmode=verify-full, et une restauration à un instant donné déjà jouée au moins une fois. Le reste est du réglage.

Installation de PostgreSQL : paquets Debian ou dépôt PGDG

Section intitulée « Installation de PostgreSQL : paquets Debian ou dépôt PGDG »

Deux sources de paquets. Debian 13 (trixie) fournit PostgreSQL 17 et le suit pendant la vie de la distribution. Le dépôt PGDG (PostgreSQL Global Development Group), tenu par le projet lui-même, fournit toutes les versions majeures maintenues pour chaque Debian supportée.

Le choix dépend d’une question : la montée de version du système doit-elle entraîner celle de la base ? Avec les paquets de la distribution, passer à la Debian suivante impose une migration majeure de PostgreSQL au même moment. Avec le PGDG, la même version majeure existe sur l’ancienne et la nouvelle Debian : les deux chantiers se dissocient. Recommandation : PGDG pour toute instance qui vivra plus longtemps que la distribution, paquets Debian pour une instance jetable ou un parc qui interdit les dépôts tiers. Le prix du PGDG est une clé de signature de plus à qui faire confiance.

Chaque version majeure est maintenue cinq ans après sa sortie, puis plus rien, pas même les correctifs de sécurité. La page de politique de versions du projet fait foi ; une version majeure à moins de douze mois de sa fin de vie n’a rien à faire sur une installation neuve.

Fenêtre de terminal
# Dépôt PGDG : le script est livré par postgresql-common
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
# Installer une version majeure précise (18 ici, à remplacer par la majeure retenue)
sudo apt install -y postgresql-18
# Vérifier l'instance créée par l'empaquetage Debian
pg_lsclusters

L’empaquetage Debian crée d’office une instance nommée main, avec les données dans /var/lib/postgresql/<version>/main et la configuration dans /etc/postgresql/<version>/main. Les outils pg_lsclusters, pg_ctlcluster et pg_upgradecluster viennent de postgresql-common et n’existent pas ailleurs : une procédure copiée depuis une autre distribution ne trouvera ni les mêmes chemins ni les mêmes commandes.

Prérequis côté système : un serveur déjà passé par le durcissement Linux avant mise en production, un volume dédié aux données, un chiffrement de disque si le support peut quitter la salle (PostgreSQL communautaire ne chiffre pas les données au repos), et une horloge synchronisée, sans quoi la restauration à un instant donné vise à côté. Depuis PostgreSQL 18, les sommes de contrôle des pages sont activées à la création de l’instance ; sur une version antérieure, SHOW data_checksums; dit ce qu’il en est.

listen_addresses et exposition réseau du port 5432

Section intitulée « listen_addresses et exposition réseau du port 5432 »

listen_addresses vaut localhost par défaut : rien n’est joignable depuis le réseau. Si l’application tourne sur la même machine, on n’y touche pas et la connexion passe par le socket Unix. Sinon, on y inscrit l’adresse précise de l’interface du réseau de données, jamais * par confort. La modification exige un redémarrage, pas un rechargement.

Trois filtres s’empilent et aucun ne remplace les autres : l’adresse d’écoute, le pare-feu (local et de zone), puis pg_hba.conf. La topologie ci-dessous montre ce qu’il faut viser : un seul flux entrant sur 5432/tcp, depuis une seule source, et un flux sortant vers le stockage de sauvegarde.

Topologie en deux zones séparées par le pare-feu FW. À gauche, le réseau applicatif 192.0.2.0/27 contient le serveur App, 192.0.2.10. À droite, le réseau données 198.51.100.0/27 contient la base de données PG01, 198.51.100.5, et le serveur Sauvegarde, 198.51.100.20. Un lien chiffré PostgreSQL sur TLS, 5432/tcp, va de App au pare-feu, qui n'accepte 5432/tcp que depuis 192.0.2.10, puis du pare-feu à PG01. Un second lien chiffré relie Sauvegarde à PG01 pour la copie de base et le flux de journaux, sur 5432/tcp.

Un port 5432 visible depuis Internet reçoit des tentatives de connexion en continu. PostgreSQL n’a aucun verrouillage de compte natif après échecs répétés : le module auth_delay ralentit les essais, rien de plus. La vraie contre-mesure est le filtrage réseau. Changer le numéro de port n’en est pas une, cela nettoie surtout les journaux.

Rôles et privilèges : superutilisateur, propriétaire, rôle applicatif

Section intitulée « Rôles et privilèges : superutilisateur, propriétaire, rôle applicatif »

Un superutilisateur PostgreSQL contourne tous les contrôles de privilèges. Il peut aussi lire et écrire des fichiers du serveur et lancer des programmes (COPY ... FROM PROGRAM) : en pratique, un mot de passe de superutilisateur vaut un shell sous le compte système postgres. Conséquence : le rôle postgres ne se connecte que localement, par peer, et ne reçoit jamais de mot de passe. Même prudence avec les rôles prédéfinis pg_execute_server_program, pg_read_server_files et pg_write_server_files, qui donnent l’équivalent par morceaux.

Le modèle à trois rôles :

  • un superutilisateur réservé à l’administration locale ;
  • un rôle propriétaire, qui possède la base et les objets, utilisé par les migrations de schéma et par elles seules ;
  • un rôle applicatif, qui lit et écrit les lignes et ne possède rien.

La séparation propriétaire/applicatif est celle qu’on sacrifie le plus souvent, parce qu’un seul rôle « ça marche ». Or le propriétaire d’une table peut la supprimer, la vider, en modifier la structure, et ces droits ne se révoquent pas. Une injection SQL (Structured Query Language) sur un rôle propriétaire devient un DROP TABLE ; sur un rôle applicatif, elle reste bornée aux données que ce rôle voit déjà, ce qui est assez grave pour ne pas en rajouter.

-- En tant que postgres, via le socket local
CREATE ROLE app_owner LOGIN; -- migrations de schéma
CREATE ROLE app_rw LOGIN; -- application en fonctionnement
CREATE ROLE sauvegarde LOGIN REPLICATION; -- copie de base et flux de journaux, rien d'autre
CREATE DATABASE appdb OWNER app_owner;
-- PUBLIC a CONNECT et TEMPORARY sur toute base neuve : on retire
REVOKE ALL ON DATABASE appdb FROM PUBLIC;
GRANT CONNECT ON DATABASE appdb TO app_rw;
\c appdb
CREATE SCHEMA app AUTHORIZATION app_owner;
GRANT USAGE ON SCHEMA app TO app_rw;
-- Droits sur les objets que app_owner créera plus tard
ALTER DEFAULT PRIVILEGES FOR ROLE app_owner IN SCHEMA app
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_rw;
ALTER DEFAULT PRIVILEGES FOR ROLE app_owner IN SCHEMA app
GRANT USAGE, SELECT ON SEQUENCES TO app_rw;

Trois pièges vérifiables. Un : ALTER DEFAULT PRIVILEGES ne vaut que pour les objets créés par le rôle nommé dans FOR ROLE ; une table créée par un autre rôle n’hérite de rien et l’application reçoit un permission denied à la première requête. Deux : depuis PostgreSQL 15, le pseudo-rôle PUBLIC (tous les rôles) n’a plus le droit de créer dans le schéma public, mais une instance migrée depuis une version antérieure conserve l’ancien droit ; REVOKE CREATE ON SCHEMA public FROM PUBLIC; règle la question, et un schéma dédié évite de se la poser. Trois : une fonction SECURITY DEFINER s’exécute avec les droits de son propriétaire et résout les noms selon le search_path de l’appelant, sauf si elle fixe le sien (SET search_path = app, pg_temp). Sans cette clause, tout rôle capable de créer un objet dans un schéma du chemin détourne la fonction.

Les mots de passe se posent avec \password app_rw dans psql, qui calcule le haché côté client. ALTER ROLE ... PASSWORD '...' envoie le mot de passe dans le texte de la requête, donc dans les journaux dès que la journalisation des instructions est active.

pg_hba.conf : ordre des règles, peer, scram-sha-256

Section intitulée « pg_hba.conf : ordre des règles, peer, scram-sha-256 »

pg_hba.conf porte dans son nom le sigle HBA (Host-Based Authentication, authentification selon l’hôte) : il décide, pour chaque connexion, de la méthode d’authentification. La règle qui gouverne tout : les lignes sont lues de haut en bas, la première qui correspond au quadruplet (type de connexion, base, rôle, adresse source) s’applique, et il n’y a aucun repli sur la suivante. Un échec d’authentification sur la ligne retenue est un refus définitif.

Séquence entre trois acteurs : Client, PostgreSQL et pg_hba.conf. Le client envoie à PostgreSQL une demande de connexion (type, base, rôle, adresse source). PostgreSQL lit la première ligne de pg_hba.conf. Si la ligne ne correspond pas, il passe à la ligne suivante ; si elle correspond, il applique sa méthode et arrête la lecture. Si la méthode réussit, la session est ouverte ; si elle échoue, PostgreSQL refuse sans essayer les lignes suivantes ; si aucune ligne ne correspond, il refuse aussi.

À lire dans ce schéma : une ligne large placée trop haut masque toutes les lignes précises placées dessous. Vingt ans de fichiers pg_hba.conf apprennent que la ligne host all all 0.0.0.0/0 ajoutée « pour tester » se trouve toujours en première position, et qu’elle survit à tous les audits qui ne lisent que la fin du fichier.

Les méthodes, par ordre de fréquentation :

  • peer : sur le socket Unix, le nom du compte système doit égaler le nom du rôle. Aucun secret à stocker. C’est la méthode des connexions locales.
  • scram-sha-256 : SCRAM (Salted Challenge Response Authentication Mechanism) ne fait transiter ni le mot de passe ni un équivalent rejouable, et le serveur ne stocke qu’un vérificateur salé. C’est la valeur par défaut de password_encryption depuis PostgreSQL 14 et la seule méthode par mot de passe à conserver.
  • md5 : MD5 (Message Digest 5) produit ici un haché qui suffit à s’authentifier ; qui lit la table des rôles n’a pas besoin de casser quoi que ce soit. Méthode dépréciée depuis PostgreSQL 18, à bannir.
  • trust : aucune vérification. Sur une ligne local, tout compte du système devient n’importe quel rôle, superutilisateur compris. À bannir sans exception, y compris « juste en local ».
# TYPE BASE RÔLE ADRESSE MÉTHODE
local all postgres peer
local all all peer
hostssl appdb app_rw 192.0.2.10/32 scram-sha-256
hostssl appdb app_owner 192.0.2.10/32 scram-sha-256
hostssl replication sauvegarde 198.51.100.20/32 scram-sha-256
host all all 0.0.0.0/0 reject
host all all ::/0 reject

hostssl ne correspond qu’aux connexions chiffrées : une tentative en clair tombe sur le reject final. Le mot-clé all dans la colonne base ne couvre pas la réplication, qui exige sa propre ligne replication. Avant de recharger, la vue pg_hba_file_rules signale les lignes invalides dans sa colonne error ; puis SELECT pg_reload_conf();. Et un rechargement ne coupe aucune session déjà ouverte : retirer une ligne ne déconnecte personne, il faut terminer les sessions avec pg_terminate_backend.

TLS côté serveur et vérification côté client avec sslmode verify-full

Section intitulée « TLS côté serveur et vérification côté client avec sslmode verify-full »

Debian active TLS (Transport Layer Security) dès l’installation, avec un certificat auto-signé générique nommé « snakeoil ». Le nom est honnête : ce certificat chiffre, il n’authentifie rien. On le remplace par un certificat émis par une autorité de certification interne (voir la rubrique PKI et TLS), dont le nom alternatif du sujet contient le nom par lequel les clients joignent le serveur.

/etc/postgresql/18/main/postgresql.conf
ssl = on
ssl_cert_file = '/etc/postgresql/18/main/server.crt'
ssl_key_file = '/etc/postgresql/18/main/server.key'
ssl_min_protocol_version = 'TLSv1.3' # défaut : TLSv1.2, à garder si des clients anciens subsistent

La clé privée appartient au compte postgres en mode 0600 (ou à root en 0640, lisible par le groupe de postgres) ; avec des droits plus larges, le serveur refuse de démarrer. Un changement de certificat se prend en compte par rechargement, sans coupure, ce qui rend le renouvellement automatisable.

Le point que tout le monde rate se situe côté client. La bibliothèque cliente libpq utilise par défaut sslmode=prefer : elle tente TLS, accepte le clair en repli, et ne vérifie aucun certificat. Un intermédiaire placé sur le chemin se fait passer pour le serveur sans la moindre alerte. Même require chiffre sans vérifier à qui l’on parle (il ne contrôle la chaîne que si un fichier d’autorité racine est présent côté client, par compatibilité, et jamais le nom). verify-ca valide la chaîne de certification ; seul verify-full valide la chaîne et le nom du serveur.

Fenêtre de terminal
psql "host=pg01.example.net dbname=appdb user=app_rw \
sslmode=verify-full sslrootcert=/etc/ssl/certs/ac-interne.pem \
channel_binding=require"

channel_binding=require lie l’échange SCRAM au canal TLS en cours : un intermédiaire qui terminerait TLS ne peut pas relayer l’authentification. Conséquence d’architecture : le paramétrage serveur ne suffit jamais, chaque chaîne de connexion de chaque application doit porter verify-full, et c’est là que l’inventaire fait mal. Les pilotes qui n’utilisent pas libpq ont leurs propres noms d’options et leurs propres défauts, à vérifier un par un.

Ce que TLS ne garantit pas : rien sur les données au repos, rien sur les fichiers de sauvegarde, rien contre un rôle légitime trop privilégié.

Journalisation PostgreSQL au service de la sécurité

Section intitulée « Journalisation PostgreSQL au service de la sécurité »

Par défaut, PostgreSQL ne journalise ni les connexions ni les instructions. Le minimum pour reconstituer qui a fait quoi :

log_connections = on
log_disconnections = on
log_line_prefix = '%m [%p] %q%u@%d %h ' # horodatage, processus, rôle, base, adresse source
log_statement = 'ddl' # créations, modifications et suppressions d'objets
log_min_duration_statement = 1000 # requêtes de plus d'une seconde
log_lock_waits = on

log_statement = 'ddl' trace les changements de structure et de droits pour un coût négligeable. all trace tout, données personnelles et mots de passe en clair inclus, et transforme le fichier journal en seconde base à protéger. Pour un audit par objet ou par rôle, l’extension pgAudit fait le travail proprement, au prix d’un chargement par shared_preload_libraries et d’un redémarrage.

Les journaux Debian vont dans /var/log/postgresql/. Un attaquant qui obtient le compte postgres les réécrit : ils n’ont de valeur de preuve qu’expédiés hors de la machine, vers la collecte centrale (voir monter une détection minimale). Les signaux à surveiller : rafales d’échecs d’authentification, connexion d’un rôle depuis une adresse inhabituelle, toute instruction de structure hors fenêtre de migration.

Sauvegarde : pg_dump, pg_basebackup et archivage des WAL

Section intitulée « Sauvegarde : pg_dump, pg_basebackup et archivage des WAL »

Deux familles, qui ne répondent pas à la même question.

pg_dump produit une sauvegarde logique : une image cohérente d’une base à l’instant du lancement, restaurable sur une autre version majeure ou une autre architecture. Il ne sauvegarde ni les rôles ni les droits globaux (pg_dumpall --globals-only s’en charge) et ne permet de revenir qu’à l’heure du dernier export.

pg_basebackup copie physiquement toute l’instance. Combiné à l’archivage continu des WAL (Write-Ahead Log, le journal où chaque modification est écrite avant d’atteindre les fichiers de données), il permet la restauration à un instant donné, ou PITR (Point-In-Time Recovery) : on repart de la copie de base, on rejoue les journaux, on s’arrête à la seconde voulue.

Schéma de séquence entre quatre acteurs : PostgreSQL, le stockage de sauvegarde, le serveur de restauration et l'exploitant. PostgreSQL envoie au stockage une copie de base périodique (pg_basebackup), puis chaque segment de journal terminé (archive_command). Le stockage fournit au serveur de restauration la copie de base la plus récente avant l'instant visé, puis les journaux archivés (restore_command). Le serveur rejoue les journaux jusqu'à recovery_target_time et, si les contrôles applicatifs réussissent, est ouvert en écriture pour l'exploitant.

À lire dans ce schéma : la chaîne casse dès qu’un seul segment manque entre la copie de base et l’instant visé.

Position : pg_dump seul ne suffit que si perdre tout ce qui a été écrit depuis le dernier export est acceptable, et que quelqu’un l’a écrit noir sur blanc. Sinon, archivage des WAL, piloté par un outil dédié (Barman, pgBackRest, après vérification que le projet retenu est toujours maintenu) plutôt que par un script archive_command maison. Un tel script échoue de façon créative : il renvoie zéro avant que le fichier soit réellement écrit, ou écrase un segment existant.

Les règles d’exploitation qui en découlent :

  • archive_mode = on exige un redémarrage ; archive_timeout borne la perte maximale sur une base peu active, puisqu’un segment n’est archivé qu’une fois terminé.
  • Tant que la commande d’archivage échoue, PostgreSQL conserve les segments dans pg_wal. Le volume se remplit, puis l’instance s’arrête. La vue pg_stat_archiver (failed_count, last_archived_time) se supervise, avec alerte.
  • Un slot de réplication abandonné retient les journaux de la même façon ; max_slot_wal_keep_size est illimité par défaut.
  • Le rôle de sauvegarde porte l’attribut REPLICATION : il lit l’intégralité de l’instance. Son secret se traite comme celui d’un superutilisateur.
  • pg_verifybackup contrôle une copie de base contre son manifeste. Depuis PostgreSQL 17, pg_basebackup --incremental et pg_combinebackup autorisent les copies incrémentales.
  • Les sauvegardes contiennent tout, en clair : chiffrement et stockage hors de portée du serveur, selon les principes de la sauvegarde immuable.

Une sauvegarde jamais restaurée est une hypothèse. Le test se joue sur une autre machine, jusqu’à l’ouverture de la base et une requête applicative, à cadence fixe, en chronométrant : la méthode est détaillée dans tester la restauration après sinistre.

Exemple : copie de base vérifiée et restauration à un instant donné

Section intitulée « Exemple : copie de base vérifiée et restauration à un instant donné »

Sur le serveur de sauvegarde, avec le rôle sauvegarde déclaré plus haut :

Fenêtre de terminal
# Copie physique, journaux nécessaires inclus, point de contrôle immédiat
pg_basebackup -h pg01.example.net -U sauvegarde \
-D /srv/sauvegarde/base-2026-10-10 -Fp -X stream -c fast -P
# Contrôle d'intégrité contre le manifeste
pg_verifybackup /srv/sauvegarde/base-2026-10-10

Sur le serveur de restauration, instance arrêtée, répertoire de données remplacé par la copie de base :

Fenêtre de terminal
# Paramètres de rejeu, dans postgresql.conf de l'instance restaurée
# restore_command = 'cp /srv/sauvegarde/wal/%f %p'
# recovery_target_time = '2026-10-10 09:41:00+02'
# recovery_target_action = 'promote'
# Le fichier vide recovery.signal déclenche le mode restauration au démarrage
sudo -u postgres touch /var/lib/postgresql/18/main/recovery.signal
sudo pg_ctlcluster 18 main start

Le restore_command montré suppose des segments déposés tels quels dans un répertoire ; avec un outil dédié, c’est sa propre commande qui s’y substitue. Sans recovery_target_action = 'promote', l’instance se met en pause une fois la cible atteinte et attend qu’on la libère, ce qui surprend à trois heures du matin.

Mises à jour mineures et montée de version majeure

Section intitulée « Mises à jour mineures et montée de version majeure »

Les versions mineures sortent environ tous les trois mois et ne changent pas le format des données : apt upgrade remplace les binaires, sans export ni import. Deux réserves. La mise à jour du paquet redémarre l’instance, donc coupe les sessions : avec des mises à jour automatiques, la coupure arrive à l’heure choisie par le planificateur. Et certaines notes de version demandent une action après coup (une reconstruction d’index, par exemple) ; elles se lisent avant, selon le processus de gestion des correctifs.

La montée de version majeure change le format interne. Trois voies : export puis import (lent, sûr, valable pour les petites bases), pg_upgrade (rapide, surtout en mode lien, mais sans retour arrière une fois la nouvelle instance démarrée dans ce mode), réplication logique vers une instance neuve (coupure minimale, préparation maximale). Sur Debian, pg_upgradecluster enveloppe les deux premières :

Fenêtre de terminal
sudo apt install -y postgresql-18
sudo pg_dropcluster 18 main --stop # retirer l'instance vide créée par le paquet
sudo pg_upgradecluster -m upgrade 17 main # l'ancienne instance reste, sur un autre port
# Après validation applicative seulement :
sudo pg_dropcluster 17 main

Avant : sauvegarde vérifiée, extensions installées pour la nouvelle version. Après : vacuumdb --all --analyze-in-stages, car avant PostgreSQL 18 les statistiques du planificateur ne suivent pas la migration et les premières requêtes partent avec des plans hasardeux.

Dernier piège, indépendant de PostgreSQL : une montée de version de Debian peut changer les règles de tri de la bibliothèque C du système. Les index sur du texte, construits avec l’ancien ordre, deviennent silencieusement faux. PostgreSQL signale un écart de version de collation à la connexion ; la réponse est un REINDEX des index concernés, puis ALTER DATABASE ... REFRESH COLLATION VERSION.

Limites du dispositif et conditions d’exploitation

Section intitulée « Limites du dispositif et conditions d’exploitation »

Ce que l’ensemble ne garantit pas, et d’où doit venir le reste :

  • Aucun chiffrement au repos : il vient du volume chiffré et du chiffrement des sauvegardes.
  • Aucune protection contre l’administrateur : un superutilisateur lit tout. La réponse est organisationnelle (comptes nominatifs sur le système, journaux expédiés ailleurs).
  • Aucun cloisonnement entre lignes par défaut : il faut activer la sécurité au niveau ligne table par table, et le propriétaire y échappe sauf FORCE ROW LEVEL SECURITY.
  • Aucune haute disponibilité : une instance seule a pour délai de reprise la durée d’une restauration, mesurée, pas estimée.

Côté secrets : le mot de passe du rôle applicatif vit dans un coffre-fort de secrets, pas dans un dépôt de code. Changer un mot de passe ne ferme pas les sessions ouvertes. Pour une rotation sans coupure, deux rôles de connexion alternent, tous deux membres d’un rôle sans connexion qui porte les privilèges. VALID UNTIL n’expire que l’authentification par mot de passe, pas le rôle.

Changer le port 5432 améliore-t-il la sécurité ?

Section intitulée « Changer le port 5432 améliore-t-il la sécurité ? »

Non. Un balayage de ports retrouve le service en quelques secondes. Le changement réduit le bruit dans les journaux, ce qui a un intérêt pour la lecture, aucun pour la protection. Le filtrage par adresse source et hostssl font le travail.

Comment sortir de md5 sur une instance existante ?

Section intitulée « Comment sortir de md5 sur une instance existante ? »

Un haché MD5 ne se convertit pas. On fixe password_encryption = 'scram-sha-256', on redéfinit chaque mot de passe, on contrôle qu’il ne reste aucune entrée commençant par md5 dans la colonne rolpassword de pg_authid, puis on remplace md5 par scram-sha-256 dans pg_hba.conf. Tant que la ligne dit md5, un rôle déjà passé à SCRAM s’authentifie en SCRAM, ce qui autorise une bascule progressive.

Seulement si perdre jusqu’à vingt-quatre heures d’écritures est accepté par le métier, et si l’export des rôles l’accompagne. Dans tous les autres cas, il complète l’archivage des journaux sans le remplacer ; il reste précieux pour restaurer une seule table ou changer de version majeure.

Avec un rôle unique, la moindre faille applicative hérite du droit de détruire les tables, pas seulement de les lire. Avec une ligne trust, n’importe quel compte du serveur devient administrateur de la base, donc du compte système qui la fait tourner. Sans vérification du certificat côté client, un équipement placé sur le chemin reçoit les requêtes et les réponses en se faisant passer pour le serveur, et rien ne le signale. Sans journal des connexions hors de la machine, impossible de dire après coup quel rôle est entré, ni d’où. Sans archivage des journaux de transactions, une suppression accidentelle à midi ramène à l’export de la nuit ; sans test, même cet export n’est qu’une supposition.

PostgreSQL est un logiciel qui range des données et répond aux programmes qui les demandent. Une fois installé, il n’écoute que la machine sur laquelle il tourne. Pour qu’un autre ordinateur lui parle, il faut l’autoriser explicitement, et seulement pour les adresses prévues.

Ensuite viennent les comptes. Un compte tout-puissant sert à l’administration et ne quitte jamais la machine. Un deuxième possède les tables et sert à modifier leur structure. Un troisième, celui du programme, peut seulement lire et écrire les données. Si le programme est piraté, le pirate n’obtient que ce troisième compte.

À chaque connexion, le serveur parcourt une liste de règles dans l’ordre et applique la première qui correspond : elle dit comment prouver son identité. Si la preuve échoue, la connexion est refusée.

Les échanges sont chiffrés, et le programme vérifie qu’il parle bien au vrai serveur. Sans cette vérification, le chiffrement protège une conversation avec un inconnu.

Le serveur note qui se connecte et qui change la structure, et envoie ces notes ailleurs.

Enfin, il copie régulièrement toutes ses données, puis chaque modification au fil de l’eau. Avec les deux, on peut reconstruire la base telle qu’elle était à une seconde précise. Si une seule modification manque, la reconstruction s’arrête là. Voilà pourquoi on s’entraîne à restaurer.

À lire aussi

Pages voisines

: les deux pages se citent l’une l’autre.