Remote port forwarding using jsch? - java

I am using the library jsch to make ssh connection. I am useing following code;
JSch jsch = new JSch();
Session session = jsch.getSession("username", "host", port);
But how to put some specific option while I am creating the connection? Actually I want to replicate;
ssh -R abc:8080:localhost80 mysite.com
This command using jsch.
Is it possible using jsch? Or I should use some other library.
Any suggestion will be very helpful.
Thanks in advance.

Is it more options than port forwarding that you need?
Port forwarding (as in -R) is possible with JSch - example here.
If the objective is emulating the OpenSSH command line options, this would be tougher. To the best of my knowledge, all the various SSH libraries for Java, JSch included, focus on providing connectivity for applications that need SSH support. That sounds like it would need a small project in command line parsing.

Related

Jump to Different server from Bastion using Java JSch [duplicate]

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?
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?

Java program to get a file on SFTP server using public key authentication and proxy server

In our project, we need to get a file from external SFTP server using public key authentication. I have searched online but didn't any example for mentioning proxy server routing since it's required as per company's policy
We are using the following command on Unix server to get the file but we want to use java program to implement this functionality
sftp -v -oIdentityFile=/home/intusr/.ssh/id_rsa -oProxyCommand="/usr/bin/corkscrew 11.555.66.22 4444 %h %p" user#transmit.com:stage/filedir/
Your help will be appreciated. Best resource I have found so far is
https://kodehelp.com/java-program-for-uploading-file-to-sftp-server/
The most commonly used Java SSH library is JSch, which supports both public key authentication and HTTP proxy:
How to transfer a file using a proxy with JSch library
Can we use JSch for SSH key-based communication?
Combined, the code would be like:
JSch jsch = new JSch();
jsch.addIdentity("/path/to/private/key");
Session session = jsch.getSession("user", "host");
ProxyHTTP proxy = new ProxyHTTP("proxy", proxyport)
proxy.setUserPasswd("proxyusername", "proxypassword");
session.setProxy(proxy);
session.connect();
For downloading a file, see:
How to retrieve a file from a server via SFTP?
You will have to verify server host key as well.

Opening ChannelSftp channel to transfer the file after using sudo [duplicate]

I am using JSch in a Java client to connect to a remote server and get some files using SFTP. The following code has been working fine for me: -
JSch ssh = new JSch();
JSch.setConfig(FileTransferConstants.STRICT_HOST_KEY_CHECKING, FileTransferConstants.NO);
Session session = ssh.getSession(userName, host, port);
session.setPassword(password);
session.connect();
Channel channel = session.openChannel(FileTransferConstants.SFTP);
channel.connect();
ChannelSftp sftp = (ChannelSftp) channel;
sftp.cd(remoteDirectoryPath);
sftp.lcd(localDirectoryPath);
sftp.get(remoteDirectoryPath + remoteFileName, remoteFileName);
The problem is that there has now been a change of site policy. I am no longer permitted to log on directly as this user (userName above). I must first log on as my personal user and then su into the user that has access to the files I want to SFTP.
I don't think there is anyway I can refactor the above code to achieve this and so I have started looking at using a shell or exec channel instead. I have had little success so far and cannot seem to find any examples on the web, so I would be very grateful for any advice or pointers in the right direction. Many thanks.
I do not think you can do this directly with JSch. But with some modification of its code, it's probably doable.
Note that my answer assumes that the server is *nix-based (what is backed by your reference to su) and uses OpenSSH SFTP server.
You have to open SSH "exec" channel, to execute something like:
sudo /bin/sftp-server
But on top of that channel, you need to build the ChannelSftp instance, not ChannelExec.
So you will need to implement Session.openChannel-like method, that will open exec channel, but create ChannelSftp for it.
For some background, see how it's possible to do sudo with WinSCP SFTP client.
Note that while the FAQ claims, that you won't be able to use password for the sudo, that's true for WinSCP. But as you have a full control of the session with JSch, you may be able to feed the password to sudo.
For that you might override the ChannelSftp.start() to write the password to the channel input, before starting the actual SFTP session.
You still need the requiretty option be off, as the SFTP cannot work with TTY.
For general considerations when automating operations using a different/root account, see:
Allowing automatic command execution as root on Linux using SSH

JSch - Port forwarding using multiple Jumphosts [duplicate]

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?
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?

JSch scp without known_host file and with StrictHostKeyChecking

I am trying to copy some files from a Windows machine to a Linux machine, which is working fine with JSch so far. I can copy files using StrictHostKeyChecking no or I need to have the known_host file from the Linux machine I copy to. I am using the code for a Java project which should be able to send files automatically to (unknown) Linux machines. I got the username, password, IP and the publickey for the machine. Is there any way to authenticate without the known_host file and via the publickey? Because of security issues I do not want to switch StrictHostKeyChecking to no but then I get "com.jcraft.jsch.JSchException: UnknownHostKey"
FileInputStream fis = null;
JSch jsch = new JSch();
//jsch.setKnownHosts("");
jsch.addIdentity("D:\\Uni\\Arbeit\\remote_id_rsa");
Session session=jsch.getSession(user, host, 22);
session.setPassword(password);
//session.setConfig("StrictHostKeyChecking", "no");
session.connect();
That does not make sense. Either you know the host public key and you can verify it either using the known_host file or programmatically using:
public void KnownHosts.add(HostKey hostkey, UserInfo userinfo)
(You can access the instance of KnownHosts using Session.getHostKeyRepository())
For more details, see How to resolve Java UnknownHostKey, while using JSch SFTP library?
Or you do not know the host public key, and then you cannot create a secure connection (and the StrictHostKeyChecking=no is your only option).
See my article about verifying the host key to understand, what is it about, and its importance. The article is about WinSCP client, but it's valid in general for any SSH client.

Categories

Resources