我正在尝试使用 Jsch 在 Java 中建立 SSH 连接。 我已将“StrictHostKeyChecking”设置为“是”。据我了解,必须事先获取服务器的主机密钥并将其存储在主机密钥文件中 在第一次尝试连接到服务器之前。如何获取服务器的 HostKey。我的代码产生以下异常:
com.jcraft.jsch.JSchException:未知主机密钥:ASY-PC RSA 密钥指纹为 22:fb:ee:fe:18:cd:aa:9a:9c:78:89:9f:b4:78:75:b4
如何与 StrictHostKeyChecking 建立连接 是的。 这是我的代码。
package sshexample;
import com.jcraft.jsch.*;
import java.io.*;
public class SSHexample
{
public static void main(String[] args)
{
String user = "user";
String password = "password";
String host = "192.168.100.103";
int port=22;
try
{
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "yes");
System.out.println("Establishing Connection...");
session.connect();
System.out.println("Connection established.");
System.out.println("Crating SFTP Channel.");
ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
sftpChannel.connect();
}catch(Exception e) {
e.printStackTrace();
}
}
您必须通过调用以下函数来提供 KnownHostKeys 文件
jsch.setKnownHosts(new FileInputStream(knownHostsFile));
此文件应包含所有已知主机的指纹,并用新行分隔。
例如
hostname,10.1.1.120, ssh-rsa AAAAC3NzaC1yc2EAAAADAQABAAABAQCi5b647581SwC0uUDQw1ENjKSz3rhJMRRZEgIjHylvF4fbuAEzj645YoAf9SItb51MhetFAJrq98jYsHpedSm3IoMG+aR/P1CjsBz1RtJKlfR2NfYDCZ7Dyx11P8FnJbwbYif/GeG0xEujekwF1pyL0tNPmf0H4/GPR4mwrv/llGlB3Lo3BzxrGtl4f4X/oSHDoo7FrQkDwqOfeSM++3vPPHxyVO5zhFJ5u9f7M/uuxUeHS+YS5JWAI7NLXKgbiM9dluGzZU/6Awo3ux4x5ojL+kf29JEVxK+o6GfW2bIW+LhgIGZNThnN5nHzBVfNNHvQ7KC5ic0h2z2gbVpwJr1h
您可以使用任何 sftp 客户端从服务器获取此密钥,但是如果您使用的是 Linux 或 unix,以下命令可能会有所帮助
ssh-keyscan -t rsa 10.1.1.120
经过几分钟的测试,我找到了解决方案。如果您不想使用默认的
knownHost
文件,只需创建您自己的
文件的外观如下:
192.168.0.1 ssh-rsa
AAAAC3NzaC1yc2EAAAADAQABAAABAQCi5b647581SwC0uUDQw1ENjKSz3rhJMRRZEgIjHylvF4fbuAEzj645YoAf9SI
tb51MhetFAJrq98jYsHpedSm3IoMG+aR/P1CjsBz1RtJKlfR2NfYDCZ7Dyx11P8FnJbwbYif
/GeG0xEujekwF1pyL0tNPmf0H4/GPR4mwrv/llGlB3Lo3BzxrGtl4f4X
/oSHDoo7FrQkDwqOfeSM++3vPPHxyVO5zhFJ5u9f7M/uuxUeHS+YS5JWAI7NLXKgbiM9dluGzZU
/6Awo3ux4x5ojL+kf29JEVxK+o6GfW2bIW+LhgIGZNThnN5nHzBVfNNHvQ7KC5ic0h2z2gbVpwJr1h
所有这些条目都由换行符分隔。您可以通过询问会话来获取所需的 RSA 密钥:
session=null;
com.jcraft.jsch.Channel channel =null;
try{
ssh=new JSch();
ssh.setKnownHosts("test");
session=ssh.getSession(userTextField.getText(),ip,22);
session.setPassword(passwordField1.getText());
System.out.println(session.getHostKey());
session.connect();
channel=session.openChannel("sftp");
channel.connect();
ChannelSftp sftp=(ChannelSftp) channel;
System.out.println(sftp.getHome());
for (Object o : sftp.ls(sftp.getHome())) {
System.out.println(((ChannelSftp.LsEntry)o).getFilename());
}
} catch (JSchException e1) {
e1.printStackTrace();
addHost(session.getHostKey().getKey());
} catch (SftpException e1) {
e1.printStackTrace();
}
}
private void addHost(String key){
try {
FileWriter tmpwriter=new FileWriter("test",true);
tmpwriter.append(ip + " ssh-rsa " + key+"\n");
System.out.println(ip + " ssh-rsa " + key);
tmpwriter.flush();
tmpwriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
所以
session.getHostKey().getKey()
就是您要拨打以获取钥匙的电话。
在索取钥匙并在catch中处理之前,您还需要先致电
session.connect();
。
大多数答案表明您必须提供已知的主机文件,但未能解决如何获取它。您只需通过 SSH 连接到主机即可。
例如
ssh [email protected]
出现提示时提供密码。首次连接时,您将保存主机 ssh 密钥指纹。连接后,您可以在
找到您的known_host文件user/.ssh/known_hosts
对我来说,Windows 路径是
C:\Users\athakur\.ssh\known_hosts
。您可以直接使用该文件。或者编辑该文件并从中选取与您的 IP 地址相对应的条目,如下所示
192.168.100.103 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1UsgiLH5hjIScZlqPA4kNhPoXAX00mMv65N8qTvYd1D1M5DwWtTTcxK4w0wGKKVA7RERzWbtjPpSomJwT1LofZr+qaf LdiEvhirIXVYHSWZqp6zTJW0jzk3p07ugjoHV3YUWKDzOaiFuOMslt8hD7pZv8nhOYfxBZdsVHdu kYRP8MADXC0ZgOD5ZYZ0EglaQJYPG7n73PSMZWZT/oafUcx6bFiRF4QsXaguWuu6umX9gaV7Vvoy MJg+kxPAKnGDFY7If61AG7vAchUUhlQ44SB1FFr25y+qeUg2NGqAxH/Z/ZAfvZ+pDv3Cd9s+KCnEIqxyxY/sPQ2zCvwf0Z9fTeQ==
注意:主机 SSH 指纹(基于您可以在
/etc/ssh/ssh_host_rsa_key.pub
找到的主机公钥)可能会在该计算机上重新安装 SSH 时发生变化。或者你可能会遇到MIM攻击(即使是为了测试)。在这种情况下,您将必须以与上述相同的方式选择新条目。
也许它不再相关,但就我而言,容器中的 docker-compose.yml 也发生了类似的问题,它是从 spring-boot 应用程序构建的,100%在本地工作
config-service:
image: <host>/<bla>-config-service:<version>
hostname: config-service
ports:
- 3000:3000
depends_on:
- discovery
environment:
- CONSUL_HOST=discovery
- CONSUL_PORT=<port>
- CONFIG_GIT_URI=git@<host>:<group>/<repository>.git
- CONFIG_GIT_BRANCH=development
volumes:
- ~/.ssh/:/root/.ssh/:ro
解决方案是对 ~/.ssh 文件夹应用 hack。
chcon -Rt svirt_sandbox_file_t ~/.ssh
之后,我认为卷在 docker 容器和本地计算机之间正确映射,并且描述的异常消失了。
基于@nothing-to-know 答案,以下方法非常方便:
public static String getHostKey(String hostName, int port, String userName, char[] password) {
JSch ssh;
Session session = null;
String hostKey = "";
try {
ssh = new JSch();
session = ssh.getSession(userName, hostName, port);
session.setPassword(new String(password));
if (session.getHostKey() != null) {
hostKey = session.getHostKey().getHost() + " " + session.getHostKey().getType() + " " + session.getHostKey().getKey();
}
session.connect();
} catch (JSchException e1) {
hostKey = session.getHostKey().getHost() + " " + session.getHostKey().getType() + " " + session.getHostKey().getKey();
} finally {
session.disconnect();
return hostKey;
}
}
使用 ssh-keyscan -t rsa 10.1.1.120 对我有用