-1

I am trying to run kafka shell scripts on a remote server to retrieve the list of consumer-groups and offsets. This is an alternative way rather than using jmx through the jvm [http://openjdk.java.net/tools/svc/jconsole/jconsole}. I am using jsch and getting the unknown host key error.

There are potential solutions from other posted questions, but I am not sure how to and which host key to retrieve. I can see 3 host key-server files on the server but not sure which one to copy.

Here is the code and error:

    JSch jsch = new JSch();
    String keyString = "";
    //byte [] key = Base64.getDecoder().decode("b6:83:60:7c:4a:98:00:ef:b9:4a:ba:b6:80:39:d6:42");
    //HostKey hostkey = new HostKey(host,key);
    //jsch.getHostKeyRepository().add(hostkey, null);

    jsch.setKnownHosts(new FileInputStream("C:\\Users\\.ssh\\host"));

    Session session = jsch.getSession(uname, host, 22);
    Properties config = new Properties();
    //config.put("StrickHostKeyChecking","no");
    session.setConfig(config);
    session.setPassword(pword);

    session.connect();

This is the error produced on the session.connect() line:

com.jcraft.jsch.JSchException: UnknownHostKey: 192.168.xx.1xx. RSA key 
         fingerprint is b6:83:60:7c:4a:98:00:ef:b9:4a:ba:b6:80:39:d6:42

EDIT:

Tried the following changes with the ssh_host_rsa_key.pub file copied from server to client. Added the following:

    JSch jsch = new JSch();
    String keyString = "";
    //byte [] key = 
     Base64.getDecoder().
         decode("b6:83:60:7c:4a:98:00:ef:b9:4a:ba:b6:80:39:d6:42");
    //HostKey hostkey = new HostKey(host,key);
    //jsch.getHostKeyRepository().add(hostkey, null);
     jsch.setKnownHosts("C:\\Users\\.ssh\\ssh_host_rsa_key.pub");

    Session session = jsch.getSession(uname, host, 22);
    Properties config = new Properties();
    session.setConfig(config);
    session.setPassword(pword);
    session.connect();

Creates the same error of JSchException: UnknownHostKey...RSA key is fingerporint. Then tried the follow way to actually read the file contents:

     String knownHostPublicKey = "";
     String readLine = "";
     BufferedReader fr = new BufferedReader(new 
            FileReader("C:\\Users\\.ssh\\ssh_host_rsa_key.pub"));
    while((readLine = fr.readLine()) != null){
        knownHostPublicKey = readLine;
        System.out.println(knownHostPublicKey);
    }

  //  jsch.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));

    session.connect();
vbNewbie
  • 3,291
  • 15
  • 71
  • 155

1 Answers1

2

The SSH protocol (not unlike other encrypted protocols) authenticates both the client to the server and the server to the client.

The client side (your code) authenticates either with a key (which is usually preferred for an automated system) or with a username/password pair. You've got that part figured out already.

The server side (the remote system) authenticates itself with a host key, which the client can use to confirm that it's talking to the server it expects. In theory, if you are paranoid, you transfer the public key part of the host key (or at least its fingerprint) from the server to your client via some out-of-band secure mechanism. In practice, most people simply acknowledge the host key the first time they connect to the server, after which it is stored in the known_hosts file on the client. (That is, most people use a Trust On First Use policy.)

The problem arises here when you're connecting to a new server with an automated process for the first time. How can you be certain that the server you're connecting to is the one you want? If a nefarious person on the network were performing a man-in-the-middle attack on you, you would be giving that person the username and password they need to log into the real server, and your code would never be the wiser.

There are two main ways to solve this. First, you can collect the host key from the remote server manually, and then save it into the known hosts file for your automated process. This is simple as long as you can manually connect: just use a command-line SSH client to connect to the server, acknowledge the new host key at the prompt, and then copy the ~/.ssh/known_hosts file (or equivalent) from your user's home directory to the location used by your automated process.

Based on the error message, the host key you want is an RSA key (with fingerprint b6:83:60:7c:4a:98:00:ef:b9:4a:ba:b6:80:39:d6:42). Assuming that the remote Unix server is using OpenSSH or a compatible implementation, the default location for the RSA host key is /etc/ssh/ssh_host_rsa_key, although this path can be changed by directives in /etc/ssh/sshd_config. The value you want to put into the known_hosts file is the public key corresponding to this private key -- typically this would be stored in /etc/ssh/ssh_host_rsa_key.pub. Again, the easiest way to get the format right is to just connect with some other SSH client, acknowledge the host key, and then check the known_hosts file you got.

A less secure alternative would be to tell your client to simply ignore the host key, and hope for the best. (Maybe you trust your network enough that you're not worried about a man in the middle, although if you trust it that much then you probably don't need SSH either.) This is what the StrictHostKeyChecking=no setting does, which I notice is set in a comment, although misspelled.

Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135
  • Thank you so much for the detailed explanation. I had a few host files in that server ssh directory and was not sure which to use but thanks for pointing out the RSA host file. It however does not seem to contain that specific fingerprint. But I will copy the contents of the file to the client machine and see if that works – vbNewbie Sep 14 '18 at 22:14
  • @vbNewbie: Note that that `/etc/ssh/ssh_host_rsa_key` is the **private key** which you do **NOT** want to exfiltrate off the server! You want the corresponding **public key** which will be stored in `/etc/ssh/ssh_host_rsa_key.pub`. The contents of the `.pub` file should be all on one line of text: that line should be added to your `known_hosts` file. – Daniel Pryden Sep 14 '18 at 22:44
  • sorry to keep bothering you but I have not got this working. Tried reading the file contents and that did not work and then just set the jsch.setknownhosts(filename) as such and in both cases the same error. I had copied the file from the remote server. Please set question EDIT: – vbNewbie Sep 16 '18 at 13:06
  • 1
    @vbNewbie+ `known_hosts` format is not merely a copy of the host pubkey. `known_hosts` can have multiple lines and each line is a **host name and/or address _followed by_** the algorithm and blob which are (effectively) copied from that host's `.pub` file. – dave_thompson_085 Sep 16 '18 at 15:15
  • @dave_thompson_085 - thanks for your response. There was no known_hosts file so I tried creating one with the contents of the server ssh_host_rsa_key file. I am just trying to figure out how to do a manual connection and get the host key message to reappear. – vbNewbie Sep 17 '18 at 01:29