{"id":38,"date":"2016-05-06T08:53:29","date_gmt":"2016-05-06T08:53:29","guid":{"rendered":"http:\/\/symbioticindia.in\/docu\/?p=38"},"modified":"2016-05-06T08:53:29","modified_gmt":"2016-05-06T08:53:29","slug":"java-ssh-tunneling-with-jsch","status":"publish","type":"post","link":"http:\/\/symbioticindia.in\/docu\/2016\/05\/06\/java-ssh-tunneling-with-jsch\/","title":{"rendered":"Java ssh tunneling with jsch"},"content":{"rendered":"<p><strong>Overview<\/strong><br \/>\nSome people are using my <a href=\"http:\/\/www.beanizer.org\/index.php3?page=tunnel4j\">Tunnel4J<\/a>, an easy graphical utility that allows connecting to remote ssh servers and mapping local and remote ports for tunneling. Tunnel4J is based on <a href=\"http:\/\/www.jcraft.com\/\">Jcraft&#8217;s Jsch<\/a>, an excellent 100% java library for ssh. As I recently received multiple requests about how to do ssh tunneling in java, I&#8217;ve decided to write this short article as a quickstart.<\/p>\n<p><strong>The whys<\/strong><br \/>\nSsh tunneling is used to access network resources located behind a firewall otherwise impossible to reach.<br \/>\nWhat is explained here can also be achieved by simply using openssh on unix systems or systems for which openssh portings exist, as explained <a href=\"http:\/\/www.beanizer.org\/index.php3?page=tt8\">here<\/a> and <a href=\"http:\/\/www.beanizer.org\/index.php3?page=tt10\">here<\/a>.<br \/>\nUsing a 100% pure java library to achieve this guarantees platform independence. Below you can see a typical situation requiring ssh tunneling:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.beanizer.org\/img\/tunneling.png\" alt=\"Typical situation requiring ssh tunneling\" border=\"1\" \/><\/p>\n<p>In this case we need to access a web server (port 80) hosted on a machine located behind a firewall and not directly accessible. Provided we have an ssh account to the firewall, we can connect to it and make a tcp local forward to gain access to the web server on the LAN web server. Let&#8217;s see how.<\/p>\n<p><strong>The code<\/strong><\/p>\n<p>First please download Jsch from <a href=\"http:\/\/www.jcraft.com\/\">Jcraft<\/a>, and put it in your classpath.<br \/>\nBelow is a simple, basic but working class, useful to explain the basics of tunneling thru Jsch.<\/p>\n<div>\n<pre><span style=\"color: #f5deb3;\"><span style=\"color: #ffffcc;\">   1:<\/span><span style=\"color: #00cc99;\">import<\/span> com.jcraft.jsch.*;\r\n<span style=\"color: #ffffcc;\">   2:<\/span>\r\n<span style=\"color: #ffffcc;\">   3:<\/span><span style=\"color: #ffa500;\">public<\/span> <span style=\"color: #cc6600;\">class<\/span> Tunnel <span style=\"color: #00ffff;\">{<\/span>\r\n<span style=\"color: #ffffcc;\">   4:<\/span>    <span style=\"color: #ffa500;\">public<\/span> <span style=\"color: #ffa500;\">static<\/span> <span style=\"color: #cc6600;\">void<\/span> <span style=\"color: #b2dfee;\">main<\/span>(String[] args)<span style=\"color: #00ffff;\">{<\/span>\r\n<span style=\"color: #00cd00;\">   5:<\/span>        Tunnel t<span style=\"color: #00ffff;\">=<\/span><span style=\"color: #ffa500;\">new<\/span> <span style=\"color: #b2dfee;\">Tunnel<\/span>();\r\n<span style=\"color: #ffffcc;\">   6:<\/span>        <span style=\"color: #ffa500;\">try<\/span><span style=\"color: #00ffff;\">{<\/span>\r\n<span style=\"color: #ffffcc;\">   7:<\/span>            t.<span style=\"color: #b2dfee;\">go<\/span>();\r\n<span style=\"color: #ffffcc;\">   8:<\/span>        <span style=\"color: #00ffff;\">}<\/span> <span style=\"color: #ffa500;\">catch<\/span>(Exception ex)<span style=\"color: #00ffff;\">{<\/span>\r\n<span style=\"color: #ffffcc;\">   9:<\/span>            ex.<span style=\"color: #b2dfee;\">printStackTrace<\/span>();\r\n<span style=\"color: #00cd00;\">  10:<\/span>        <span style=\"color: #00ffff;\">}<\/span>\r\n<span style=\"color: #ffffcc;\">  11:<\/span>    <span style=\"color: #00ffff;\">}<\/span>\r\n<span style=\"color: #ffffcc;\">  12:<\/span>    <span style=\"color: #ffa500;\">public<\/span> <span style=\"color: #cc6600;\">void<\/span> <span style=\"color: #b2dfee;\">go<\/span>() <span style=\"color: #ffa500;\">throws<\/span> Exception<span style=\"color: #00ffff;\">{<\/span>\r\n<span style=\"color: #ffffcc;\">  13:<\/span>        String host<span style=\"color: #00ffff;\">=<\/span><span style=\"color: #00cd00;\">\"<\/span><span style=\"color: #00cd00;\">XXX.XXX.XXX.XXX<\/span><span style=\"color: #00cd00;\">\"<\/span>;\r\n<span style=\"color: #ffffcc;\">  14:<\/span>        String user<span style=\"color: #00ffff;\">=<\/span><span style=\"color: #00cd00;\">&amp;qmauot;<\/span><span style=\"color: #00cd00;\">username<\/span><span style=\"color: #00cd00;\">\"<\/span>;\r\n<span style=\"color: #00cd00;\">  15:<\/span>        String password<span style=\"color: #00ffff;\">=<\/span><span style=\"color: #00cd00;\">\"<\/span><span style=\"color: #00cd00;\">password<\/span><span style=\"color: #00cd00;\">\"<\/span>;\r\n<span style=\"color: #ffffcc;\">  16:<\/span>        <span style=\"color: #cc6600;\">int<\/span> port<span style=\"color: #00ffff;\">=<\/span><span style=\"color: #cdcd00;\">22<\/span>;\r\n<span style=\"color: #ffffcc;\">  17:<\/span>        \r\n<span style=\"color: #ffffcc;\">  18:<\/span>        <span style=\"color: #cc6600;\">int<\/span> tunnelLocalPort<span style=\"color: #00ffff;\">=<\/span><span style=\"color: #cdcd00;\">9080<\/span>;\r\n<span style=\"color: #ffffcc;\">  19:<\/span>        String tunnelRemoteHost<span style=\"color: #00ffff;\">=<\/span><span style=\"color: #00cd00;\">\"<\/span><span style=\"color: #00cd00;\">YYY.YYY.YYY.YYY<\/span><span style=\"color: #00cd00;\">\"<\/span>;\r\n<span style=\"color: #00cd00;\">  20:<\/span>        <span style=\"color: #cc6600;\">int<\/span> tunnelRemotePort<span style=\"color: #00ffff;\">=<\/span><span style=\"color: #cdcd00;\">80<\/span>;\r\n<span style=\"color: #ffffcc;\">  21:<\/span>        \r\n<span style=\"color: #ffffcc;\">  22:<\/span>        JSch jsch<span style=\"color: #00ffff;\">=<\/span><span style=\"color: #ffa500;\">new<\/span> <span style=\"color: #b2dfee;\">JSch<\/span>();\r\n<span style=\"color: #ffffcc;\">  23:<\/span>        Session session<span style=\"color: #00ffff;\">=<\/span>jsch.<span style=\"color: #b2dfee;\">getSession<\/span>(user, host, port);\r\n<span style=\"color: #ffffcc;\">  24:<\/span>        session.<span style=\"color: #b2dfee;\">setPassword<\/span>(password);\r\n<span style=\"color: #00cd00;\">  25:<\/span>        localUserInfo lui<span style=\"color: #00ffff;\">=<\/span><span style=\"color: #ffa500;\">new<\/span> <span style=\"color: #b2dfee;\">localUserInfo<\/span>();\r\n<span style=\"color: #ffffcc;\">  26:<\/span>        session.<span style=\"color: #b2dfee;\">setUserInfo<\/span>(lui);\r\n<span style=\"color: #ffffcc;\">  27:<\/span>        session.<span style=\"color: #b2dfee;\">connect<\/span>();\r\n<span style=\"color: #ffffcc;\">  28:<\/span>        session.<span style=\"color: #b2dfee;\">setPortForwardingL<\/span>(tunnelLocalPort,tunnelRemoteHost,tunnelRemotePort);\r\n<span style=\"color: #ffffcc;\">  29:<\/span>        System.out.<span style=\"color: #b2dfee;\">println<\/span>(<span style=\"color: #00cd00;\">\"<\/span><span style=\"color: #00cd00;\">Connected<\/span><span style=\"color: #00cd00;\">\"<\/span>);\r\n<span style=\"color: #00cd00;\">  30:<\/span>    \r\n<span style=\"color: #ffffcc;\">  31:<\/span>    <span style=\"color: #00ffff;\">}<\/span>\r\n<span style=\"color: #ffffcc;\">  32:<\/span>    \r\n<span style=\"color: #ffffcc;\">  33:<\/span>  <span style=\"color: #cc6600;\">class<\/span> localUserInfo <span style=\"color: #ffa500;\">implements<\/span> UserInfo<span style=\"color: #00ffff;\">{<\/span>\r\n<span style=\"color: #ffffcc;\">  34:<\/span>    String passwd;\r\n<span style=\"color: #00cd00;\">  35:<\/span>    <span style=\"color: #ffa500;\">public<\/span> String <span style=\"color: #b2dfee;\">getPassword<\/span>()<span style=\"color: #00ffff;\">{<\/span> <span style=\"color: #ffa500;\">return<\/span> passwd; <span style=\"color: #00ffff;\">}<\/span>\r\n<span style=\"color: #ffffcc;\">  36:<\/span>    <span style=\"color: #ffa500;\">public<\/span> <span style=\"color: #cc6600;\">boolean<\/span> <span style=\"color: #b2dfee;\">promptYesNo<\/span>(String str)<span style=\"color: #00ffff;\">{<\/span><span style=\"color: #ffa500;\">return<\/span> <span style=\"color: #ffff66;\">true<\/span>;<span style=\"color: #00ffff;\">}<\/span>\r\n<span style=\"color: #ffffcc;\">  37:<\/span>    <span style=\"color: #ffa500;\">public<\/span> String <span style=\"color: #b2dfee;\">getPassphrase<\/span>()<span style=\"color: #00ffff;\">{<\/span> <span style=\"color: #ffa500;\">return<\/span> <span style=\"color: #ffff66;\">null<\/span>; <span style=\"color: #00ffff;\">}<\/span>\r\n<span style=\"color: #ffffcc;\">  38:<\/span>    <span style=\"color: #ffa500;\">public<\/span> <span style=\"color: #cc6600;\">boolean<\/span> <span style=\"color: #b2dfee;\">promptPassphrase<\/span>(String message)<span style=\"color: #00ffff;\">{<\/span><span style=\"color: #ffa500;\">return<\/span> <span style=\"color: #ffff66;\">true<\/span>; <span style=\"color: #00ffff;\">}<\/span>\r\n<span style=\"color: #ffffcc;\">  39:<\/span>    <span style=\"color: #ffa500;\">public<\/span> <span style=\"color: #cc6600;\">boolean<\/span> <span style=\"color: #b2dfee;\">promptPassword<\/span>(String message)<span style=\"color: #00ffff;\">{<\/span><span style=\"color: #ffa500;\">return<\/span> <span style=\"color: #ffff66;\">true<\/span>;<span style=\"color: #00ffff;\">}<\/span>\r\n<span style=\"color: #00cd00;\">  40:<\/span>    <span style=\"color: #ffa500;\">public<\/span> <span style=\"color: #cc6600;\">void<\/span> <span style=\"color: #b2dfee;\">showMessage<\/span>(String message)<span style=\"color: #00ffff;\">{<\/span><span style=\"color: #00ffff;\">}<\/span>\r\n<span style=\"color: #ffffcc;\">  41:<\/span>  <span style=\"color: #00ffff;\">}<\/span>     \r\n<span style=\"color: #ffffcc;\">  42:<\/span><span style=\"color: #00ffff;\">}<\/span> <\/span><\/pre>\n<\/div>\n<p>Let&#8217;s focus on the &#8220;go&#8221; method. On line <strong>22<\/strong> we instantiate a Jsch object, which is the core of the library. We then use it as a factory to get a Session (line <strong>23<\/strong>), to which we pass the user name, the host address and the port. In our case, the host is the firewall and the port is 22 (ssh).<br \/>\nOn line <strong>24<\/strong> we set the password for the user on the firewall. Let&#8217;s ignore for the moment lines <strong>25<\/strong> and <strong>26<\/strong> (we&#8217;ll talk about them in a minute).<br \/>\nOn line <strong>27<\/strong> we connect to the remote host(the firewall), but the &#8220;magic&#8221; is on line <strong>28<\/strong>. What we make with the method &#8220;setPortForwardingL&#8221; is telling our open session that any data sent to port &#8220;tunnelLocalPort&#8221; of our machine (localhost, to be clear) should be forwarded to port &#8220;tunnelRemotePort&#8221; of the machine with address &#8220;tunnelRemoteHost&#8221; located behind the firewall, and viceversa. This way, with the values used in the code above (remember to substitute the IP addresses and the tcp ports to match your situation), if on my browser I write &#8220;http:\/\/127.0.0.1:9080&#8221; , I&#8217;ll see the home page of the webserver active on port 80 of the machine with IP address YYY.YYY.YYY.YYY located behind the firewall.<\/p>\n<p>Now the lines we left behind (<strong>25<\/strong> and <strong>26<\/strong>). These refer to the inner class defined in our code, &#8220;localUserInfo&#8221;. It implements UserInfo, and works as an utility used for authenticating on the proxy machine (the firewall in our case). The interesting overridden methods are:<\/p>\n<ol>\n<li><strong>promptPassword<\/strong> &#8211; here we can put code needed to input a password. In our case we&#8217;ve already set the password with &#8220;session.setPassword&#8221;, otherwise we should have set it here. In graphical applications we could have shown a dialog with a text field, in a console application we could have prompted it on the standard input.<\/li>\n<li><strong>showMessage<\/strong> &#8211; This will be called by jsch whenever something happens during connection\/authentication. It&#8217;s a developer&#8217;s task the showing of the passed message, thru a simple System.out.println,a dialog box or whatever.<\/li>\n<li><strong>promptYesNo<\/strong> &#8211; this is called by Jsch, with a message attached if confirmation of something is needed (tipically acceptance of connection to an unknown host). Here we return true (otherwise the connection is rejected, but again, you could implement a yes\/no dialog box to ask for confirmation).<\/li>\n<\/ol>\n<p>This said, line <strong>25<\/strong> instantiates our inner class, while line <strong>26<\/strong> makes our session use the created instance of &#8220;localUserInfo&#8221; to manage the authentication process.<\/p>\n<p>We&#8217;ve just seen the simplest possible scenario, but using Jsch it is possible to do some really interesting things. For example, I use it to locally mount filesystems located behind a firewall. It&#8217;s not difficult:<\/p>\n<ol>\n<li>Make a local forwarding of your 2022(any free port will be just fine) to port 22 of your protected resource<\/li>\n<li>Do a <em>shfsmount<\/em> of it using as host 127.0.0.1 and port 2022<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Overview Some people are using my Tunnel4J, an easy graphical utility that allows connecting to remote ssh servers and mapping local and remote ports for tunneling. Tunnel4J is based on Jcraft&#8217;s Jsch, an excellent 100% java library for ssh. As I recently received multiple requests about how to do ssh tunneling in java, I&#8217;ve decided ..<\/p>\n<div class=\"clear-fix\"><\/div>\n<p><a href=\"http:\/\/symbioticindia.in\/docu\/2016\/05\/06\/java-ssh-tunneling-with-jsch\/\" title=\"read more...\">Read more<\/a><\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,8],"tags":[],"class_list":["post-38","post","type-post","status-publish","format-standard","hentry","category-java","category-ssh"],"_links":{"self":[{"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/posts\/38","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/comments?post=38"}],"version-history":[{"count":1,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/posts\/38\/revisions"}],"predecessor-version":[{"id":39,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/posts\/38\/revisions\/39"}],"wp:attachment":[{"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/media?parent=38"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/categories?post=38"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/tags?post=38"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}