SSH-Verbindung mit Java

Java Top

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs

1. Einleitung

SSH, auch als Secure Shell oder Secure Socket Shell bekannt, ist ein Netzwerkprotokoll, mit dem ein Computer über ein ungesichertes Netzwerk eine sichere Verbindung zu einem anderen Computer herstellen kann. In diesem Tutorial zeigen wir, wie Sie mithilfe der JSHD- und Apache MINA SSHD-Bibliotheken eine Verbindung zu einem Remote-SSH-Server mit Java herstellen .

In unseren Beispielen öffnen wir zuerst die SSH-Verbindung, führen dann einen Befehl aus, lesen die Ausgabe und schreiben sie in die Konsole und schließen schließlich die SSH-Verbindung. Wir werden den Beispielcode so einfach wie möglich halten.

2. JSch

JSch ist die Java-Implementierung von SSH2, mit der wir eine Verbindung zu einem SSH-Server herstellen und Portweiterleitung, X11-Weiterleitung und Dateiübertragung verwenden können. Außerdem ist es unter der BSD-Lizenz lizenziert und bietet uns eine einfache Möglichkeit, eine SSH-Verbindung mit Java herzustellen.

Fügen wir zunächst die JSch Maven-Abhängigkeit zu unserer Datei pom.xml hinzu :

 com.jcraft jsch 0.1.55 

2.1. Implementierung

Um eine SSH-Verbindung mit JSch herzustellen, benötigen wir einen Benutzernamen, ein Kennwort, eine Host-URL und einen SSH-Port . Der Standard-SSH-Port ist 22, aber es kann vorkommen, dass wir den Server so konfigurieren, dass er einen anderen Port für SSH-Verbindungen verwendet:

public static void listFolderStructure(String username, String password, String host, int port, String command) throws Exception { Session session = null; ChannelExec channel = null; try { session = new JSch().getSession(username, host, port); session.setPassword(password); session.setConfig("StrictHostKeyChecking", "no"); session.connect(); channel = (ChannelExec) session.openChannel("exec"); channel.setCommand(command); ByteArrayOutputStream responseStream = new ByteArrayOutputStream(); channel.setOutputStream(responseStream); channel.connect(); while (channel.isConnected()) { Thread.sleep(100); } String responseString = new String(responseStream.toByteArray()); System.out.println(responseString); } finally { if (session != null) { session.disconnect(); } if (channel != null) { channel.disconnect(); } } }

Wie wir im Code sehen können, erstellen wir zuerst eine Client-Sitzung und konfigurieren sie für die Verbindung mit unserem SSH-Server. Anschließend erstellen wir einen Clientkanal für die Kommunikation mit dem SSH-Server, in dem wir einen Kanaltyp angeben - in diesem Fall exec, was bedeutet, dass wir Shell-Befehle an den Server übergeben.

Außerdem sollten wir den Ausgabestream für unseren Kanal festlegen, in den die Serverantwort geschrieben wird. Nachdem wir die Verbindung mit der Methode channel.connect () hergestellt haben, wird der Befehl übergeben und die empfangene Antwort auf die Konsole geschrieben.

Mal sehen, wie man verschiedene Konfigurationsparameter verwendet, die JSch bietet :

  • StrictHostKeyChecking - Gibt an, ob die Anwendung prüft, ob der öffentliche Hostschlüssel unter bekannten Hosts gefunden wurde. Die verfügbaren Parameterwerte sind außerdem ask , yes und no , wobei ask die Standardeinstellung ist. Wenn wir diese Eigenschaft auf yes setzen , fügt JSch den Hostschlüssel niemals automatisch zur Datei unknown_hosts hinzu und verweigert die Verbindung zu Hosts, deren Hostschlüssel sich geändert hat. Dies zwingt den Benutzer, alle neuen Hosts manuell hinzuzufügen. Wenn wir es auf no setzen , fügt JSch der Liste der bekannten Hosts automatisch einen neuen Hostschlüssel hinzu
  • compress.s2c - Gibt an, ob die Komprimierung für den Datenstrom vom Server zu unserer Clientanwendung verwendet werden soll. Verfügbare Werte sind zlib und keine, wobei der zweite Standard ist
  • compress.c2s - Gibt an, ob die Komprimierung für den Datenstrom in Client-Server-Richtung verwendet werden soll. Verfügbare Werte sind zlib und keine, wobei der zweite Standard ist

