How do I use JSch with strict host key checking and known_hosts validation?

When using JSch (Java Secure Channel) to connect to an SSH server, you can enable strict host key checking and validate the server against a known_hosts file. By default, strict host key checking ensures that your application will only connect to SSH servers that are already listed in the known_hosts file. If the server’s key is not present or doesn’t match, the connection will fail.

Here’s how you can implement strict host key checking and configure the use of a known_hosts file with JSch:

Step 1: Enable Strict Host Key Checking and Set Known Hosts

Below is an example of how to configure JSch with strict host key checking:

package org.kodejava.jsch;

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

import java.util.Properties;

public class JSchStrictHostKeyCheckingExample {
   public static void main(String[] args) {
      String username = "username";
      String host = "example.com";
      int port = 22; // default SSH port
      String privateKeyPath = "/path/to/your/private/key";
      String knownHostsPath = "/path/to/your/known_hosts";

      try {
         // Initialize JSch
         JSch jsch = new JSch();

         // Set private key if authentication requires it
         jsch.addIdentity(privateKeyPath);

         // Set the known_hosts file for host key verification
         jsch.setKnownHosts(knownHostsPath);

         // Create SSH session
         Session session = jsch.getSession(username, host, port);

         // Set session properties for strict host key checking
         Properties config = new Properties();
         config.put("StrictHostKeyChecking", "yes"); // Enables strict host key checking
         session.setConfig(config);

         // Connect to the SSH server
         session.connect();

         System.out.println("Connected securely with strict host key checking.");

         // Perform your operations (e.g., execute commands, transfer files, etc.)

         // Disconnect from the SSH server
         session.disconnect();
         System.out.println("Disconnected from server.");

      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

Explanation:

  1. StrictHostKeyChecking:
    • Setting the StrictHostKeyChecking property to "yes" will enforce strict validation of the host’s key against the known_hosts file.
    • If the host is not in the known_hosts file or if the key does not match, the connection will fail.
  2. Known Hosts File:
    • Use jsch.setKnownHosts(knownHostsPath) to specify the path to the known_hosts file. This file stores the public host keys of remote servers that you trust.
  3. Private Key:
    • If the SSH server requires private key authentication, use jsch.addIdentity(privateKeyPath) to add your private key.
  4. Session Configuration:
    • Other common configuration options (set in Properties) may include:
      • PreferredAuthentications: Specify the preferred authentication methods (e.g., publickey,password,keyboard-interactive).
      • UserKnownHostsFile: Alternative way to point to the known_hosts file.
  5. Error Handling:
    • If the server’s host key is not present in the known_hosts file or does not match, you will encounter an error similar to:
    com.jcraft.jsch.JSchException: reject HostKey: your-host
    

    This means the server’s public key either needs to be added to the known_hosts file or matches an incorrect entry.

Step 2: Generating/Updating the known_hosts File

To manually add a host key to the known_hosts file:

Run the following command on any system with SSH installed:

ssh-keyscan -H your-host >> /path/to/known_hosts
  • -H: Hashes the hostname before storing it in the known_hosts file.
  • Replace your-host with the actual hostname or IP address of the server.

Common Issues and Debugging

  1. Host Key Verification Failed:
    • Ensure the server’s public key exists in the known_hosts file.
    • Ensure the correct knownHostsPath is specified in your code.
  2. Permission Denied:
    • Check your username, private key path, and associated permissions.
    • Make sure your private key is readable and properly associated with the user on the server.
  3. Logging Debug Information:
    JSch provides detailed logs for debugging. You can enable verbose logging as below:

    JSch.setLogger(new com.jcraft.jsch.Logger() {
          public boolean isEnabled(int level) { return true; }
          public void log(int level, String message) { System.out.println(message); }
      });
    

By following this approach, you can securely connect to an SSH server while leveraging strict host key checking and known_hosts validation.


Maven Dependencies

<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.55</version>
</dependency>

Maven Central

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.