Solved

How to construct an ssh tunnel inside a java program

Posted on 2012-12-26
8
1,320 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Transaction Monitoring Vs. Real User Monitoring

Synthetic Transaction Monitoring Vs. Real User Monitoring: When To Use Each Approach? In this article, we will discuss two major monitoring approaches: Synthetic Transaction and Real User Monitoring.

 
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
 
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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:

691 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