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?
JSch - Examples. Shell.java. demonstrating how to connect to sshd server and get the shell prompt. Exec.java. demonstrating the remote exec. ViaHTTP.java. demonstrating the ssh session via HTTP proxy. ViaSOCKS.java. demonstrating the ssh session via SOCKS proxy.
What you will have to do is establish a local port forward to the ssh port on the machine you're tunneling to, then establish a secondary ssh connection to this system using the api. I've taken your example and slightly rewritten it to accomplish this:
a SOCKS proxy setting on jsch allows you to connect to a running proxy server on the remote side. An sshd on the remote side would not be considered a SOCKS proxy.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With