How to connect SSH (Secure Shell) with Java

Nithidol Vacharotayan
3 min readFeb 2, 2024

--

Icon by Freepik

SSH (Secure Shell) is a helpful protocol for remote and transferring files between SSH server and client.

Java can execute commands, shell scripts, or transfer files on the server.

Use case scenario: An administrator of a web application wants to do a task, but The Task needs to execute crontab or shell scripts on the server. The developer can design a web page to support this requirement by creating an admin page with a button for the administrator to go to the admin page and click a button to execute it. This can provide an easy way for administrators to execute commands or shell scripts without knowledge of Linux or Unix OS.

For example, connect to SSH (Secure Shell).

private static Session setupJsch() throws JSchException {
String server = "localhost";
int port = 22;
String user = "admin";
String pass = "password";
JSch jsch = new JSch();
jsch.setKnownHosts("C:/Users/nithidol.v/.ssh/known_hosts_web");
//generate the known_hosts file using the following command:
//ssh-keyscan -H -t rsa REMOTE_HOSTNAME >> known_hosts_web
//copy keyscan to c:/Users/user_name/.ssh/known_hosts_web
Session jschSession = jsch.getSession(user, server, port);
jschSession.setPassword(pass);
System.out.println("#connect begin.");
jschSession.connect();
System.out.println("#connect end.");
return jschSession;
}

Connect without KnownHosts

Developers who deploy projects on the server can avoid generating KnownHosts by adding configurations.

jschSession.setConfig("StrictHostKeyChecking", "no");

Algorithm negotiation fails.

Developers connect to SSH and then encounter a problem Algorithm.

Algorithm negotiation fail: algorithmName="cipher.c2s" jschProposal="aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com" serverProposal="aes128-cbc,aes256-cbc"

Developers can add more Algorithms by adding configuration.

java.util.Properties config = new java.util.Properties();
config.put("cipher.c2s", "aes128-cbc,aes256-cbc");
config.put("cipher.s2c", "aes128-cbc,aes256-cbc");

jschSession.setConfig(config);

Timeout configuration

Developers can configure the timeout to wait for a server response any longer to prevent a timeout when a server is a busy traffic network.

jschSession.setTimeout(120000); //2 minutes

Example execute command.

public static void listFile() throws JSchException, IOException {
Session session = setupJsch();
ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setCommand("ls -l");
channel.connect();

// Read the command output
InputStream in = channel.getInputStream();
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0) {
break;
}
System.out.print(new String(tmp, 0, i));
}
if (channel.isClosed()) {
if (in.available() > 0) {
continue;
}
System.out.println("Exit status: " + channel.getExitStatus());
break;
}
}

channel.disconnect();
session.disconnect();
System.exit(0);
}

Example: execute shell scripts.

public static void executeShellScript() throws JSchException, IOException {
String remoteScriptPath = "/path/on/remote/server/script.sh";
Session session = setupJsch();
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
InputStream scriptInputStream = new FileInputStream(remoteScriptPath);
channelExec.setCommand("bash");
channelExec.setInputStream(scriptInputStream);
channelExec.connect();
scriptInputStream.close();
channelExec.disconnect();
session.disconnect();
System.exit(0);
}

For example, execute crontab for schedule.

public static void executeCrontab() throws JSchException {
String cronExpression = "*/5 * * * *"; // Example: Run every 5 minutes
Session session = setupJsch();
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
channelExec.setCommand("echo \"" + cronExpression + " /path/to/remote/script.sh\" | crontab -");
channelExec.connect();
channelExec.disconnect();
session.disconnect();
System.exit(0);
}

For example, create not exist directory.

private static void createDirectory(ChannelSftp channelSftp, String path) throws SftpException {
String[] folders = path.split("/");
StringBuilder currentPath = new StringBuilder();
for (String folder : folders) {
if (!folder.isEmpty()) {
currentPath.append("/").append(folder);
try {
channelSftp.cd(currentPath.toString());
} catch (Exception e) {
channelSftp.mkdir(currentPath.toString());
}
}
}
}

For example, upload files.

public void uploadFile(String source, String remoteFilePath) throws Exception {
ChannelSftp channelSftp = setupJsch();
channelSftp.connect();
File f = new File(source); // D:/reports/example.csv
log.debug("source=" + f.getAbsolutePath());
log.debug("remotePath=" + remoteFilePath + "/" + f.getName()); // /report/date_YYYYMMdd/example.csv
channelSftp.put(f.getAbsolutePath(), remoteFilePath + "/" + f.getName());
log.debug(source + " has uploaded.");
channelSftp.exit();
}

Finally, SSH (Secure Shell) can be used for multiple purposes, such as the CI/CD Integration Pipeline. The developer should learn Linux and UNIX commands. It is helpful for The developer to manage and maintain the server.

Thank you for reading.

--

--

Nithidol Vacharotayan

Programming enthusiast with 10+ years of experience in Java loves sharing knowledge with others and exploring new technologies together!