QoreDB LogoQoreDB
Retour au blog
ProduitJournal technique

Comment se connecter à PostgreSQL via un tunnel SSH : guide complet

Une base PostgreSQL en production n'est presque jamais joignable directement depuis Internet. Le port 5432 reste accessible uniquement depuis le réseau privé du cluster, et l'accès humain passe par un bastion SSH. Le tunnel forwarde un port local vers la base à travers la session…

Raphaël – Creator of QoreDBRaphaël – Creator of QoreDB
5 min de lecture

Une base PostgreSQL en production n'est presque jamais joignable directement depuis Internet. Le port 5432 reste accessible uniquement depuis le réseau privé du cluster, et l'accès humain passe par un bastion SSH. Le tunnel forwarde un port local vers la base à travers la session SSH chiffrée, sans exposer la base au monde extérieur.

Ce guide couvre les trois approches utilisées en 2026 : la commande ssh à la main, le fichier ~/.ssh/config pour réutiliser une config nommée, et les clients desktop qui embarquent eux-mêmes le tunnel (DBeaver, DataGrip, QoreDB). On finit par les pièges concrets : timeout, ProxyJump, host key et passphrase.

La commande ssh -L en ligne de commande

Le port-forwarding local s'écrit toujours de la même manière :

ssh -L 5433:postgres.internal:5432 user@bastion.example.com -p 22 -N

L'option -L 5433:postgres.internal:5432 signifie : écoute sur 127.0.0.1:5433 côté client, et forwarde vers postgres.internal:5432 vu depuis le serveur SSH. L'option -N demande à ne pas exécuter de commande distante, on veut juste le tunnel.

Une fois le tunnel ouvert, on se connecte à PostgreSQL via le port local :

psql -h 127.0.0.1 -p 5433 -U appuser -d appdb

Piège classique : le remote_host est résolu côté serveur SSH, jamais côté client. Si vous mettez localhost, c'est la machine bastion qui essaie de joindre sa propre base sur 5432. Il faut le nom interne de la base tel que le bastion le voit : IP privée, FQDN interne, ou nom de service Docker.

Le fichier ~/.ssh/config

Réécrire la commande complète à chaque fois est pénible. La bonne pratique est de tout déclarer dans ~/.ssh/config, une fois pour toutes.

Host prod-pg / HostName bastion.example.com / User myuser / Port 22 / IdentityFile ~/.ssh/prod_ed25519 / LocalForward 5433 postgres.internal:5432 / ServerAliveInterval 30 / ServerAliveCountMax 3

Une simple commande ssh -N prod-pg ouvre alors le tunnel avec toute la config attachée. Avantage non négligeable : les clients qui n'intègrent pas le tunnel SSH peuvent quand même profiter du mécanisme. On lance le tunnel à part, et ils se connectent à 127.0.0.1:5433 comme si la base était locale.

Les clients desktop qui intègrent le tunnel

Plusieurs clients GUI proposent une configuration SSH directement dans la définition de connexion. On saisit une fois l'hôte, le port, la clé privée et l'utilisateur SSH, à côté des credentials PostgreSQL. Le client ouvre lui-même le tunnel à l'établissement de la connexion et le ferme quand on déconnecte.

DBeaver embarque sa propre stack SSH (JSch historiquement, Apache MINA SSHD sur les versions récentes). DataGrip s'appuie sur la stack SSH des IDE JetBrains. QoreDB délègue au binaire ssh natif du système et lance un sous-processus. Chaque approche a des conséquences différentes : algorithmes supportés, gestion des passphrases, intégration avec ssh-agent.

Le critère pratique : si vous tenez à utiliser les mêmes algorithmes et la même configuration crypto que votre OpenSSH système, choisissez un client qui appelle le binaire natif. Si vous voulez une configuration totalement autonome, indépendante du système, un client avec stack SSH embarquée fait le job.

Les pièges qu'on rencontre vraiment

