Solved

How to construct an ssh tunnel inside a java program

Posted on 2012-12-26
8
1,187 Views
Last Modified: 2013-01-01
How to have a java program do the same thing as the ssh unix command (0) where the userName does not have a password associated with it?


(0) The unix command that works
 ssh -i ~/.ssh/pemFile.pem -L 8000:ec2-0-0-0-0.compute-1.amazonaws.com:8000 userName@ec2-0-0-0-0.compute-1.amazonaws.com
 


(1) The pem file
-----BEGIN RSA PRIVATE KEY-----
SOMETEXSOMETEXTALJDLAJFAJFLADSFJASDFFDA
ALDFJALFJASLDFASFDASJDLFJASLDFJAJSSDLF
-----END RSA PRIVATE KEY-----

(2) Java program that currently does not work ( i think i need a user info object or something also I do not have both a cert and key in my pem file do I need to generate one of these?)
public static void main (String args []) throws Exception {
            String pemPath = "/Users/username/.ssh/pemFile.pem";
            String ec2 = "userName@ec2-0-0-0-0.compute-1.amazonaws.com";
            SSLSocketFactory factory = null;
             factory = getSocketFactoryPEM(pemPath);
            InetAddress remote = InetAddress.getByName(ec2);
            InetAddress local = InetAddress.getByName("localhost");
            
            Socket socket = factory.createSocket(remote, 8000, local, 8000);
      }

      public static SSLSocketFactory getSocketFactoryPEM(String pemPath) throws Exception {  
            
          Security.addProvider(new BouncyCastleProvider());

          SSLContext context = SSLContext.getInstance("TLS");

          byte[] certAndKey = getBytesFromFile(new File(pemPath));

          String delimiter = "-----BEGIN RSA PRIVATE KEY-----";
          String[] tokens = new String(certAndKey).split(delimiter);

          byte[] certBytes = tokens[0].concat(delimiter).getBytes();
          //byte[] keyBytes = tokens[1].getBytes();

          PEMReader reader;

          reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(certBytes)));
          X509Certificate cert = (X509Certificate)reader.readObject();        

          //reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(keyBytes)));
          //PrivateKey key = (PrivateKey)reader.readObject();        

          KeyStore keystore = KeyStore.getInstance("JKS");
          keystore.load(null);
          keystore.setCertificateEntry("cert-alias", cert);
          //keystore.setKeyEntry("key-alias", key, "changeit".toCharArray(), new Certificate[] {cert});

          KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
          kmf.init(keystore, "changeit".toCharArray());

          KeyManager[] km = kmf.getKeyManagers();

          context.init(km, null, null);

          return context.getSocketFactory();
      }
0
Comment
Question by:RichardSDetsch
  • 3
  • 3
  • 2
8 Comments
 
LVL 25

Expert Comment

by:Tomas Helgi Johannsson
ID: 38723116
Hi!

Here are some examples to look at
http://www.example-code.com/java/ssh.asp
http://www.beanizer.org/site/index.php/en/Articles/Java-ssh-tunneling-with-jsch.html

Hope this helps.

Regards,
    Tomas Helgi
0
 

Assisted Solution

by:RichardSDetsch
RichardSDetsch earned 0 total points
ID: 38723897
Thanks for the links they are helpful.  I will try them tonight.

Here are some of my thoughts before though.

A. The JSCH does not show me what to do with the pem file and also I do not know what to put in the userInfo object, note the unix command (0) above does not require any user input after running. If there is a command in JSCH like I see "addIdentity" what format should I give my pem file do I have to trim the -----BEGIN RSA PRIVATE KEY----- and make it byte array form.

B. If I do privKey = key.loadText("myPrivateKey.pem"); can I just give it my pem the way it is.  For the below how can I verify that a public key is in the remote ~/.ssh directory and if it is not there can I generate it from the pem file?  Does it have to exist for my unix command (0) to work?

