QoreDB LogoQoreDB
Retour au blog
ArchitectureJournal technique

Comment QoreDB gère les tunnels SSH sans agent tiers

Accéder à une base de données derrière un bastion SSH est un cas d'usage courant pour tout développeur qui travaille avec des serveurs en production. La plupart des clients de base de données embarquent une bibliothèque SSH (libssh2, russh, paramiko) pour gérer cette couche…

Raphaël – Creator of QoreDBRaphaël – Creator of QoreDB
5 min de lectureMis à jour le 19 mai 2026
Comment QoreDB gère les tunnels SSH sans agent tiers

Accéder à une base de données derrière un bastion SSH est un cas d'usage courant pour tout développeur qui travaille avec des serveurs en production. La plupart des clients de base de données embarquent une bibliothèque SSH (libssh2, russh, paramiko) pour gérer cette couche réseau en interne. QoreDB fait un choix différent : déléguer entièrement le tunnel au client OpenSSH installé sur la machine de l'utilisateur.

Ce choix a des conséquences directes sur la compatibilité, la sécurité et la maintenance du code. Voici comment il fonctionne concrètement.

Pourquoi déléguer au client OpenSSH

Embarquer une bibliothèque SSH dans un client desktop pose plusieurs problèmes concrets. Il faut suivre les CVE de la bibliothèque, gérer les mises à jour indépendamment du système, et reproduire un comportement que l'OS gère déjà très bien. Le client OpenSSH est installé par défaut sur macOS, Linux, et Windows 10+ (via le composant optionnel OpenSSH). Il est maintenu activement, audité régulièrement, et supporte nativement les agents SSH, les fichiers de configuration, et les protocoles les plus récents.

En déléguant au binaire système, QoreDB hérite automatiquement de toute la configuration SSH de l'utilisateur : les clés chargées dans ssh-agent, les entrées du fichier ~/.ssh/config, les algorithmes négociés par le système. Il n'y a pas de décalage entre ce qui fonctionne dans le terminal et ce qui fonctionne dans QoreDB.

L'architecture du tunnel dans le code Rust

Le module SSH de QoreDB est construit autour de deux traits Rust : SshTunnelBackend et SshTunnelHandle. Le premier définit l'interface pour ouvrir un tunnel, le second gère son cycle de vie (port local, fermeture). Cette abstraction permet d'ajouter d'autres backends à l'avenir sans modifier le reste du code.

Aujourd'hui, le seul backend implémenté est OpenSshBackend. Il fonctionne en lançant un processus ssh -N -L via tokio, en mode non-interactif. La commande est construite avec des options strictes : BatchMode=yes pour éviter tout prompt, ExitOnForwardFailure=yes pour couper le tunnel si le port-forwarding échoue, et IdentitiesOnly=yes pour ne tester que la clé spécifiée.

L'allocation du port local est automatique : QoreDB ouvre un listener TCP sur le port 0, récupère le port assigné par l'OS, ferme le listener, puis passe ce port à la commande SSH. Cela évite les conflits de port et fonctionne sans configuration utilisateur.

Gestion des host keys et sécurité

La vérification des host keys est un point critique pour tout tunnel SSH. QoreDB expose trois politiques à l'utilisateur : accept-new (TOFU, confiance à la première connexion), strict (la clé doit déjà être dans le fichier known_hosts), et une option désactivée réservée au développement.

Un point important : QoreDB utilise son propre fichier known_hosts, séparé de celui du système. Sur Linux et macOS, il est stocké dans ~/.qoredb/ssh/known_hosts, sur Windows dans %APPDATA%\QoreDB\ssh\known_hosts. Le fichier known_hosts global du système est explicitement ignoré (redirigé vers /dev/null). Ce cloisonnement garantit un comportement déterministe : les empreintes de serveurs validées via QoreDB n'interfèrent pas avec celles du terminal, et inversement.

La sortie stderr du processus SSH est également filtrée avant d'être remontée à l'utilisateur. Les adresses IP internes sont anonymisées, la sortie est tronquée à 200 caractères, et les lignes qui contiennent des informations d'identité sont supprimées sauf les messages de type "Permission denied". Cela évite de fuiter des détails d'infrastructure dans l'interface.

Support du bastion et du ProxyJump

Dans beaucoup d'environnements de production, la base de données n'est pas accessible directement. Il faut passer par un serveur intermédiaire (bastion ou jump host). QoreDB supporte nativement cette configuration via l'option -J d'OpenSSH (ProxyJump). L'utilisateur renseigne une adresse au format user@host:port dans l'interface, et QoreDB l'ajoute à la commande SSH.

Le champ ProxyJump est validé côté backend avec une regex stricte. Les caractères spéciaux, les espaces et les options SSH injectées sont rejetés. C'est une précaution nécessaire car la valeur est passée en argument de ligne de commande : sans validation, un utilisateur malintentionné ou un import corrompu pourrait tenter d'injecter des options SSH arbitraires.

Keep-alive et reconnexion automatique

Un tunnel SSH peut se couper silencieusement, notamment en cas de coupure réseau ou de timeout côté serveur. QoreDB configure le keep-alive directement dans la commande SSH via ServerAliveInterval et ServerAliveCountMax. Par défaut, le client envoie un signal toutes les 30 secondes et tolère 3 échecs consécutifs avant de couper la connexion.

Côté session manager, QoreDB surveille aussi l'état du tunnel en essayant périodiquement de se connecter au port local. Si le port ne répond plus, le session manager tente de recréer le tunnel automatiquement avec la même configuration, puis de reconnecter le driver de base de données. L'utilisateur n'a pas besoin d'intervenir manuellement dans la majorité des cas.

En pratique : se connecter à PostgreSQL via un bastion

L'expérience utilisateur est directe. Dans le formulaire de connexion, on active le tunnel SSH, on renseigne l'hôte et le port du serveur SSH, le nom d'utilisateur, et le chemin vers la clé privée. Le champ "hôte de base de données" correspond à l'adresse de la base telle qu'elle est joignable depuis le serveur SSH, pas depuis la machine locale. C'est un point qui peut surprendre mais qui est parfaitement logique : avec un tunnel SSH, la résolution d'adresse se fait côté serveur distant.

Au moment de la connexion, QoreDB alloue un port local aléatoire, lance le processus SSH, attend que le tunnel soit opérationnel (en sondant le port toutes les 50ms, avec un timeout de 5 secondes), puis connecte le driver de base de données sur 127.0.0.1:port_local. Si le processus SSH échoue au démarrage, l'erreur stderr est remontée immédiatement dans l'interface.

Déléguer le tunnel SSH au binaire système est un choix de conception qui aligne QoreDB avec l'écosystème existant plutôt que de le remplacer. L'utilisateur conserve ses habitudes (ssh-agent, fichiers de configuration, mises à jour OS), et QoreDB se concentre sur ce qu'il sait faire : fournir une interface rapide pour explorer et manipuler des données. Le code Rust qui orchestre ce mécanisme tient dans un module de quelques centaines de lignes, avec un trait extensible pour ajouter d'autres backends si le besoin se présente.

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