Monday, July 20, 2015

Multi hop tunneling in Android/Java

Once I  was mentoring an intern for an app development in Android. The aim of the application was to create an android app for an existing web application.But the application is deployed in a server which is not in public domain.The application is in LAN.But the aim of the android app was to monitor the application on the go.Even if the support guy is not in  the office,but still he should be able to access the app in his mobile device.

Assume the scenarios are like this.Suppose server A is the gateway of the LAN.And server B is the central server in the LAN which is accessible from the server A.And C is another central server which is accessible from server B. And our web application is deployed in server D in the same LAN which is accessible from server C.Our web application is deployed in tomcat installed in server D.And tomcat is running on port 9091.Our aim is to access the URL eg. http://ipaddress:9091/appname  in our android application. 

Immediately some solutions come to mind.One of them is first open the gateway of the office LAN with the help of putty software.Then forward the central server of the LAN by ssh tunneling which is accessible from the LAN gateway . Then open the desired server from  the Central server.For this we can take the help of putty software for android.Or we can use ConnectBot for android.Then we will do all the required tunneling for all the servers.But here one disadvantage is  we have to install one more extra application like putty or ConnectBot in the mobile device.So here comes a  third party dependence,which is not desired. So what can be done here?

So next thing we want to do is multi hop ssh tunneling with the help of some third party api which can be imported  as a library with the application. The available APIs are Chilkat SSH,JSCH,Trilead SSH etc.
But we decided to use JSCH(Java secure channel).
Now we will  do multiple hop ssh tunneling by using JSCH.And we will look implementation  of port forwarding by JSCH.




import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class PortForward {
    public static void main(String[] args) {
     
 
        int lport;
        String rhost;
        int rport;
      //  protected String doInBackground(String... arg0) {
            JSch jsch=new JSch();
            try{
                String user="LanGateway";
                String host="LanGatewayIp";
                String pswd="LanGatewayPassword";
                Session session=jsch.getSession(user, host, 22);
                session.setPassword(pswd);
                java.util.Properties config = new java.util.Properties();
                config.put("StrictHostKeyChecking", "no");
                session.setConfig(config);
                session.connect();

                lport=2249;
                rhost= "CentralServerIp";
                rport= 22;
                int assinged_port=session.setPortForwardingL(lport, rhost, rport);
           
                String user2="UserForCentralServer";
                String pswd2= "CentralServerPassword";
                Session session2=jsch.getSession(user2, "localhost", assinged_port);
                session2.setPassword(pswd2);

                session2.setConfig(config);

                session2.connect();
                lport=2248;
                rhost= "CentralServer2";
                rport= 22;
                int assinged_port2=session2.setPortForwardingL(lport, rhost, rport);
            
                String user3="UserForCentralServer2";
                String pswd3= "PasswordForCentralServer2";
                Session session3=jsch.getSession(user3, "localhost", assinged_port2);
                session3.setPassword(pswd3);

                session3.setConfig(config);
                session3.connect();
                lport=2246;
                rhost= "webApplicationServer";
                rport= 22;
                int assinged_port3=session3.setPortForwardingL(lport, rhost, rport);
       

                String user4="webapplicationServerUserName";
                String pswd4= "webapplicationServerPassword";
                Session session4=jsch.getSession(user4,           "localhost", assinged_port3);
                session4.setPassword(pswd4);
                session4.setConfig(config);
                session4.connect();

                lport=9095;
                rhost= "localhost";
                rport= 9091;
               int  assinged_port4=session4.setPortForwardingL(lport, rhost, rport);

 /*
  You can  write code here to check if the port for tomcat is forwarded properly or not.Just write code to hit the url http://localhost:9095.And you will get the tomcat's home page as     response.Otherwise just open your browser and write http://localhost:9095 in address bar and hit enter  button.You will see tomcat's home page in your browser.
 */
              
 }
     catch(Exception e){
       e.printStacktrace();

  }


           // return rhost;
}}

The above code is straight forward and self explanatory.In similar manner we can forward any port locally.
Like we can forward Mysql port  also to access Mysql of the remote system in our machine.


2 comments:

  1. when I try to create a session on the second sever it says "connection closed by foreign server"
    Why is that coming?

    ReplyDelete
    Replies
    1. Hi Kishen,
      Please follow the following steps to ensure the connectivity.
      1.Use a third party tool like winscp or filezilla to check the connectivity from the same server from where you are initiating the session.
      2.Please check the user id and password and the access level of the user,ie if the user has full perimission to access the file or dir.
      3.If all of the above not works ,please try with a different forwarded port(because that port might already in use.)

      Delete