3SP Knowledgebase
Information and FAQs about 3SP products
  
Search  
   
Browse by Category
3SP Knowledgebase .: Developers .: J2SSH Maverick .: Tutorials .: SSH Connection via HTTP Proxy Server

SSH Connection via HTTP Proxy Server

Pre-Requisite
J2SSH Maverick API
Target Host running SSH Server
Apache WebServer

Resources
OpenSSH Free open source SSH server http://www.openssh.com/
HTTP Proxy Server - Opensource HTTP Server http://httpd.apache.org/

What It Does
This tutorial demonstrates how simple it is to connect to an Ssh Server that is sitting behind a HTTP Proxy Server. A proxy server acts as an intermediary between client and server helping users on a private network get information when they need it but in addition performing secure functions as network address translation, mapping internal network addresses to a single "safe" IP address all in an attempt to keep an internal network safe. Because Proxy Servers operate at the Application layer of the OSI model, proxy servers can do a lot more than just service client requests, all in attempt to minimise illegal traffic. To delve any further into this topic is beyond the scope of this article, this article uses Apache HTTP Server as its Proxy Server further information on the HTTP Apache Server can be found in the Resource section of this article.
In this example the HTTP request will proxy data sent by our Ssh Client to its intended target, the Ssh Server, which is placed behind the our Proxy Server.

How It Works
Setting Up Apache
Apache must already be up and running as a Web Server. If it is not then it is simply a matter of installing and running the application, please refer to the Apache website as directed from the Resource section of this article. In order for Apache Web Server to become a fully working forwarding pode> cipher.

Connect to Host
Now we are ready to connect to our Ssh Server. Under normal direct client server connections we utilise the con.connect(new SocketTransport(hostname, 22), username) method. Maverick has been designed to operate over a transport interface called SshTransport which at its simplist requires just a pair of IO streams. This enables Maverick to operate over any type of current or future communication medium supported by the Java runtime. W supply the hostname of the computer we wish to connect to and the port number to the SocketTransport constructor, which in our case is the default SSH port number 22. The second parameter identifies the username for the connection. However for our connection we are connecting through our HTTP Proxy Server and for this we must use the HttpProxyTransport class. This class provides an SshTransport implementation that can route the connection through our HTTP proxy. To connect the transport we simply call the HttpProxyTransport::connectViaProxy(String, int, String, int, String, String, String), username) method.

            /**
             * Connect to the host
             */

            ssh = (Ssh2Client)con.connect(HttpProxyTransport.connectViaProxy(hostname, 22,
                    proxyHostname, proxyPort, proxyUsername, proxyPassword, "J2SSH Maverick"), username);

As you can see this implementation requires a few more additional parameters in particular the HTTP Proxy credentials and a User Agent value, "J2SSH Maverick" that identifies the connecting application to the HTTP Server. This can be left as an empty string if need be as it does not affect the workings of class.

When this is executed the SshConnector will try and establish a connection to the SshServer. Once a connection has been established the method returns an instance of the SshClient interface. This interface provides a protocol independent contract for an SSH client allowing applications to support both versions of the SSH protocol without the need for seperate client libraries. When the client connects to the server, the server supplies its public key for the client to verify. Since we informed the SshConnector to use our PasswordHostKey implementation all we should see is the host key finger print.

Authenticate User
We now have a connection to the SSH server the next task is to authenticate the Ssh user we identified earlier in our connect method, HttpProxyTransport.connectViaProxy(..., username). We will not be able to perform any other operation until the user has been authenticated. Password authentication is ideal for first time users as it requires no additional configuration within the SSH client or server. The user simply supplies his username and password to the client which is then transmitted over the encrypted connection to the server. The server then checks that the given password is acceptable to the native password-authentication mechanism of the host operating system and returns the result to the client.

            /**
             * Authenticate the user using password authentication
             */

            Ssh2PasswordAuthentication passwordAuthentication = new Ssh2PasswordAuthentication();

            System.out.print("Password: ");
            passwordAuthentication.setPassword(reader.readLine());

            if(ssh.authenticate(passwordAuthentication)!=SshAuthentication.COMPLETE) {

                System.out.println("Authentication failed!");
                System.exit(0);
            }

If authentication fails, !=SshAuthentication.COMPLETE then we end immediately. If however we succeed then we are finally able to start using our Ssh2Client object. This instance is returned to the main calling class.

