Reputation: 25261
I'm not sure if this is caused by using a private key instead of password for the port forwarding but here's what I'm trying to do
I need to forward local port 3308 all the way to the my SQL DB at 3306.
I can run things like this all together in terminal on my local
ssh -L 3308:localhost:3307 username@jumpbox "ssh -L 3307:mysqlDB:3306 username@server"
Or run the first part on my local and then the second part on the jumpbox. Both works fine and I can connect to my localhost:3308.
The problem comes when I start using JSch. Here is my code
JSch jsch = new JSch();
jsch.addIdentity("~/.ssh/id_rsa");
Session session = jsch.getSession("username", "jumpbox");
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
int assinged_port = session.setPortForwardingL(3308, "localhost", 3307);
Session mysqlSession = jsch.getSession("username", "server", assinged_port);
mysqlSession.setConfig("StrictHostKeyChecking", "no");
mysqlSession.connect(); // Connection timed out here
mysqlSession.setPortForwardingL(3307, "mysqlDB", 3306);
The first connection is done but the second one timed out.
Exception in thread "main" com.jcraft.jsch.JSchException: java.net.ConnectException: Operation timed out (Connection timed out)
Am I doing something wrong here with JSch or port forwarding?
Upvotes: 7
Views: 3319
Reputation: 202088
Your ssh
command is making use of an SSH client (another ssh
) running on "jump box".
When you want to implement the same using Java, you have two options:
Do the same in Java, i.e. use session
to run ssh -L 3307:mysqlDB:3306 username@server
on the "jump box".
See Executing a command using JSch.
Though, I do not think you should rely on ssh
program for the second jump, for the same reason you use Java/JSch for the first jump (and not ssh
program).
Avoid using a separate ssh
tool, and instead open the other SSH session locally via yet another forwarded port. You can actually do the same using recent versions of ssh
, with -J
(jump) switch (supported since OpenSSH 7.3):
ssh -L 3308:mysqlDB:3306 -J username@jumpbox username@server
See also Does OpenSSH support multihop login?
I prefer this approach.
To implement the latter approach:
You have to forward some local port to server:22
, so that you can open SSH connection to the server
:
JSch jsch = new JSch();
jsch.addIdentity("~/.ssh/id_rsa");
Session jumpboxSession = jsch.getSession("username", "jumpbox");
jumpboxSession.connect();
int serverSshPort = jumpboxSession.setPortForwardingL(0, "server", 22);
Session serverSession = jsch.getSession("username", "localhost", serverSshPort);
serverSession.connect();
Then you forward another local port via server
to MySQL port:
int mysqlPort = serverSession.setPortForwardingL(0, "mysqlDB", 3306);
Now you should be able to connect to localhost:mysqlPort
using MySQL client.
Obligatory warning: Do not use StrictHostKeyChecking=no
to blindly accept all host keys. That is a security flaw. You lose a protection against MITM attacks.
For a correct (and secure) approach, see:
How to resolve Java UnknownHostKey, while using JSch SFTP library?
Upvotes: 6