我正在尝试构建一个利用Spring Boot和Integration来通过SSH从远程系统检索文件的应用程序。如果我将SessionFactory的allowUnknownKeys
属性设置为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);
}
但是,如果我将allowUnknownKeys
设置为false并取消注释了上面代码段中的行,则无法建立连接。
2019-01-21 08:55:05.536错误10680 --- [ask-scheduler-1] osintegration.handler.LoggingHandler:org.springframework.messaging.MessagingException:将'sftp-outbound'同步到时发生问题本地目录;嵌套的异常是org.springframework.messaging.MessagingException:无法在以下位置执行 会议嵌套的异常是org.springframework.integration.util.PoolItemNotAvailableException:无法获取池项
根本原因是无法建立“主机的真实性”,并且要我授予建立连接的权限。我明白了但是,我的问题是为什么它无法正确读取/解析known_hosts文件?我传递给它的是自动生成的一个,当我通过命令行ssh进入系统时,它可以正常工作。使用断点,我已验证应用程序正在查找和读取正确的known_hosts
文件。我可以使用完全相同的凭据并通过bash shell连接,而无需任何有关主机真实性的提示。
我想念什么?
谢谢。
答案 0 :(得分:1)
有趣;我刚刚在Mac到Mac上进行了测试,并遇到了相同的问题-我调试了JSCH客户端,它找到了确定的密钥,但是类型不匹配-在我的known_hosts文件中,类型为ecdsa-sha2-nistp256
(类型3)但密钥交换返回的密钥报告为类型2(ssh-rsa
)。
我在this answer的帮助下解决了此问题...
Properties sessionConfig = new Properties();
sessionConfig.setProperty("server_host_key", "ecdsa-sha2-nistp256");
factory.setSessionConfig(sessionConfig);
或者您也可以按照链接中的说明将ssh-rsa密钥添加到known_hosts。
确认已使用
重建已知主机ssh -o HostKeyAlgorithms=ssh-rsa <host>
(或ssh-keyscan
)也可以。