20.08.2015

ssh-Bibliothek für Java

Nach dem ganzen politischen und schulischen Kram, mit dem ich mich letztens beschäftigt habe, mal wieder 'was Interessantes für Programmierer.

Ich habe durch ein berufliches Projekt von einer coolen Java-Bibliothek erfahren, mit der man SSH verwenden kann, ohne externe Programme aufzurufen. Und diese Bibliothek nutzt sogar das OpenSSH-Format für persönliche und Host-Keys! Das gefällt mir gut ;)

Die Rede ist von JSch (Java Secure channel), das in einer sehr frühen Version vorliegt, aber schon ganz gut funktioniert.

So bekommt man es zum Laufen:

Man braucht ant zum Selberbauen, wenn man nicht das fertige Jar als Archiv von sourceforge herunterladen will.
Nach dem Auspacken wechselt man einfach in das JSch-Verzeichnis und ruft build.sh auf. Wie üblich sollte JAVA_HOME gesetzt sein.
Danach findet sich in dist/lib die jar-Datei, die man dann in den CLASSPATH aufnehmen kann.

jsch-0.1.53 $ PATH=$PATH:~/apache-ant/bin
jsch-0.1.53 $ ant
Buildfile: /home/tseeling/java/jsch-0.1.53/build.xml

init:

compile:

dist:
      [jar] Building jar: /home/tseeling/java/jsch-0.1.53/dist/lib/jsch-0.1.53.jar

BUILD SUCCESSFUL




Danach kann man dann im eigenen Java-Programm den private key laden, die known_hosts laden und auf einem anderen System Befehl ausführen. Außerdem ist es möglich, Subsysteme wie sftp direkt anzusprechen. Cool ;)

Hier ist ein kleines Programm, das ähnlich wie das "echte" ssh einen Befehl auf einen anderen Rechner schickt. Natürlich steckt man die Passphrase nicht hartkodiert ins Programm oder übergibt sie auf der Kommandozeile, das ist nur ein kleines Beispiel ;)

$ javac -classpath jsch-0.1.53.jar shell.java
$ java -classpath .:jsch-0.1.53.jar shell ths server ~/.ssh/id_rsa ***
Linux

Und hier das Beispielprogramm:

import com.jcraft.jsch.*;
import java.util.Properties;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class shell{
  public static void main(String[] argv){

    try{
      JSch jsch=new JSch();
      Properties config = new Properties();
      String home=System.getProperty("user.home");
      String user=System.getProperty("user.name");
      String key=home+"/.ssh/id_rsa";
      String passphrase="";
      String host="localhost";
      String cmd="uname";

      if (argv.length>0) { user      =argv[0]; }
      if (argv.length>1) { host      =argv[1]; }
      if (argv.length>2) { key       =argv[2]; }
      if (argv.length>3) { passphrase=argv[3]; }
      if (argv.length>4) { cmd       =argv[4]; }

      jsch.addIdentity(key,passphrase);
      jsch.setKnownHosts(home+"/.ssh/known_hosts");
      config.put("StrictHostKeyChecking", "no");

      Session session=jsch.getSession(user, host, 22);
      session.setConfig(config);
      session.connect();
      ChannelExec channel=(ChannelExec) session.openChannel("exec");
      BufferedReader in=new BufferedReader(new InputStreamReader(channel.getInputStream()));
      channel.setCommand(cmd);
      channel.connect();

      String msg=null;
      while((msg=in.readLine())!=null){
        System.out.println(msg);
      }

      channel.disconnect();
      session.disconnect();

    }
    catch(Exception e){
      System.out.println(e);
    }
  }
}