SSH-verbinding met Java

Java Top

Ik heb zojuist het nieuwe aangekondigd Leer de lente natuurlijk, gericht op de basisprincipes van Spring 5 en Spring Boot 2:

>> BEKIJK DE CURSUS

1. Inleiding

SSH, ook wel Secure Shell of Secure Socket Shell genoemd, is een netwerkprotocol waarmee een computer veilig verbinding kan maken met een andere computer via een onbeveiligd netwerk. In deze tutorial laten we zien hoe een verbinding tot stand brengen met een externe SSH-server met Java met behulp van de JSch- en Apache MINA SSHD-bibliotheken.

In onze voorbeelden openen we eerst de SSH-verbinding, voeren dan een commando uit, lezen de uitvoer en schrijven deze naar de console, en ten slotte sluiten we de SSH-verbinding. We houden de voorbeeldcode zo eenvoudig mogelijk.

2. JSch

JSch is de Java-implementatie van SSH2 waarmee we verbinding kunnen maken met een SSH-server en gebruik kunnen maken van port forwarding, X11 forwarding en bestandsoverdracht. Het is ook gelicentieerd onder de BSD-stijllicentie en biedt ons een gemakkelijke manier om een ​​SSH-verbinding met Java tot stand te brengen.

Laten we eerst de JSch Maven-afhankelijkheid toevoegen aan onze pom.xml het dossier:

 com.jcraft jsch 0.1.55 

2.1. Implementatie

Om een ​​SSH-verbinding tot stand te brengen met JSch, hebben we een gebruikersnaam, wachtwoord, host-URL en SSH-poort nodig. De standaard SSH-poort is 22, maar het kan gebeuren dat we de server configureren om een ​​andere poort te gebruiken voor SSH-verbindingen:

openbare statische ongeldige listFolderStructure (String-gebruikersnaam, String-wachtwoord, String-host, int-poort, String-opdracht) genereert Uitzondering {Session session = null; ChannelExec kanaal = null; probeer {session = new JSch (). getSession (gebruikersnaam, host, poort); session.setPassword (wachtwoord); session.setConfig ("StrictHostKeyChecking", "nee"); session.connect (); channel = (ChannelExec) session.openChannel ("exec"); channel.setCommand (opdracht); ByteArrayOutputStream responseStream = nieuwe ByteArrayOutputStream (); channel.setOutputStream (responseStream); channel.connect (); while (channel.isConnected ()) {Thread.sleep (100); } String responseString = nieuwe String (responseStream.toByteArray ()); System.out.println (responseString); } eindelijk {if (session! = null) {session.disconnect (); } if (kanaal! = null) {kanaal.disconnect (); }}}

Zoals we in de code kunnen zien, maken we eerst een clientsessie en configureren deze voor verbinding met onze SSH-server. Vervolgens maken we een clientkanaal aan dat wordt gebruikt om te communiceren met de SSH-server waar we een kanaaltype opgeven - in dit geval uitvoerder, wat betekent dat we shell-opdrachten aan de server zullen doorgeven.

We moeten ook de uitvoerstroom voor ons kanaal instellen waar de serverreactie zal worden geschreven. Nadat we de verbinding tot stand hebben gebracht met behulp van de channel.connect () methode, wordt de opdracht doorgegeven en wordt het ontvangen antwoord op de console geschreven.

Laten we kijken hoe u verschillende configuratieparameters gebruikt die JSch biedt:

  • StrictHostKeyChecking - het geeft aan of de toepassing zal controleren of de publieke sleutel van de host kan worden gevonden bij bekende hosts. Beschikbare parameterwaarden zijn ook vragen, Ja, en Nee, waar vragen is de standaard. Als we deze eigenschap instellen op Ja, Zal JSch de hostsleutel nooit automatisch aan het bekende_hosts bestand, en het zal weigeren om verbinding te maken met hosts waarvan de hostsleutel is gewijzigd. Dit dwingt de gebruiker om alle nieuwe hosts handmatig toe te voegen. Als we het instellen op Nee, Zal JSch automatisch een nieuwe hostsleutel toevoegen aan de lijst met bekende hosts
  • compressie.s2c - specificeert of compressie moet worden gebruikt voor de datastroom van de server naar onze clienttoepassing. Beschikbare waarden zijn zlib en geen waarbij de tweede de standaard is
  • compressie.c2s - specificeert of compressie moet worden gebruikt voor de datastroom in de client-serverrichting. Beschikbare waarden zijn zlib en geen waar de tweede de standaard is