//  Authenticate with the SSH server using the login and
    //  private key.  (The corresponding public key should've
    //  been installed on the SSH server beforehand.)
    success = ssh.AuthenticatePk("myLogin",key);
    if (success != true) {
        System.out.println(ssh.lastErrorText());
        return;
    }

Thanks, Shane
0
 
LVL 25

Accepted Solution

by:
Tomas Helgi Johannsson earned 500 total points
ID: 38723978
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 38724080
For the below how can I verify that a public key is in the remote ~/.ssh directory
If it's not there how would this work?
(0) The unix command that works
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 25

Expert Comment

by:Tomas Helgi Johannsson
ID: 38724188
You will have to upload your keys to the remote server and put it into the .ssh directory for the ssh connection to work to that server.

Regards,
    Tomas Helgi
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 38724216
You will have to upload your keys to the remote server and put it into the .ssh directory
That's already done (see my last comment)

In fact, it's conceivable you might have to do the reverse if you're using Jsch, as the load methods for keys seem to want to work only with a pair of files
0
 

Author Comment

by:RichardSDetsch
ID: 38725122
Thanks the below works and was derived form http://stackoverflow.com/questions/7525679/how-to-get-the-java-security-privatekey-object-from-rsa-privatekey-pem-from-a-f

public static void main (String args []) throws Exception {
            String pemPath = "/Users/userName/.ssh/pemFile.pem";
            String ec2 = "ec2-xxxxxxxx-.compute-1.amazonaws.com";
            Session session = connect(ec2, pemPath);
            session.connect();
          Thread.sleep(60000);
            session.disconnect();
}
     
       public static Session connect(String dnsName, String privKey) throws IOException {
                JSch jSch = new JSch();

                Session session = null;
                try {
                    jSch.addIdentity(privKey);
                    session = jSch.getSession("someUser", dnsName, 22);
                    java.util.Properties config = new java.util.Properties();
                    config.put("StrictHostKeyChecking", "no");
                    session.setConfig(config);
                    System.out.println("Connecting SSH to " + dnsName + " - Please wait for few minutes... ");
                    System.out.println("Forwarding");
                        int assinged_port = session.setPortForwardingL(80, dnsName, 80);
                        System.out.println("localhost:"+assinged_port+" -> "+dnsName+":80");

                } catch (JSchException e) {
                    e.printStackTrace();
                }
                  return session;

            }
0
 

Author Closing Comment

by:RichardSDetsch
ID: 38734249
Thanks the below works and was derived form http://stackoverflow.com/questions/7525679/how-to-get-the-java-security-privatekey-object-from-rsa-privatekey-pem-from-a-f

public static void main (String args []) throws Exception {
            String pemPath = "/Users/userName/.ssh/pemFile.pem";
            String ec2 = "ec2-xxxxxxxx-.compute-1.amazonaws.com";
            Session session = connect(ec2, pemPath);
            session.connect();
          Thread.sleep(60000);
            session.disconnect();
}
      
       public static Session connect(String dnsName, String privKey) throws IOException {
                JSch jSch = new JSch();

                Session session = null;
                try {
                    jSch.addIdentity(privKey);
                    session = jSch.getSession("scbeCoreDevUsEast1", dnsName, 22);
                    java.util.Properties config = new java.util.Properties();
                    config.put("StrictHostKeyChecking", "no");
                    session.setConfig(config);
                    System.out.println("Connecting SSH to " + dnsName + " - Please wait for few minutes... ");
                    System.out.println("Forwarding");
                        int assinged_port = session.setPortForwardingL(8081, dnsName, 8080);
                        System.out.println("localhost:"+assinged_port+" -> "+dnsName+":8080");

                } catch (JSchException e) {
                    e.printStackTrace();
                }
                  return session;

            }
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
mapAB Challlenge 35 128
Unexpected HttpURLConnection connection behavior 2 86
JavaScript/Java - Changing an image background color 4 56
rhino JavaScript import, load 25 69
This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now