Ein Kunde hat mich kürzlich gefragt, ob FireDAC verwendet werden kann, um über einen SSH-Tunnel eine Verbindung zu einer Datenbank herzustellen. Die kurze Antwort lautet natürlich ja. Aber lassen Sie uns besser verstehen, was ein SSH-Tunnel ist und wie dieses Ziel mit Delphi und FireDAC leicht erreicht werden kann.
Table of Contents
SSH-Tunnel
Secure Shell (ssh) ist ein Standardtool, das in den meisten „Netzwerk“ -Betriebssystemen enthalten ist, z. B. Linux, UNIX, MacOS und jetzt auch unter Windows (nativ). Wenn Sie PuTTY irgendwann in Ihrem Leben verwendet hatten, um eine Verbindung zu einer Remote-Befehlszeilenschnittstelle herzustellen, im Allgemeinen einem Linux-System, war SSH das dafür verwendete Protokoll.
Der Schlüssel zur Verwendung von FireDAC über eine sichere SSH-Schnittstelle besteht darin, zu verstehen, dass FireDAC (oder ein anderes Datenbankzugriffsframework) nichts damit zu tun hat. Sie müssen lediglich einen permanenten SSH-Tunnel einrichten und anschließend Ihre Datenbankverbindung ordnungsgemäß einrichten.
Es gibt zwei Möglichkeiten, einen SSH-Tunnel einzurichten: eine mit einem externen Tool (PuTTY) und die zweite direkt in Ihrer Anwendung codiert.
SSH-Server
In diesem Artikel wird nicht erläutert, wie ein SSH-Server erstellt wird. Ich musste jedoch einen erstellen, um meine Lösung zu testen. Daher verwende ich Folgendes. Grundsätzlich habe ich eine Linux-VM, auf der eine PostgreSQL-Datenbank ausgeführt wird (dies ist die Datenbank, die der Kunde verbinden möchte, die Lösung ist jedoch datenbankunabhängig), und darüber habe ich nach diesem Tutorial einen SSH-Server installiert und gestartet:
https://docs.oracle.com/cd/E37670_01/E41138/html/ch25s03.html
Dies ist für Oracle Linux (dies ist das, was ich aufgrund eines weiteren Proof-of-Concept-Vorgangs mache, den ich letzte Woche durchführen musste), aber Sie werden ähnliche Tutorials für Ihre bevorzugte Linux-Variante finden.
Testen der Verbindung
Bevor Sie die Verbindung von FireDAC aus versuchen, sollten Sie die Verbindung nur mit Befehlszeilentools überprüfen, die integraler Bestandteil der Betriebssysteme sind. Sie haben also eine Vorstellung davon, ob die Dinge funktionieren oder nicht.
Wenn also sowohl der SSH-Server als auch die Datenbankinstanz (in meinem Fall PostgreSQL) geöffnet sind und unter Linux ausgeführt werden, können wir versuchen, eine erste Verbindung von Windows über ein beliebiges SSH-Client-Terminal herzustellen. Windows 10 hat seit dem „Oktober-Update“ von 1809 einen nativen Client, aber ich bleibe bei PuTTY, da dies ein dominierendes Dienstprogramm für Systemadministratoren ist.
Dies sind meine Putty-Konfigurationen. Auf der Seite Sitzung müssen Sie die Server-IP und den SSH-Port angeben (22 ist die Standardeinstellung):
Auf der Konfigurationsseite für SSH / Tunnel geben Sie an, wie der Tunnel erstellt werden soll:
Was sagt diese Konfiguration aus? Grundsätzlich müssen Sie zum Erstellen eines SSH-Tunnels den Quellport (jede verfügbare / nicht verwendete Portnummer, die Sie in Ihrem System haben) und die Ziel-IP / den Ziel-Port (in diesem Fall die IP-Adresse des Linux-Servers und den Port, an dem sich die PostgreSQL-Instanz befindet, angeben Abhören – der 5432 ist der Standard-PostgreSQL-Port. Natürlich lautet die Quell-IP-Adresse immer „localhost“, was bedeutet, dass Ihre Datenbankverbindung auf localhost / 63333 verweist und der Tunnel die Magie ausführt, die Befehle an den Server sendet und die Ergebnisse zurückerhält.
Wenn Sie schließlich die PuTTY-Verbindung öffnen und einen gültigen Linux-Benutzer und ein gültiges Kennwort angeben (es wird empfohlen, einen bestimmten Benutzer nur für die SSH-Verwendung zu erstellen), sehen Sie unten etwas Ähnliches. Hässlich, ich weiß. Sie können einige Linux-Befehle darauf testen, wie z. B. „ls -l“:
Codierungszeit!
Nachdem die Infrastruktur ordnungsgemäß konfiguriert und getestet wurde, richten wir eine FireDAC-Datenbankverbindung ein und testen sie. Wie Sie unten sehen können, handelt es sich um eine Standard-FireDAC-Verbindung mit dem PostgreSQL-Treiber. Die einzige nicht triviale Sache ist der Server / Port, der auf den über PuTTY erstellten Tunnel verweist:
Normalerweise möchten Sie dies für Ihren Endbenutzer „transparent“ machen, sodass Sie das PuTTY oder ein anderes drittes Tool nicht konfigurieren müssen. Um dies zu erreichen, müssen Sie eine SSH-Client-Implementierung für Delphi in Betracht ziehen, die diesen Tunnel im Grunde genommen für Sie erstellt, jedoch innerhalb Ihrer App. Hierfür stehen viele Komponenten von Drittanbietern zur Verfügung, aber auch einige wunderbare Open Source-Implementierungen, die Sie bei einer Suche in GitHub finden können.
Meine Wahl fiel auf die Ssh-Pascal-Bibliothek. Es ist sehr vollständig und wurde vom Vater von PyScript (einer der besten Open-Source-Python-IDE – vollständig in Delphi hergestellt) erstellt😉
https://github.com/pyscripter/Ssh-Pascal
Die Implementierung basiert auf libssh2 , einer bekannten SSH-Implementierung, die in vielen Sprachen und Frameworks vorhanden ist. In Bezug auf die Installation müssen nur die Bibliotheksquellen in Ihrem Projekt hinzugefügt und verwendet werden, keine Komponenten oder externen Abhängigkeiten. Zum Bereitstellen sollte die libssh2.dll zusammen mit Ihrer ausführbaren Datei verfügbar gemacht werden.
Dein eigener SSH-Tunnel
Nachfolgend haben wir das, was ich für diesen Proof of Concept gebaut habe. Bitte beachten Sie, dass dies nur zum Testen des Konzepts und nicht zur vollständigen Implementierung dient. Dies bedeutet, dass viele Verbesserungen vorgenommen werden können.
Ein paar Details:
- Die PostgreSQL-Verbindungskonfiguration ist genau die gleiche wie die zuvor vorgestellte
- Die Schaltflächen zum Öffnen / Schließen der Datenbank sind für das Öffnen und Schließen der Datenbankverbindung verantwortlich
- Der Open / Close-Tunnelcode ist unten zu finden (bitte beachten Sie, dass alle Parameter fest codiert sind, da dies nur ein Beispiel ist. Bitte nehmen Sie dies keinesfalls als Beispiel für eine gute Codierungspraxis.)
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; |
Und schließlich läuft die App und zeigt einige PostgreSQL-Daten an. Dies kann wiederum für jede Datenbank durchgeführt werden – bis mir jemand eine Nachricht sendet, dass etwas nicht funktioniert😉
Den vollständigen Quellcode finden Sie hier in meinem GitHub , zusammen mit einigen anderen Demo-Projekten.
Fühlen Sie sich frei, Ihre Kommentare, Probleme, Anwendungsfälle usw. zu lassen, es wird sehr geschätzt!
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition