Un client m’a récemment demandé si FireDAC pouvait être utilisé pour se connecter à une base de données via un tunnel SSH. La réponse courte est oui, bien sûr. Mais comprenons mieux ce qu’est un tunnel SSH et comment cet objectif peut être facilement atteint en utilisant Delphi et FireDAC.
Table of Contents
Tunnels SSH
Secure Shell (ssh) est un outil standard inclus sur la plupart des systèmes d’exploitation «réseau» c’est-à-dire Linux, UNIX, MacOS, et maintenant aussi sur Windows (en mode natif). Si vous aviez utilisé PuTTY à un moment de votre vie pour vous connecter à une interface de ligne de commande distante, en général un système Linux, SSH était le protocole utilisé pour cela.
Donc, la chose clé ici pour utiliser FireDAC via une interface sécurisée SSH est de comprendre que FireDAC (ou tout autre framework d’accès aux bases de données) n’a rien à voir avec cela. Ce dont vous avez besoin est d’établir un tunnel SSH permanent, puis de configurer correctement votre connexion à la base de données.
Nous verrons deux manières d’établir un tunnel SSH: l’une utilisant un outil externe (PuTTY) et la seconde directement codée dans votre application.
Serveurs SSH
Le but de cet article n’est pas d’enseigner comment créer un serveur SSH, mais j’ai dû en créer un pour tester ma solution, voici donc ce que j’utilise. Fondamentalement, j’ai une machine virtuelle Linux exécutant une base de données PostgreSQL (c’est la base de données que le client souhaite connecter, mais la solution est indépendante de la base de données), et par-dessus, j’ai installé et démarré un serveur SSH en suivant ce tutoriel:
https://docs.oracle.com/cd/E37670_01/E41138/html/ch25s03.html
C’est pour Oracle Linux (c’est ce que j’utilise en raison d’une autre preuve de concept que j’ai dû faire la semaine dernière) mais vous trouverez des tutoriels similaires pour votre version Linux préférée.
Tester la connexion
Avant d’essayer la connexion depuis FireDAC, c’est une bonne idée de prouver la connexion en utilisant uniquement des outils de ligne de commande qui font partie intégrante des systèmes d’exploitation, afin que vous ayez une idée si les choses fonctionnent ou non.
Ainsi, ayant à la fois le serveur SSH et l’instance de base de données (PostgreSQL dans mon cas) ouverts et exécutés sous Linux, nous pouvons essayer une première connexion depuis Windows en utilisant n’importe quel terminal client SSH. Windows 10 a un client natif depuis la «mise à jour d’octobre» de 1809, mais je m’en tiendrai à PuTTY car il s’agit d’un utilitaire dominant pour les administrateurs système.
Ce sont mes configurations Putty. Dans la page Session, vous devez spécifier l’adresse IP du serveur et le port SSH (22 est la valeur par défaut):
Et dans la page de configuration SSH / Tunnels, vous spécifiez comment le tunnel sera créé:
Que dit cette configuration? Fondamentalement, pour créer un tunnel SSH, vous devez spécifier le port source (tout numéro de port disponible / non utilisé que vous avez dans votre système) et l’adresse IP / port de destination (dans ce cas, l’adresse IP du serveur Linux et le port où se trouve l’instance PostgreSQL. écoute – le 5432 est le port PostgreSQL par défaut). Bien sûr, l’adresse IP source sera toujours «localhost», ce qui signifie que votre connexion à la base de données pointera vers localhost / 63333 et le tunnel fera la magie, envoyant les commandes au serveur et recevant les résultats.
Enfin, en ouvrant la connexion PuTTY et en fournissant un utilisateur et un mot de passe Linux valides (il est recommandé de créer un utilisateur spécifique uniquement pour l’utilisation SSH), vous allez voir quelque chose de similaire ci-dessous. Moche, je sais. Vous pouvez tester certaines commandes Linux dessus, comme «ls -l»:
Temps de codage!
Après avoir correctement configuré et testé l’infra, configurons une connexion à la base de données FireDAC et testons-la. Comme vous pouvez le voir ci-dessous, il s’agit d’une connexion FireDAC standard utilisant le pilote PostgreSQL, la seule chose non triviale est le serveur / port pointant vers le tunnel créé via PuTTY:
Maintenant, vous voudrez normalement rendre cela «transparent» pour votre utilisateur final, ce qui signifie ne pas avoir à configurer le PuTTY ou tout autre 3ème outil. Pour ce faire, vous devez envisager une implémentation de client SSH pour Delphi qui créera essentiellement ce tunnel pour vous, mais depuis l’intérieur de votre application. Il existe de nombreux composants tiers disponibles pour cela, mais aussi de merveilleuses implémentations open source que vous pouvez trouver en effectuant une recherche dans GitHub.
Mon choix s’est porté sur la bibliothèque Ssh-Pascal. Il est très complet et a été construit par le père de PyScript (l’un des meilleurs IDE Python open source – entièrement réalisé en Delphi) – mérite donc un crédit supplémentaire😉
https://github.com/pyscripter/Ssh-Pascal
L’implémentation est basée sur la libssh2 , une implémentation SSH bien connue qui est présente dans de nombreux langages et frameworks. En ce qui concerne l’installation, il s’agit simplement d’ajouter les sources de la bibliothèque dans votre projet et de l’utiliser, sans composants ni dépendances externes. Pour déployer, le libssh2.dll doit être mis à disposition avec votre exécutable.
Votre propre tunnel SSH
Ci-dessous, nous avons ce que j’ai construit pour cette preuve de concept. S’il vous plaît, considérez que c’est juste pour tester le concept et non une mise en œuvre complète, ce qui signifie que de nombreuses améliorations peuvent être apportées.
Quelques détails:
- La configuration de la connexion PostgreSQL est exactement la même que celle présentée précédemment
- Les boutons Ouvrir / Fermer la base de données sont responsables de l’ouverture et de la fermeture de la connexion à la base de données
- Le code du tunnel Open / Close peut être trouvé ci-dessous (veuillez noter que tous les paramètres sont codés en dur car il ne s’agit que d’un exemple, s’il vous plaît, ne le prenez pas comme un exemple de bonne pratique de codage par quelque moyen que ce soit)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
procedure TMainForm.butOpenTunnelClick(Sender: TObject); Var Host: string; UserName: string; Password: string; begin Host := '192.168.56.106'; UserName := 'oracle'; Password := 'oracle'; Session := CreateSession(Host, 22); Session.Connect; if not Session.UserAuthPass(UserName, Password) then begin ShowMessage('Authorization Failure'); Exit; end; SshTunnel := CreateSshTunnel(Session); Thread := TThread.CreateAnonymousThread( procedure begin SshTunnel.ForwardLocalPort(63333, '192.168.56.106', 5432); end); Thread.FreeOnTerminate := True; Thread.Start; end; |
1 2 3 4 5 6 7 8 9 10 |
procedure TMainForm.butCloseTunnelClick(Sender: TObject); begin Thread.Terminate; SshTunnel.Cancel; if not Thread.Finished then begin Thread.WaitFor; Thread.Free; end; end; |
Et enfin, nous avons l’application en cours d’exécution affichant des données PostgreSQL. Encore une fois, cela peut être fait pour n’importe quelle base de données – jusqu’à ce que quelqu’un m’envoie un message disant que quelque chose ne fonctionne pas😉
Le code source complet peut être trouvé ici dans mon GitHub , avec d’autres projets de démonstration.
N’hésitez pas à laisser vos commentaires, problèmes, cas d’utilisation, etc., ce sera très apprécié!
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition