Creating a SSH Tunnel in Java

tl;dr

How to create a SSH tunnel in a Java app from a localhost port through a jump box to a specific port on a server. Allowing a connection to the remote server port as if it was a localhost port.

Examples found online provided only one ‘hop’, not the double ‘hop’ needed. The code below supports 2 hops, but in theory could be used to support any number of hops.

The Why

A jump box (or bastion host) is a common security setup for servers. It requires users to first SSH to the jump box and then SSH to the remote server. It means the remote server can limit what ports are open to the internet and user access control can be managed on the jump box.

This is security setup is often seen on cloud hosting providers like Amazon Web Services EC2 (AWS) or Microsoft Azure.

Details

In this example, there is a webapp on port 8080 on the remote server that we want to make available on localhost 8080. Specifically, this is the Apache Tomcat Manager webapp on the remote server, normally not available to the Internet for security reasons (e.g. blocked by forwarding rules or proxy settings).

Another example might be to map 3306 from localhost to a remote MySQL database. This would allow connection to the remove database over the localhost 3306 port. For that scenario, simply replace 8080 with 3306.

Command Line SSH

Using SSH to chain the connections together to create a tunnel using command line parameters looks like this:

In this example localhost 8080 is connected to JUMP_BOX 8080 which is then connected to REMOTE_SERVER 8080.

It is also possible to use keys so that there are no password prompts:

NOTE: The INTERNAL_SERVER_KEY_FILE.pem needs to be the key file (and prepended path) on the JUMP_BOX server

Using the command line will work for many solutions, but is not ideal if you are trying to automate steps as part of an application.

Jcraft Jsch

The code below uses the JSch library, to make the ssh connections. I would like to the thank the authors of Jsch for their work and making it available and updated.

The Jsch project does have some examples available, but as mentioned, I didn’t find a jump box example.

Java SSH

The code below is part of an example application to automate deployments implemented in Java. It is procedural proof of concept and could be refactored into more reusable, modular classes.

It should be noted that there are other tools available for deployments, such as Jenkins, that maybe a better fit for some use cases.

The values set between BEGIN required customization and END required customization will need to be customized to match your settings.

The code is available on Github as a full maven project:

https://github.com/gordonturner/reference-cli-java-ssh-tunnel-tomcat

Conclusion

This example should be used as a starting point for any command line or server side ssh connections that need to use a jump box or bastion host and other ports can be easily substituted for port 8080.

Comments are closed.