And that's all there is to it!

The purpose of this article, to establish an Ssh Connection through a HTTP Proxy Server, has been accomplish. The rest of the article returns back to the main calling method which proceeds to use the configured Ssh2Client instance to establish a Terminal Session with the remote server.

Requesting a Pseudo Terminal
After a session has been established between our SSH client and server our next task is to configure a pseudo terminal. A pseudo terminal is a device that imitates a terminal. Rather than being connected to an actual terminal, a pseudo-terminal or pty is connected to a process. This will allow us to gain visual representation of the remotely opened shell.

            if(ssh.isAuthenticated()) {
                final ForwardingClient fwd = new ForwardingClient(ssh);
                final SshSession session = ssh.openSessionChannel();
                
                // create a terminal to allow communication with remote shell
                session.requestPseudoTerminal("vt100", 80, 24, 0, 0);

As you can see the above block of code and the remaining is all maintained within a secure 'if' block, only successfully Authenticated connections are allowed to continue. A psuedoTerminal can only be retrieved through an SshClient session object and as above we open a new session instance through our successful connection 'SshClient' object, calling the 'openSessionChannel' method.

Opening a Shell
We now must start up a shell to interact with the remote shell on the SSH Server.

                session.startShell();

Displaying Status Information
Maverick allows us to query various details regarding our Ssh session here we simply demonstrate this by requesting status information on firstly the SshClient, whether it is connected to the server still. Secondly whether the authentication on the client succeeded or not, next if the connection to the SSH server is still alive and finally we display a selection of information detailing the algorithms utilised in our active session.

                System.out.println("SshClient connected["+ssh.isConnected()+"]");
                System.out.println("SshClient authenticated["+ssh.isAuthenticated()+"]");
                System.out.println("SshSession closed["+session.isClosed()+"]");
                System.out.println("Cipher[client->server]:"
                   +((Ssh2Context)con.getContext(SshConnector.SSH2)).getPreferredCipherCS());
                System.out.println("Cipher[cleint<-server]:"+
                    ((Ssh2Context)con.getContext(SshConnector.SSH2)).getPreferredCipherSC());
                System.out.println("Public Key Algorithm:"+
                    ((Ssh2Context)con.getContext(SshConnector.SSH2)).getPreferredPublicKey());
                System.out.println("Key Exchange Algorithm:"+
                    ((Ssh2Context)con.getContext(SshConnector.SSH2)).getPreferredKeyExchange());

Handling Output Session Data
Our session has been configured all we intend to do is establish IO interaction with our shell. Firstly we establish a means of retrieving the shells response to our requests,

                // use the input stream from the session to read the reply form the shell
                final InputStream in = session.getInputStream();
                Terminal terminal = new Terminal(in);
                terminal.start();

We retrieve the sessions InputStream and pass that to the Terminal class, If you take a look at the Terminal class you can see this is a simple thread that iterates through the InputStream we supplied, simply printing out the characters received from the remote shell.

Handling Input Session Data
Now that we can see what the shell is returning we need someway of replying to and writing commands to it. This is achieved through the current sessions OutputStream.

                while((read = System.in.read()) > -1) {
                    session.getOutputStream().write(read);
                }

We simply loop around writing the content of the System read buffer and writing it out to the sessions output stream.

Execute The Code
Once this code is executed the session is established and we are able to execute commands on the remote machine, instead of a direct Ssh connection to the host our secure channel is directed through our Apache HTTP Proxy Server.

Communication
Even with a HTTP proxy server in place to help a company's security we are still able to connect to our company's internal Ssh server resource. But with the transmissions going over Ssh we do not put the integrity of the corporate network at risk and nor does the inclusion of proxying systems interfere with our accessing of company resources. In affect a secure Ssh channel works hand in hand with security systems as proxy servers. The communication is secured right across the route from client through to server with the added security of a Proxy Server in between.

How To Run This Code
This attached zip file contains several source files. Unzip these into a new Java project and build.

2005 3SP Ltd, All Rights Reserved


How helpful was this article to you?

User Comments

Add Comment
Comment nyari duit di internet <rayearth26@plasa.com>
6th February, 2008 at 18:17

nice tutor
thank for this great articles


powered by Lore
© 2008 3SP Ltd. All Rights Reserved