Connexion SSH avec Java

Haut Java

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS

1. Introduction

SSH, également connu sous le nom de Secure Shell ou Secure Socket Shell, est un protocole réseau qui permet à un ordinateur de se connecter en toute sécurité à un autre ordinateur via un réseau non sécurisé. Dans ce didacticiel, nous montrerons comment établir une connexion à un serveur SSH distant avec Java à l'aide des bibliothèques SSHD JSch et Apache MINA .

Dans nos exemples, nous allons d'abord ouvrir la connexion SSH, puis exécuter une commande, lire la sortie et l'écrire sur la console, et enfin fermer la connexion SSH. Nous allons garder l'exemple de code aussi simple que possible.

2. JSch

JSch est l'implémentation Java de SSH2 qui nous permet de nous connecter à un serveur SSH et d'utiliser le transfert de port, le transfert X11 et le transfert de fichiers. En outre, il est sous licence de style BSD et nous fournit un moyen facile d'établir une connexion SSH avec Java.

Tout d'abord, ajoutons la dépendance JSch Maven à notre fichier pom.xml :

 com.jcraft jsch 0.1.55 

2.1. la mise en oeuvre

Pour établir une connexion SSH à l'aide de JSch, nous avons besoin d'un nom d'utilisateur, d'un mot de passe, d'une URL d'hôte et d'un port SSH . Le port SSH par défaut est 22, mais il se peut que nous configurions le serveur pour utiliser un autre port pour les connexions SSH:

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(); } } }

Comme nous pouvons le voir dans le code, nous créons d'abord une session client et la configurons pour la connexion à notre serveur SSH. Ensuite, nous créons un canal client utilisé pour communiquer avec le serveur SSH où nous fournissons un type de canal - dans ce cas, exec, ce qui signifie que nous passerons des commandes shell au serveur.

De plus, nous devons définir le flux de sortie de notre canal où la réponse du serveur sera écrite. Après avoir établi la connexion à l'aide de la méthode channel.connect () , la commande est passée et la réponse reçue est écrite sur la console.

Voyons comment utiliser les différents paramètres de configuration proposés par JSch :

  • StrictHostKeyChecking - il indique si l'application vérifiera si la clé publique de l'hôte peut être trouvée parmi les hôtes connus. En outre, les valeurs de paramètre disponibles sont ask , yes et no , où ask est la valeur par défaut. Si nous définissons cette propriété sur yes , JSch n'ajoutera jamais automatiquement la clé d'hôte au fichier known_hosts et refusera de se connecter aux hôtes dont la clé d'hôte a changé. Cela oblige l'utilisateur à ajouter manuellement tous les nouveaux hôtes. Si nous le définissons sur non , JSch ajoutera automatiquement une nouvelle clé d'hôte à la liste des hôtes connus
  • compression.s2c - spécifie s'il faut utiliser la compression pour le flux de données du serveur vers notre application cliente. Les valeurs disponibles sont zlib et none où la seconde est la valeur par défaut
  • compression.c2s - spécifie s'il faut utiliser la compression pour le flux de données dans le sens client-serveur. Les valeurs disponibles sont zlib et none où la seconde est la valeur par défaut

Il est important de fermer la session et le canal SFTP une fois la communication avec le serveur terminée pour éviter les fuites de mémoire .

3. Apache MINA SSHD

Apache MINA SSHD prend en charge SSH pour les applications Java. Cette bibliothèque est basée sur Apache MINA, une bibliothèque d'E / S asynchrones évolutive et performante.

Ajoutons la dépendance Apache Mina SSHD Maven:

 org.apache.sshd sshd-core 2.5.1 

3.1. la mise en oeuvre

Voyons l'exemple de code de connexion au serveur SSH à l'aide d'Apache MINA SSHD:

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(); } }

Lorsque vous travaillez avec Apache MINA SSHD, nous avons une séquence d'événements assez similaire à celle de JSch. Tout d'abord, nous établissons une connexion à un serveur SSH à l'aide de l' instance de classe SshClient . Si nous l'initialisons avec SshClient.setupDefaultClient (), nous pourrons travailler avec l'instance qui a une configuration par défaut adaptée à la plupart des cas d'utilisation. Cela comprend les chiffrements, la compression, les adresses MAC, les échanges de clés et les signatures.

Après cela, nous allons créer ClientChannel et y attacher le ByteArrayOutputStream , afin que nous l' utilisions comme flux de réponse. Comme nous pouvons le voir, SSHD nécessite des délais d'expiration définis pour chaque opération. Cela nous permet également de définir combien de temps il attendra la réponse du serveur une fois la commande passée à l'aide de la méthode Channel.waitFor () .

Il est important de noter que SSHD écrira la sortie complète de la console dans le flux de réponse. JSch le fera uniquement avec le résultat de l'exécution de la commande.

Une documentation complète sur Apache Mina SSHD est disponible sur le référentiel GitHub officiel du projet.

4. Conclusion

Cet article a illustré comment établir une connexion SSH avec Java à l'aide de deux des bibliothèques Java disponibles - JSch et Apache Mina SSHD. Nous avons également montré comment passer la commande au serveur distant et obtenir le résultat de l'exécution. En outre, des exemples de code complets sont disponibles à l'adresse over sur GitHub.

Fond Java

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS