Reputation: 63
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
Reputation: 21
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
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