Es ist wichtig, die Sitzung und den SFTP-Kanal nach Beendigung der Kommunikation mit dem Server zu schließen, um Speicherverluste zu vermeiden .

3. Apache MINA SSHD

Apache MINA SSHD bietet SSH-Unterstützung für Java-basierte Anwendungen. Diese Bibliothek basiert auf Apache MINA, einer skalierbaren und leistungsstarken asynchronen E / A-Bibliothek.

Fügen wir die Abhängigkeit von Apache Mina SSHD Maven hinzu:

 org.apache.sshd sshd-core 2.5.1 

3.1. Implementierung

Sehen wir uns das Codebeispiel für die Verbindung zum SSH-Server mit Apache MINA SSHD an:

public static void listFolderStructure(String username, String password, String host, int port, long defaultTimeoutSeconds, String command) throws IOException { SshClient client = SshClient.setUpDefaultClient(); client.start(); try (ClientSession session = client.connect(username, host, port) .verify(defaultTimeoutSeconds, TimeUnit.SECONDS).getSession()) { session.addPasswordIdentity(password); session.auth().verify(defaultTimeoutSeconds, TimeUnit.SECONDS); try (ByteArrayOutputStream responseStream = new ByteArrayOutputStream(); ClientChannel channel = session.createChannel(Channel.CHANNEL_SHELL)) { channel.setOut(responseStream); try { channel.open().verify(defaultTimeoutSeconds, TimeUnit.SECONDS); try (OutputStream pipedIn = channel.getInvertedIn()) { pipedIn.write(command.getBytes()); pipedIn.flush(); } channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), TimeUnit.SECONDS.toMillis(defaultTimeoutSeconds)); String responseString = new String(responseStream.toByteArray()); System.out.println(responseString); } finally { channel.close(false); } } } finally { client.stop(); } }

Bei der Arbeit mit der Apache MINA SSHD haben wir eine ziemlich ähnliche Abfolge von Ereignissen wie bei JSch. Zunächst stellen wir mithilfe der SshClient- Klasseninstanz eine Verbindung zu einem SSH-Server her . Wenn wir es mit SshClient.setupDefaultClient () initialisieren , können wir mit der Instanz arbeiten, deren Standardkonfiguration für die meisten Anwendungsfälle geeignet ist. Dies umfasst Chiffren, Komprimierung, MACs, Schlüsselaustausch und Signaturen.

Danach erstellen wir ClientChannel und hängen den ByteArrayOutputStream daran an, damit wir ihn als Antwortstrom verwenden können. Wie wir sehen können, erfordert SSHD definierte Zeitüberschreitungen für jede Operation. Außerdem können wir mithilfe der Channel.waitFor () -Methode definieren, wie lange auf die Serverantwort gewartet wird, nachdem der Befehl übergeben wurde .

Es ist wichtig zu beachten, dass SSHD die vollständige Konsolenausgabe in den Antwortstrom schreibt. JSch führt dies nur mit dem Ergebnis der Befehlsausführung aus.

Die vollständige Dokumentation zu Apache Mina SSHD finden Sie im offiziellen GitHub-Repository des Projekts.

4. Fazit

In diesem Artikel wurde veranschaulicht, wie eine SSH-Verbindung mit Java mithilfe von zwei der verfügbaren Java-Bibliotheken hergestellt wird - JSch und Apache Mina SSHD. Wir haben auch gezeigt, wie der Befehl an den Remote-Server übergeben und das Ausführungsergebnis abgerufen wird. Auf GitHub sind auch vollständige Codebeispiele verfügbar.

Java unten

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs