尝试使用java生成在远程unix服务器上执行脚本时出错

问题描述 投票:-1回答:1

我试图在远程服务器上运行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();
java jsch
1个回答
2
投票

SSH协议(与其他加密协议不同)对服务器的客户端和客户端的服务器进行身份验证。

客户端(您的代码)使用密钥(通常是自动系统首选)或用户名/密码对进行身份验证。你已经弄清楚了那部分。

服务器端(远程系统)使用主机密钥对自身进行身份验证,客户端可以使用主机密钥确认它正在与预期的服务器通信。理论上,如果您是偏执狂,则通过某种带外安全机制将主机密钥的公钥部分(或至少其指纹)从服务器传输到客户端。实际上,大多数人只是在第一次连接到服务器时确认主机密钥,然后将其存储在客户端的known_hosts文件中。 (也就是说,大多数人都使用Trust On First Use政策。)

当您第一次使用自动化流程连接到新服务器时,会出现此问题。你怎么能确定你要连接的服务器是你想要的服务器?如果网络上的一个邪恶的人正在对你进行中间人攻击,你就会给那个人登录真实服务器所需的用户名和密码,而你的代码永远不会更明智。

有两种主要方法可以解决这个问题。首先,您可以手动从远程服务器收集主机密钥,然后将其保存到自动进程的已知主机文件中。只要您可以手动连接,这很简单:只需使用命令行SSH客户端连接到服务器,在提示符下确认新的主机密钥,然后将~/.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/sshd_config中的指令更改此路径。您要放入known_hosts文件的值是与此私钥对应的公钥 - 通常这将存储在/etc/ssh/ssh_host_rsa_key.pub中。再次,获得正确格式的最简单方法是只与其他SSH客户端连接,确认主机密钥,然后检查您获得的known_hosts文件。

一个不太安全的替代方案是告诉客户简单地忽略主机密钥,并希望最好。 (也许你足够信任你的网络,你不担心中间的人,虽然如果你相信那么多,那么你可能也不需要SSH。)这就是StrictHostKeyChecking=no设置所做的,我注意到的是设置在评论中,虽然拼写错误。

© www.soinside.com 2019 - 2024. All rights reserved.