1

I am attempting to build an application that makes use of Spring Boot and Integration to retrieve files from a remote system over SSH. It works just fine if I set the allowUnknownKeys property of the SessionFactory to true.

@Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
    DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
    factory.setHost("x");
    factory.setPort(22);
    factory.setUser("x");
    factory.setPassword("x");
    factory.setAllowUnknownKeys(true);
    // factory.setHostKeyAlias("x");
    // factory.setKnownHosts(
    //         System.getProperty("user.home") + File.separator + ".ssh" + File.separator + "known_hosts");

    return new CachingSessionFactory<LsEntry>(factory);
}

However, if I set allowUnknownKeys to false and uncomment out the lines in the snippet above, a connection cannot be established.

2019-01-21 08:55:05.536 ERROR 10680 --- [ask-scheduler-1] o.s.integration.handler.LoggingHandler : org.springframework.messaging.MessagingException: Problem occurred while synchronizing 'sftp-outbound' to local directory; nested exception is org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is org.springframework.integration.util.PoolItemNotAvailableException: Failed to obtain pooled item

The underlying cause is the fact that the "authenticity of the host" cannot be established, and it is wanting me to give permission to establish the connection. I understand this. However, my problem is why it is not reading/parsing the the known_hosts file correctly? The one I am passing to it is the one automatically generated and it works fine when I ssh into a system through the command line. Using breakpoints, I have verified that the application is finding and reading the correct known_hosts file. I can use the exact same credentials and connect through a bash shell without any prompt concerning the authenticity of the host.

What am I missing?

Thanks.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
KellyM
  • 2,472
  • 6
  • 46
  • 90
  • Do you know if the Java application has correct permissions to access the `known_hosts` file? In most *nix environments, the file permissions are strictly limited for the `.ssh` directory and any files inside of it. – Alex W Jan 21 '19 at 18:17
  • 1
    Interesting; I just tested it mac to mac and had the same problem - I debugged the JSCH client and it finds the key ok, but the type doesn't match - in my known_hosts file, the type is `ecdsa-sha2-nistp256` (type 3) but the key returned by the key exchange is reported as type 2 (`ssh-rsa`). – Gary Russell Jan 21 '19 at 18:50
  • 1
    Found a work-around in [this answer](https://stackoverflow.com/questions/34684251/jsch-unknownhostkey-exception-when-host-key-is-in-known-hosts-and-after-adding). – Gary Russell Jan 21 '19 at 19:25

1 Answers1

1

Interesting; I just tested it mac to mac and had the same problem - I debugged the JSCH client and it finds the key ok, but the type doesn't match - in my known_hosts file, the type is ecdsa-sha2-nistp256 (type 3) but the key returned by the key exchange is reported as type 2 (ssh-rsa).

I solved it with help from this answer...

    Properties sessionConfig = new Properties();
    sessionConfig.setProperty("server_host_key", "ecdsa-sha2-nistp256");
    factory.setSessionConfig(sessionConfig);

Or you can add the ssh-rsa key to the known_hosts as is described in the links there.

Confirmed that rebuilding known_hosts with

ssh -o HostKeyAlgorithms=ssh-rsa <host>

(or ssh-keyscan) works too.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Thanks! I tried the first solution (setting a configuration property), but definitely may look into the others depending on how the project develops. – KellyM Jan 21 '19 at 21:00