Alex Yeah
Alex Yeah

Reputation: 63

Jsch Known Hosts not working

Alright, I am getting UnknownHostKey exception. I don't want to do a workaround with StrictHostKeyChecking=no as in this post com.jcraft.jsch.JSchException: UnknownHostKey. I'd like JSCH to use the known hosts file the system's ssh uses. Is it possible?

Upvotes: 2

Views: 16934

Answers (2)

Sergey Yazvinskiy
Sergey Yazvinskiy

Reputation: 21

Find below another approach to provide full path to known_hosts file

As stated before we have to supply full path to known_hosts file, like '/home/<username>/.ssh/known_hosts'

With the example below, we do not need to hard code the path for a particular user. It will generate location of the file for current user using $HOME system variable.

And again, we have to manually issue sftp command on server ( via Putty for example) for the first time in order to update known_hosts file.

        private static ChannelSftp getChannel (String user, String passwd, String host, int port, String IdentityFile, String PassPhrase) throws JSchException
        {

            // set dbms_java.set_output(1000000); -- in PL/SQL to read messages  
            System.out.println("user: " + user);
            System.out.println("passwd: " + passwd);
            System.out.println("host: " + host);
            System.out.println("port: " + port);
            System.out.println("IdentityFile: " + IdentityFile);
            System.out.println("PassPhrase: " + PassPhrase);
            // -- 
            
            JSch jsch = new JSch();

            String HOME = String.valueOf(System.getenv("HOME"));
            String knownHostsFileName = Paths.get(HOME, ".ssh", "known_hosts").toString();
            System.out.println("knownHostsFileName: " + knownHostsFileName);

            if (knownHostsFileName != null && new File(knownHostsFileName).exists()) {
                jsch.setKnownHosts(knownHostsFileName);
                System.out.println("KnownHostsFile added");
            }
            
            if (IdentityFile != null && new File(IdentityFile).exists()) {
                  jsch.addIdentity(IdentityFile, PassPhrase);
                  System.out.println("IdentitFile added");
            }
            
            Session session = jsch.getSession(user, host, port);
            System.out.println("jsch.getSession");
            session.setPassword(passwd);
            System.out.println("setPassword");

/*          // It is necessary if we want to turn off known_hosts checking          
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            config.put("PreferredAuthentications", "publickey,password");
            session.setConfig(config); */
            
            session.connect();
            System.out.println("session.connect");
            Channel channel = session.openChannel("sftp");
            System.out.println("session.openChannel-sftp");
            channel.connect();
            System.out.println("channel.connect");
            return (ChannelSftp) channel;
        }

Upvotes: 1

Rishi Ahuja
Rishi Ahuja

Reputation: 126

Yes this is possible, while making the JSCH connection you need to set the knownHosts file location :

example JSCH Connection code :

        JSch jsch = new JSch();
        jsch.setKnownHosts(propertyReader.getKnownHosts());
        session = jsch.getSession(propertyReader.getUsername(),
                propertyReader.getSftpLocation(), 22);
        session.setPassword(propertyReader.getPassword());
        session.connect();
        channel = session.openChannel("sftp");
        channel.connect();
        ChannelSftp sftp = (ChannelSftp) channel;

        if (!StringUtils.isBlank(fileToPut)) {
            sftp.put(fileToPut, propertyReader.getSftpDirectory() + "/"
                    + newFileName);
        } else {
            sftp.put(propertyReader.getSftpDirectory() + "/" + newFileName,
                    ChannelSftp.OVERWRITE);
        }

Here the propertyReader is class which sets the location of all the sftp logistics the known hosts file will be located inside the ~/.ssh directory of the user with which the java program is running :

/home/<username>/.ssh/known_hosts

To add remote sftp server to the known hosts file, you can first do a manual sftp using the regular sftp command on the server from where you need to run the java process using the same user:

sftp username@host

then provide the password. OR if using key :

sftp -i KEYFILE.pem username@host

If the connection is established it will prompt you to add the host to the known hosts, reply with a yes.

After registering the host to the known hosts file, use the java program to connect.

Upvotes: 1

Related Questions