尝试使用 java 在远程 unix 服务器上执行脚本时出错
Error attempting to execute script on remote unix server using java produces
我正在尝试 运行 kafka shell scripts on a remote server to retrieve the list of consumer-groups and offsets. This is an alternative way rather than using jmx through the jvm [http://openjdk.java.net/tools/svc/jconsole/jconsole}. I am using 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 协议(与其他加密协议不同)既向服务器验证客户端,又向客户端验证服务器。
客户端(您的代码)使用密钥(自动化系统通常首选)或 username/password 对进行身份验证。你已经弄清楚了那部分。
服务器端(远程系统)使用主机密钥对自身进行身份验证,客户端可以使用该密钥来确认它正在与它期望的服务器对话。理论上,如果您偏执,您可以通过某种带外安全机制将主机密钥的 public 密钥部分(或至少是其指纹)从服务器传输到您的客户端。实际上,大多数人在第一次连接到服务器时简单地确认主机密钥,之后它存储在客户端的 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
文件的值是与此私钥对应的 public 密钥 ——通常这将存储在 /etc/ssh/ssh_host_rsa_key.pub
中.同样,获得正确格式的最简单方法是与其他 SSH 客户端连接,确认主机密钥,然后检查您获得的 known_hosts
文件。
一个不太安全的替代方法是告诉您的客户简单地忽略主机密钥,并希望最好的结果。 (也许你足够信任你的网络,所以你不担心中间人,但如果你那么信任它,那么你可能也不需要 SSH。)这就是 StrictHostKeyChecking=no
设置的作用,我注意到它是在评论中设置的,尽管拼写错误。
我正在尝试 运行 kafka shell scripts on a remote server to retrieve the list of consumer-groups and offsets. This is an alternative way rather than using jmx through the jvm [http://openjdk.java.net/tools/svc/jconsole/jconsole}. I am using 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 协议(与其他加密协议不同)既向服务器验证客户端,又向客户端验证服务器。
客户端(您的代码)使用密钥(自动化系统通常首选)或 username/password 对进行身份验证。你已经弄清楚了那部分。
服务器端(远程系统)使用主机密钥对自身进行身份验证,客户端可以使用该密钥来确认它正在与它期望的服务器对话。理论上,如果您偏执,您可以通过某种带外安全机制将主机密钥的 public 密钥部分(或至少是其指纹)从服务器传输到您的客户端。实际上,大多数人在第一次连接到服务器时简单地确认主机密钥,之后它存储在客户端的 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
文件的值是与此私钥对应的 public 密钥 ——通常这将存储在 /etc/ssh/ssh_host_rsa_key.pub
中.同样,获得正确格式的最简单方法是与其他 SSH 客户端连接,确认主机密钥,然后检查您获得的 known_hosts
文件。
一个不太安全的替代方法是告诉您的客户简单地忽略主机密钥,并希望最好的结果。 (也许你足够信任你的网络,所以你不担心中间人,但如果你那么信任它,那么你可能也不需要 SSH。)这就是 StrictHostKeyChecking=no
设置的作用,我注意到它是在评论中设置的,尽管拼写错误。