我正在尝试在远程服务器上运行kafka shell脚本,以检索使用者组和偏移量的列表。这是一种替代方法,而不是通过jvm使用jmx[http://openjdk.java.net/tools/svc/jconsole/jconsole}. 我正在使用jsch并得到未知的主机密钥错误。
其他发布的问题有潜在的解决方案,但我不确定如何以及检索哪个主机密钥。我可以在服务器上看到 3 个主机密钥服务器文件,但不确定要复制哪个文件。
下面是代码和错误:
JSch jsch = new JSch();
String keyString = "";
//byte [] key = Base64.getDecoder().decode("b6:83:60:7c:4a:98:00:ef:b9:4a:ba:b6:80:39:d6:42");
//HostKey hostkey = new HostKey(host,key);
//jsch.getHostKeyRepository().add(hostkey, null);
jsch.setKnownHosts(new FileInputStream("C:\\Users\\.ssh\\host"));
Session session = jsch.getSession(uname, host, 22);
Properties config = new Properties();
//config.put("StrickHostKeyChecking","no");
session.setConfig(config);
session.setPassword(pword);
session.connect();
这是session.connect()行产生的错误:
com.jcraft.jsch.JSchException: UnknownHostKey: 192.168.xx.1xx. RSA key
fingerprint is b6:83:60:7c:4a:98:00:ef:b9:4a:ba:b6:80:39:d6:42
编辑:
已尝试对从服务器复制到客户端的 ssh_host_rsa_key.pub 文件进行以下更改。添加了以下内容:
JSch jsch = new JSch();
String keyString = "";
//byte [] key =
Base64.getDecoder().
decode("b6:83:60:7c:4a:98:00:ef:b9:4a:ba:b6:80:39:d6:42");
//HostKey hostkey = new HostKey(host,key);
//jsch.getHostKeyRepository().add(hostkey, null);
jsch.setKnownHosts("C:\\Users\\.ssh\\ssh_host_rsa_key.pub");
Session session = jsch.getSession(uname, host, 22);
Properties config = new Properties();
session.setConfig(config);
session.setPassword(pword);
session.connect();
创建相同的 JSchException: UnknownHostKey...RSA密钥是fingerporint。然后尝试以下方式实际读取文件内容:
String knownHostPublicKey = "";
String readLine = "";
BufferedReader fr = new BufferedReader(new
FileReader("C:\\Users\\.ssh\\ssh_host_rsa_key.pub"));
while((readLine = fr.readLine()) != null){
knownHostPublicKey = readLine;
System.out.println(knownHostPublicKey);
}
// jsch.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));
session.connect();
SSH协议(与其他加密协议不同)对客户端到服务器和服务器到客户端进行身份验证。
客户端(您的代码)使用密钥(这通常是自动化系统的首选)或用户名/密码对进行身份验证。您已经弄清楚了这部分。
服务器端(远程系统)使用主机密钥对自身进行身份验证,客户端可以使用该密钥来确认它正在与预期的服务器通信。理论上,如果你是偏执狂,你会通过一些带外安全机制将主机密钥的公钥部分(或至少是其指纹)从服务器传输到客户端。实际上,大多数人只是在第一次连接到服务器时确认主机密钥,然后将其存储在客户端的known_hosts
文件中。(也就是说,大多数人使用“首次使用时信任”策略。
当您第一次使用自动化流程连接到新服务器时,问题就出现在这里。如何确定要连接的服务器是您想要的服务器?如果网络上有一个邪恶的人在对你进行中间人攻击,你会给这个人登录真实服务器所需的用户名和密码,而你的代码永远不会更明智。
解决这个问题主要有两种方法。首先,您可以从远程服务器手动收集主机密钥,然后将它保存到已知的hosts文件中,以供自动化流程使用。这很简单,只要您可以手动连接:只需使用命令行SSH客户机连接到服务器,在提示符下确认新的主机密钥,然后复制< code>~/。ssh/known_hosts文件(或等效文件)从用户的主目录复制到自动化流程使用的位置。
根据错误消息,您需要的主机密钥是RSA密钥(带有指纹b6:83:60:7c:4a:98:00:ef:b9:4a:ba:b6:80:39:d6:42
)。假设远程Unix服务器使用的是OpenSSH或兼容的实现,RSA主机密钥的默认位置是/etc/ssh/ssh_host_RSA_key
,尽管可以通过etc/ssh/shd_config
中的指令更改此路径。您要放入known_hosts
文件中的值是与此私钥对应的公钥——通常将存储在/etc/ssh/ssh_host_rsa_key.pub
中。同样,获得正确格式的最简单方法是,只需连接其他SSH客户端,确认主机密钥,然后检查获得的known_hosts
文件。
一个不太安全的选择是告诉你的客户直接忽略主机密钥,并抱最好的希望。(也许你足够信任你的网络,所以你不担心中间的人,尽管如果你如此信任它,那么你可能也不需要SSH。)这就是StrictHostKeyChecking=no
设置的作用,我注意到它是在注释中设置的,尽管拼写错误。