Het is belangrijk om sluit de sessie en het SFTP-kanaal nadat de communicatie met de server is beëindigd om geheugenlekken te voorkomen.

3. Apache MINA SSHD

Apache MINA SSHD biedt SSH-ondersteuning voor op Java gebaseerde applicaties. Deze bibliotheek is gebaseerd op Apache MINA, een schaalbare en hoogwaardige asynchrone IO-bibliotheek.

Laten we de Apache Mina SSHD Maven-afhankelijkheid toevoegen:

 org.apache.sshd sshd-core 2.5.1 

3.1. Implementatie

Laten we het codevoorbeeld bekijken van verbinding maken met de SSH-server met Apache MINA SSHD:

openbare statische ongeldige listFolderStructure (String gebruikersnaam, String wachtwoord, String host, int poort, lange defaultTimeoutSeconds, String commando) gooit IOException {SshClient client = SshClient.setUpDefaultClient (); client.start (); probeer (ClientSession-sessie = client.connect (gebruikersnaam, host, poort) .verify (defaultTimeoutSeconds, TimeUnit.SECONDS) .getSession ()) {session.addPasswordIdentity (wachtwoord); session.auth (). verify (defaultTimeoutSeconds, TimeUnit.SECONDS); probeer (ByteArrayOutputStream responseStream = nieuwe ByteArrayOutputStream (); ClientChannel kanaal = session.createChannel (Channel.CHANNEL_SHELL)) {channel.setOut (responseStream); probeer {kanaal.open (). verifieer (defaultTimeoutSeconds, TimeUnit.SECONDS); probeer (OutputStream pipedIn = channel.getInvertedIn ()) {pipedIn.write (command.getBytes ()); pipedIn.flush (); } channel.waitFor (EnumSet.of (ClientChannelEvent.CLOSED), TimeUnit.SECONDS.toMillis (defaultTimeoutSeconds)); String responseString = nieuwe String (responseStream.toByteArray ()); System.out.println (responseString); } eindelijk {channel.close (false); }}} eindelijk {client.stop (); }}

Wanneer we met de Apache MINA SSHD werken, hebben we een redelijk vergelijkbare reeks gebeurtenissen als met JSch. Eerst brengen we een verbinding tot stand met een SSH-server met behulp van de SshClient klasse-instantie. Als we het initialiseren met SshClient.setupDefaultClient (), we kunnen werken met de instantie die een standaardconfiguratie heeft die geschikt is voor de meeste gebruiksscenario's. Dit omvat cijfers, compressie, MAC's, sleuteluitwisselingen en handtekeningen.

Daarna maken we ClientChannel en bevestig het ByteArrayOutputStream naar het toe, zodat we het zullen gebruiken als een antwoordstroom. Zoals we kunnen zien, vereist SSHD voor elke bewerking gedefinieerde time-outs. Het stelt ons ook in staat om te definiëren hoe lang het zal wachten op een serverreactie nadat de opdracht is doorgegeven door gebruik te maken van Channel.waitFor () methode.

Het is belangrijk om dat op te merken SSHD schrijft de volledige console-uitvoer naar de antwoordstroom. JSch zal het alleen doen met het resultaat van de uitvoering van de opdracht.

Volledige documentatie over Apache Mina SSHD is beschikbaar in de officiële GitHub-repository van het project.

4. Conclusie

Dit artikel illustreert hoe u een SSH-verbinding met Java tot stand brengt met behulp van twee van de beschikbare Java-bibliotheken: JSch en Apache Mina SSHD. We hebben ook laten zien hoe je de opdracht doorgeeft aan de externe server en het uitvoeringsresultaat krijgt. Er zijn ook complete codevoorbeelden beschikbaar op GitHub.

Java onderkant

Ik heb zojuist het nieuwe aangekondigd Leer de lente natuurlijk, gericht op de basisprincipes van Spring 5 en Spring Boot 2:

>> BEKIJK DE CURSUS