JDBC over SSH

2008-09-23 by mira

This is a short summary about how to access a database using JDBC through a secure SSH tunnel.

On Unix boxes, the SSH daemon is usually running by default, which makes SSH tunnels a good choice for making secure connections to services running on Unix boxes.

Prerequisites:

  1. Generate SSH keypair:
    $ ssh-keygen -t dsa -f ssh/id_dsa
  2. Add public key to authorized_keys on SSH server machine (user=foo):
    $ cat id_dsa.pub >> ~foo/.ssh/authorized_keys
  3. Get JSch library - Java implementation of SSH2

We use the SSH tunnel to do a local port forwarding. Doing so, all requests to a designated local port on the client machine are forwarded thru the tunnel to the destination port on the remote host. The remote host can be the same as the SSH server, but can also be a different host reachable by the SSH server.

ssh_server: SSH server name or IP
ssh_user: SSH user name

lport: local port on the client machine (example here: 3366)
rhost: remote host running the database
rport: remote port to access the database (3306 for MySQL)

// SSH Tunnel
Session session = null;
try {
  final JSch jsch = new JSch();
  session = jsch.getSession(ssh_user, ssh_server, 22);

  final Hashtable config = new Hashtable();
  config.put("StrictHostKeyChecking", "no");
  session.setConfig(config);
  jsch.addIdentity("ssh/id_dsa");

  session.connect();

  int assigned_port = session.setPortForwardingL(lport, rhost, rport);

} catch (Exception e) {
  e.printStackTrace();
  System.exit(-1);
}    

// DB connection
Connection con = null;
try {
  Class.forName("com.mysql.jdbc.Driver");
  con = DriverManager.getConnection("jdbc:mysql://localhost:3366/db_name", "db_user", "db_pass");

  // access  database

} catch (Exception ex) {
  ex.printStackTrace();
  System.exit(-1);
} finally {
  try {
    if (con != null) con.close();
  } catch (Exception ex) {/* NOP */}
}

session.disconnect();    

Archive

architecture