Java SSH connection - java

How can I connect to internet server from Java desktop application? I need to access MySQL database and upload/download files. The host that I have (one.com), don't support remote database access, so I've tried with SSH. I don't know anything at all about this. I've tried various codes examples but none of them pass further than connection. I add jsch.jar to my project. Is there something else that I have to add/install or what em I missing?
public static void main(String args[])
{
String user = "user";
String password = "pass";
String host = "00.000.00.000";
int port=22;
String remoteFile="/home/mywebsite.com/test.txt";
try
{
JSch jsch = new JSch();
Session session = (Session) jsch.getSession(user, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
System.out.println("Establishing Connection...");
session.connect();
System.out.println("Connection established.");
System.out.println("Creating SFTP Channel.");
ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
sftpChannel.connect();
System.out.println("SFTP Channel created.");
InputStream out= null;
out= sftpChannel.get(remoteFile);
try (BufferedReader br = new BufferedReader(new InputStreamReader(out))) {
String line;
while ((line = br.readLine()) != null)
System.out.println(line);
}
}
catch(JSchException | SftpException | IOException e){System.err.print(e);}
}
I get the error:
com.jcraft.jsch.JSchException: java.net.ConnectException: Connection timed out: connect
BUILD SUCCESSFUL (total time: 24 seconds)
Or what other alternatives I have to achieve a remote connection to my site & database?
P.S. I have tried almost all the example-codes from stackoverflow and all get stuck in the same point ...
Thank you!

Connection timed out indicates that you're trying to connect to a server that isn't accepting SSH connections on port 22, or your host is incorrect. Is host = "00.000.00.000"; the actual IP address you're trying to connect to, or did you change it for your Stack Overflow question?

I'm not going to debug your code, but will tell you how to accomplish this.
The solution is to use SSH "port forwarding", which you should first set up from the command line, to learn how it works, before embedding it in your Java code. You may not need to write any code if a command-line tunnel will suffice.
ssh -L3306:localhost:3306 <databaseHost>
This creates an SSH "tunnel" from your computer's port 3306 to the <databaseHost> and then on to localhost from <databaseHost>. Any connection on your computer to your local port 3306 gets tunnelled across SSH to <databaseHost> and then on to whatever <databaseHost> knows as localHost, i.e. back to itself, on port 3306.
When your Java code connects to the database, it should connect to localhost:3306. Note that the localhost in your database connect string refers to your computer, while the one in the ssh command is from the point of view of the remote server, so they mean different things.
In summary, a packet from your Java code to the remote MySQL server travels the following route:
Connect to my computer port 3306
Intercepted by ssh
Encrypted and transmitted to remote database server
Decrypted by sshd and fed to port 3306 on the same server
Received by MySQL running on the remote host
For return packets, this process is reversed, managed by the local ssh client and the remote sshd daemon.
Note that this can be used for more interesting cases. For example, suppose the remote ssh server and database server are on different systems behind the same firewall. Let's say the ssh host is visible as gateway.xyz.com, while the database host is on an internal LAN at 10.0.0.3 which is not reachable from the Internet, but reachable from the gateway.
ssh -L3306:10.0.0.3:3306 gateway.xyz.com
The packet route is then
Your computer 3306
Received by ssh
Encryption and sent to gateway.xyz.com
Decrypted by sshd forwarded to 10.0.0.3:3306
Received at 10.0.0.3:3306 by MySQL
To be clear, this is something you set up from the command line, before executing your Java code, which should happen in a different session from the ssh command. The tunnel remains available as long as the ssh command is running.

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?

JSch multiple tunnels/jumphosts

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

How to connect to an FTP server from an existing connection to Unix server?

Currently I am using Reflection for Unix and OpenVMS. I connect to a Unix server. Once connected, I establish a new FTP connection to the target server. Here is how the console window look like:
login: xxx
Password : xxx
// Now I'm connected to UNIX
// Next I am connecting to that FTP
ftpLogin#hostName :/whatever/.../ $ ftp someftp.example.com
Conencted
Name: myLogin
Password:
XXX
Login OK
I tried to replicate the same steps programmatically, but got confused with this "double connection" thing. I was able to connect to Unix only, but then I don't know how to proceed.
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
System.out.println("Establishing Connection...");
session.connect();
Now that I am connected to Unix, how do I proceed with this step ftpLogin#hostName :/whatever/.../ $ ftp someftp.example.com?
I think I might only need to send a command, something like
sftpChannel.setCommand("ftpLogin#hostName :/whatever/.../ $ ftp someftp.example.com ?")
How can I connect to a separate FTP from an existing "session/connection"?
You typically use the local port forwarding for this.
In JSch, after you connect, call the setPortForwardingL:
int ftpPort = session.setPortForwardingL(0, "someftp.example.com", 21);
And then connect a local FTP client (e.g. the FTPClient from Apache Commons) to the localhost:ftpPort:
FTPClient ftp = new FTPClient();
ftp.connect("localhost", ftpPort);
ftp.login("myLogin", password);

Java: SSH tunneling - set local SOCKS as the listener

What I want to do is to set up a SOCKS server and then add its port as the local listening port in an SSH tunnel connection. What I want to achieve is dynamic port forwarding (the -D option in ssh, if I remember correctly). I'm using JSch for SSH tunneling. Here's the code that I have so far (copied from http://kahimyang.info/kauswagan/code-blogs/1337/ssh-tunneling-with-java-a-database-connection-example):
int assigned_port;
int local_port=<local listening port goes here>;
// Remote host and port
int remote_port=<remote port goes here>;
String remote_host = "<SSH host goes here>";
String login = "<SSH login goes here>";
String password = "<SSH password goes here>";
try {
JSch jsch = new JSch();
// Create SSH session. Port 22 is your SSH port which
// is open in your firewall setup.
Session session = jsch.getSession(login, remote_host, 22);
session.setPassword(password);
// Additional SSH options. See your ssh_config manual for
// more options. Set options according to your requirements.
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
config.put("Compression", "yes");
config.put("ConnectionAttempts","2");
session.setConfig(config);
// Connect
session.connect();
// Create the tunnel through port forwarding.
// This is basically instructing jsch session to send
// data received from local_port in the local machine to
// remote_port of the remote_host
// assigned_port is the port assigned by jsch for use,
// it may not always be the same as
// local_port.
assigned_port = session.setPortForwardingL(local_port,
remote_host, remote_port);
} catch (JSchException e) {
System.out.println("JSch:" + e.getMessage());
return;
}
if (assigned_port == 0) {
System.out.println("Port forwarding failed!");
return;
}
However, If I start up a local SOCKS proxy on my client machine, JSch cannot use its port as a local listening port saying that it cannot be bound. I gather that is because the port is occupied by the SOCKS server (which is pretty obvious, huh). The question is, what is the correct way to do dynamic port forwarding with JSch?
If the SOCKS proxy were running on the remote server, you could make an SSH tunnel from a port on the local server to the SOCKS proxy port on the remote server. Once you set that up, your SOCKS-capable client could use the local tunnel port as if it were the SOCKS proxy.
The OpenSSH ssh program and the windows Putty utility have built-in SOCKS proxy capability. You could just use one of them.
Here's the description of -D:
Specifies a local "dynamic" application-level port forwarding.
This works by allocating a socket to listen to port on the local
side, optionally bound to the specified bind_address. Whenever a
connection is made to this port, the connection is forwarded over
the secure channel, and the application protocol is then used to
determine where to connect to from the remote machine. Currently
the SOCKS4 and SOCKS5 protocols are supported, and ssh will act
as a SOCKS server. Only root can forward privileged ports.
Dynamic port forwardings can also be specified in the configura-
tion file.
#Kenster's right about what ssh does, but I think what you want isn't to run a SOCKS proxy remotely, but to implement a Java SOCKS proxy server server in jsch (then contribute it back to jsch).

Categories

Resources