First, credit where credit is due. Most of this code came from here (I just modified it a bit):
http://www.miranet.ch/posts/2008/09/23/howto_jdbc_over_ssh/
You’ll also need JSch (a java implementation of SSH):
The major function of SSH tunnels are to secure what would otherwise be an unsecure client/server connection. But another awfully handy use of SSH tunnels are accessing remote resources that are not normally exposed. Databases, for example.
I recently needed to access a MySQL database on a remote server from some local Java code. This database is off on a third party hosting server that does not allow outside access to MySQL, but I can login via SSH.
So, here goes:
import java.sql.Connection; import java.sql.DriverManager; import java.util.Properties; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; public class CTestDriver { private static void doSshTunnel( String strSshUser, String strSshPassword, String strSshHost, int nSshPort, String strRemoteHost, int nLocalPort, int nRemotePort ) throws JSchException { final JSch jsch = new JSch(); Session session = jsch.getSession( strSshUser, strSshHost, 22 ); session.setPassword( strSshPassword ); final Properties config = new Properties(); config.put( "StrictHostKeyChecking", "no" ); session.setConfig( config ); session.connect(); session.setPortForwardingL(nLocalPort, strRemoteHost, nRemotePort); } public static void main(String[] args) { try { String strSshUser = "ssh_user_name"; // SSH loging username String strSshPassword = "abcd1234"; // SSH login password String strSshHost = "your.ssh.hostname.com"; // hostname or ip or SSH server int nSshPort = 22; // remote SSH host port number String strRemoteHost = "your.database.hostname.com"; // hostname or ip of your database server int nLocalPort = 3366; // local port number use to bind SSH tunnel int nRemotePort = 3306; // remote port number of your database String strDbUser = "db_user_name"; // database loging username String strDbPassword = "4321dcba"; // database login password CTestDriver.doSshTunnel(strSshUser, strSshPassword, strSshHost, nSshPort, strRemoteHost, nLocalPort, nRemotePort); Class.forName("com.mysql.jdbc.Driver"); Connection con = DriverManager.getConnection("jdbc:mysql://localhost:"+nLocalPort, strDbUser, strDbPassword); con.close(); } catch( Exception e ) { e.printStackTrace(); } finally { System.exit(0); } } }
So, now I can access the remote database and the traffic is encrypted on top of that!
Same disclaimer as always, this IS NOT production worthy code as is. The exception handling is crap and there’s lots more paranoia to be had. Please follow your own coding best-practices.