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.
We have also made a video on this topic, which you can find at the end of this article. Please feel free to check it out.
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.