Search code examples
javaapachesshhttpshttp-tunneling

Reverse Tunnel over JSCH (SSH) and HTTPS


I have to implement a reverse tunnel from client to server. I have used JSCH with the following command

session.setPortForwardingR(rport, lhost, lport);

and it works (see also Reverse SSH tunnel with JSCH Java)!

next I have to tunnel my ssh session over an HTTPS stream 2-way authenticated:

client -> firewall -> apache https -> ssh server 

----------------------> HTTPS
====================================> SSH
---------------------->

I'm looking for

  1. a small piece of java code to encapsulate SSH into HTTPS
  2. 2 way HTTPS authentication
  3. APACHE configuration

possible solution:

1) HTTPS Tunnel

  1. JHTTPTunnel, but it is based on J2ME and it doesn't support SSL (see also Java Http Tunneling , Is there an Java library for sending binary data over HTTP, HTTP Tunneling?)
  2. JOD, but it doesn't support SSL

3) APACHE CONFIGURATION

  1. Maybe this configuration works but I have to try
## Load the required modules.
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so

## Listen on port 8443 (in addition to other ports like 80 or 443)
Listen 8443

<VirtualHost *:8443>

  ServerName youwebserver:8443
  DocumentRoot /some/path/maybe/not/required
  ServerAdmin [email protected]

  ## Only ever allow incoming HTTP CONNECT requests.
  ## Explicitly deny other request types like GET, POST, etc.
  ## This tells Apache to return a 403 Forbidden if this virtual
  ## host receives anything other than an HTTP CONNECT.
  RewriteEngine On
  RewriteCond %{REQUEST_METHOD} !^CONNECT [NC]
  RewriteRule ^/(.*)$ - [F,L]

  ## Setup proxying between youwebserver:8443 and yoursshserver:22

  ProxyRequests On
  ProxyBadHeader Ignore
  ProxyVia Full

  ## IMPORTANT: The AllowCONNECT directive specifies a list
  ## of port numbers to which the proxy CONNECT method may
  ## connect.  For security, only allow CONNECT requests
  ## bound for port 22.
  AllowCONNECT 22

  ## IMPORTANT: By default, deny everyone.  If you don't do this
  ## others will be able to connect to port 22 on any host.
  <Proxy *>
    Order deny,allow
    Deny from all
  </Proxy>

  ## Now, only allow CONNECT requests bound for kolich.com
  ## Should be replaced with yoursshserver.com or the hostname
  ## of whatever SSH server you're trying to connect to.  Note
  ## that ProxyMatch takes a regular expression, so you can do
  ## things like (kolich\.com|anothersshserver\.com) if you want
  ## to allow connections to multiple destinations.
  <ProxyMatch (kolich\.com)>
    Order allow,deny
    Allow from all
  </ProxyMatch>

  ## Logging, always a good idea.
  LogLevel warn
  ErrorLog logs/yourwebserver-proxy_error_log
  CustomLog logs/yourwebserver-proxy_request_log combined

</VirtualHost>

Solution

  • The solution proposed by yourself is ok it is based on Implement HTTPS tunneling with JSSE I think.

    the basic steps are:

    1. define your connection factory for JSCH
    2. open a SSL Socket and call "CONNECT " + host + ":" + port

    on server side catch all request calling the "CONNECT" and enable 22 SSH port.

    But you have also to consider the following issues:

    1. tune the timeout because the SSL handshake is quite long
    2. enable 2-way authentication or all people can connect to 22 of your server: Using client/server certificates for two way authentication SSL socket on Android