Connecting to Mongo database through SSH tunnel in Java

David V picture David V · Jul 1, 2015 · Viewed 7.7k times · Source

FIXED (edited code to reflect changes I made)

I'm trying to connect to a Mongo database through an SSH tunnel using Java.

I'm using the Mongo driver 3.0.2 and jcraft (JSch) to create an SSH tunnel. The idea is that I:

  • connect to the machine hosting the MongoDB installation through SSH
  • set up port forwarding from a local port to the remote MongoDB port
  • connect to MongoDB remotely

My code looks like this:

// forwarding ports
private static final String LOCAL_HOST = "localhost";
private static final String REMOTE_HOST = "127.0.0.1";
private static final Integer LOCAL_PORT = 8988;
private static final Integer REMOTE_PORT = 27017; // Default mongodb port

// ssh connection info
private static final String SSH_USER = "<username>";
private static final String SSH_PASSWORD = "<password>";
private static final String SSH_HOST = "<remote host>";
private static final Integer SSH_PORT = 22;

private static Session SSH_SESSION;

public static void main(String[] args) {
try {
    java.util.Properties config = new java.util.Properties();
    config.put("StrictHostKeyChecking", "no");
    JSch jsch = new JSch();
    SSH_SESSION = null;
    SSH_SESSION = jsch.getSession(SSH_USER, SSH_HOST, SSH_PORT);
    SSH_SESSION.setPassword(SSH_PASSWORD);
    SSH_SESSION.setConfig(config);
    SSH_SESSION.connect();
    SSH_SESSION.setPortForwardingL(LOCAL_PORT, REMOTE_HOST, REMOTE_PORT);

    MongoClient mongoClient = new MongoClient(LOCAL_HOST, LOCAL_PORT);
    mongoClient.setReadPreference(ReadPreference.nearest());
    MongoCursor<String> dbNames = mongoClient.listDatabaseNames().iterator();
    while (dbNames.hasNext()) {
    System.out.println(dbNames.next());
    }
} catch (Exception e) {
    e.printStackTrace();
} finally {
    SSH_SESSION.delPortForwardingL(LOCAL_PORT);
    SSH_SESSION.disconnect();
}
}

This code, when run, doesn't EDIT: does work. Connecting to the SSH server works just fine, but connecting to the Mongo database behind it doesn't work and returns this error:

INFO: Exception in monitor thread while connecting to server localhost:8988
com.mongodb.MongoSocketReadException: Prematurely reached end of stream
    at com.mongodb.connection.SocketStream.read(SocketStream.java:88)
    at com.mongodb.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:491)
    at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:221)
    at com.mongodb.connection.CommandHelper.receiveReply(CommandHelper.java:134)
    at com.mongodb.connection.CommandHelper.receiveCommandResult(CommandHelper.java:121)
    at com.mongodb.connection.CommandHelper.executeCommand(CommandHelper.java:32)
    at com.mongodb.connection.InternalStreamConnectionInitializer.initializeConnectionDescription(InternalStreamConnectionInitializer.java:83)
    at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:43)
    at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115)
    at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:127)
    at java.lang.Thread.run(Unknown Source)

I've tried doing this through command line as follows:

$ ssh <user>@<host> -p 22 -X -C
$ <enter requested password>
<user>@<host>$ mongo
<user>@<host>$ MongoDB shell version: 2.6.10
<user>@<host>$ connecting to: test

So this seems to work. I'm at a loss as to why the Java code (which should be doing roughly the same thing) doesn't work.

Answer

mcolak picture mcolak · Jan 28, 2021

This code is run successfully, but the main problem is your mongo db is stopped. Please check the instance of the mongo is running or not.

sudo systemctl status mongod

if it is not running

sudo systemctl start mongod