Sometimes, we might need to connect to a different machine to execute a few commands or transfer files to it. This article will discuss how to connect to a remote machine/server using Java.
Note: We have also attached a video at the end of this article. In case you are more comfortable with the video version, then please feel free to have a look.
Adding dependencies
We will use the JSch library to connect to the remote server. So, we will add its dependency here –
<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
Now, we will attempt to connect to a remote server. There are typically two methods for doing so –
Let’s see both of them one by one.
Making an SSH connection with Jsch using a password
So, let us see what we need to connect to a remote server. Well, there are only a few things-
- Remote server IP
- Remote server port ( The port on which you want to connect, say, 33000 )
- Username
- Password
Below is the sample code to connect with your server using the password –
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.JSchException;
public class Codekru {
public static void main(String[] args) {
try {
JSch jsch = new JSch();
String username = "codekru"; // your username
String host = "127.0.0.1"; // your remote server address
int port = 33000; // your remote server port
String password = "root"; // your username's password
Session session = jsch.getSession(username, host, port);
session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password");
session.setPassword(password);
session.setTimeout(15000);
session.connect();
} catch (JSchException e) {
e.printStackTrace();
}
}
}
This is how you can establish an SSH connection using a password. Let’s now move on to creating a connection using a key.
Making an SSH connection using key
We will store the private key named “codekru.pem” in the “/Users/codekru/key” directory and use it to establish an SSH connection with the remote server.
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.JSchException;
public class Codekru {
public static void main(String[] args) {
try {
JSch jsch = new JSch();
String user = "codekru"; // your username
String host = "127.0.0.1"; // your remote server address
int port = 33000; // your remote server port
String yourKeyName = "/Users/codekru/key/codekru.pem";
jsch.addIdentity(yourKeyName);
Session session = jsch.getSession(user, host, port);
session.setTimeout(15000);
session.connect();
} catch (JSchException e) {
e.printStackTrace();
}
}
}
You will probably get the below error –
Exception in thread "main" java.lang.RuntimeException: com.jcraft.jsch.JSchException: UnknownHostKey: 127.0.0.1.
This is because SSH isn’t able to validate the identity of the remote server. So, how do we fix it?
Well, there are 2 ways –
- One is to bypass the checking of identity by setting the “StrictHostKeyChecking” value as “no” ( not recommended )
- And second is by using the known_hosts file
Using StrictHostKeyChecking
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.JSchException;
public class Codekru {
public static void main(String[] args) {
try {
JSch jsch = new JSch();
String user = "codekru"; // your username
String host = "127.0.0.1"; // your remote server address
int port = 33000; // your remote server port
String yourKeyName = "/Users/codekru/key/codekru.pem";
jsch.addIdentity(yourKeyName);
Session session = jsch.getSession(user, host, port);
session.setConfig("StrictHostKeyChecking","no");
session.setTimeout(15000);
session.connect();
} catch (JSchException e) {
e.printStackTrace();
}
}
}
Now, we should be able to connect with the server, but this way is not recommended. Because it poses various security concerns and is more prone to man-in-the-middle attacks. So, let’s see the other way now.
Using known_hosts file
Run the below commands in your terminal –
ssh-keyscan -t rsa <Remote_Machine_IP> >> ~/.ssh/known_hosts
This command retrieves the RSA key from the remote machine and appends it to the known_hosts file.
Then, we can tell our program the path of the known_hosts file so that the server’s identity can be validated using the known_hosts file.
jSch.setKnownHosts("/.ssh/known_hosts");
Whole code
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.JSchException;
public class Codekru {
public static void main(String[] args) {
try {
JSch jsch = new JSch();
String user = "codekru"; // your username
String host = "127.0.0.1"; // your remote server address
int port = 33000; // your remote server port
String yourKeyName = "/Users/codekru/key/codekru.pem";
jsch.addIdentity(yourKeyName);
jSch.setKnownHosts("/.ssh/known_hosts");
Session session = jsch.getSession(user, host, port);
session.setTimeout(15000);
session.connect();
} catch (JSchException e) {
e.printStackTrace();
}
}
}
And again, we would be able to make an SSH connection with the remote machine.
Here is the video showing how to connect to a remote machine using Java.
What if we used an invalid key? What exception will we get?
We will get an invalid privatekey JSchException.
com.jcraft.jsch.JSchException: invalid privatekey: [B@1b2c6ec2
at com.jcraft.jsch.KeyPair.load(KeyPair.java:948)
at com.jcraft.jsch.KeyPair.load(KeyPair.java:561)
at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
at com.jcraft.jsch.JSch.addIdentity(JSch.java:406)
at com.jcraft.jsch.JSch.addIdentity(JSch.java:366)
What if we used the wrong password?
Here, we will get an Auth fail JSchException.
com.jcraft.jsch.JSchException: Auth fail
at com.jcraft.jsch.Session.connect(Session.java:519)
at com.jcraft.jsch.Session.connect(Session.java:183)
Related Articles –
- How to execute commands using Jsch in java
- Copy or transfer file from a local to the remote server using Java
I hope you liked this article. If you found anything wrong or have any doubts, please feel free to write us in the comments or mail us at admin@codekru.com.