Timeout silencieux. Sans ServerAliveInterval, un NAT, un firewall ou un load balancer peut couper la session après quelques minutes d'inactivité. Régler 30 secondes d'intervalle et ServerAliveCountMax=3 règle 90 % des coupures.

Chaîne de bastions. Quand il faut traverser un bastion public puis un bastion interne, ssh -J user@public-bastion user@inner-bastion gère la chaîne. ~/.ssh/config supporte ProxyJump comme directive. Côté clients GUI, l'intégration est inégale : QoreDB l'expose en champ dédié, DBeaver passe par la config OpenSSH avancée.

Validation de la host key. La première connexion demande de valider l'empreinte du serveur. En mode automatisé, StrictHostKeyChecking=accept-new accepte une nouvelle clé inconnue mais refuse une clé qui a changé. C'est le bon compromis pour les setups d'équipe : pas de friction sur l'ajout d'un nouveau bastion, alerte immédiate si une clé existante est modifiée (signe potentiel d'attaque MITM).

Clé privée avec passphrase. Certains clients ne savent pas déchiffrer la clé eux-mêmes et refuseront toute clé protégée. La solution propre est ssh-agent : on charge la clé une fois avec ssh-add, l'agent garde la clé en mémoire, et tous les outils qui appellent OpenSSH (psql via tunnel, QoreDB, scripts) la récupèrent automatiquement.

Port local déjà occupé. Si 5433 est pris, le tunnel échoue silencieusement ou bloque le port précédent. Pour éviter le problème, certains clients (dont QoreDB) bindent un port local éphémère choisi par l'OS, plutôt que de figer un numéro arbitraire.

Approche QoreDB : OpenSSH natif

QoreDB n'embarque pas de stack SSH. À chaque ouverture de connexion avec tunnel, l'app lance ssh ou ssh.exe comme sous-processus, avec les options BatchMode=yes, ExitOnForwardFailure=yes, et un UserKnownHostsFile dédié pour ne pas polluer le ~/.ssh/known_hosts personnel.

Trois politiques de host key sont exposées dans l'UI : accept-new par défaut, strict pour les environnements sensibles, et insecure pour le développement local (désactive la vérification, à n'utiliser que dans Docker). ProxyJump est supporté avec validation du format pour éviter l'injection d'arguments dans la ligne de commande SSH.

Conséquence directe : si OpenSSH fonctionne en ligne de commande sur la machine, QoreDB fonctionne avec exactement la même configuration. Les algorithmes supportés, les options globales dans /etc/ssh/ssh_config, et les clés chargées dans ssh-agent sont partagés entre la CLI et l'app. Une équipe qui a déjà standardisé sa config OpenSSH n'a rien à réapprendre.

Quelle approche choisir

Trois niveaux d'intégration, du plus brut au plus fluide. La ligne de commande ssh -L reste imbattable pour comprendre ce qui se passe et pour les setups ponctuels. Le fichier ~/.ssh/config est le minimum vital dès qu'on accède régulièrement à plusieurs bastions. Le client desktop avec tunnel intégré gagne quand on accède quotidiennement à dix environnements et qu'on veut éviter le double clic mental ouvrir le tunnel, puis ouvrir le client.

Les trois approches se cumulent. On peut très bien configurer ~/.ssh/config avec ProxyJump et des clés en agent, et laisser QoreDB ou DataGrip appeler ce setup sans dupliquer la moindre option. C'est probablement le sweet spot pour un dev backend en 2026 : une configuration SSH centralisée, et un client de base de données qui s'y branche sans frottement.

Newsletter

Restez informé des nouveautés

Rejoignez notre newsletter pour recevoir les mises à jour majeures, les nouveaux drivers et nos coulisses techniques.

🎁 Bonus : Recevez notre fiche mémo d'optimisation SQL — 9 pages, PostgreSQL / MySQL / SQLite (PDF) !
Partager