我在使用以下任何库 JSCH、apache 的 sshd 和 sshj 时遇到了一些 SSH 问题。当试图从我运行的命令中读取输出时,它们都阻塞在 exec channel
上,最终会超时。问题是这只发生在一些安装了 OpenSSH 4.5 服务器的路由器上。客户端在我安装了最新可能版本的 OpenSSH 的虚拟机上完美运行。
使用 Apache MINA SSHD 的客户端将是:
public static void main(String[] args) throws InterruptedException, IOException {
String cmdToRun = "ls";
SshClient client = SshClient.setUpDefaultClient();
client.start();
ClientSession session = client.connect("127.0.0.1", 22).await().getSession();
session.authPassword("sshUser", "sshPass").await().isSuccess();
ChannelExec channelExec = session.createExecChannel(cmdToRun);
channelExec.setOut(System.out);
channelExec.open();
channelExec.waitFor(ClientChannel.CLOSED, 0);
channelExec.close(true);
client.stop();
}
我正在 Eclipse 中调试它并使用 WireShark 我正在观察传输的消息和接收的消息,一切似乎都很好。 DH 交换进行得很顺利,auth 也很顺利,但是当我尝试打开 exec channel 时,在 Virtual Box(它工作的地方)我得到:
.....
.....
Received SSH_MSG_USERAUTH_SUCCESS
Send SSH_MSG_CHANNEL_OPEN on channel 101
我从服务器收到的响应如下:
5b 00 00 00 65 00 00 00 00 00 00 00 00 00 00 80 00
5b means SSH_MSG_CHANNEL_OPEN_CONFIRMATION
00 00 00 65 is the channel the client sent(101 of course)
00 00 00 00 is the channel that the server assigned
00 00 00 00 is the initial window size
00 00 80 00 is the maximum packet size
因为初始窗口大小为0,所以我先收到一个SSH_MSG_CHANNEL_WINDOW_ADJUST
消息,然后我收到一个SSH_MSG_CHANNEL_SUCCESS
,这意味着请求(命令)运行成功. SSH_MSG_CHANNEL_REQUEST
,其中包含 exit-status 0
和 SSH_MSG_CHANNEL_DATA
,其中包含我的 ls
命令的结果,稍后按预期进行交换。
现在在具有 OpenSSH 4.5 的路由器上,5b 消息看起来略有不同:
5b 00 00 00 65 00 00 00 00 00 02 00 00 00 00 80 00
我们可以看到初始窗口已设置,因此无需接收 SSH_MSG_CHANNEL_WINDOW_ADJUST
。我确实收到了 SSH_MSG_CHANNEL_SUCCESS
,仅此而已,然后它停止了。它不接收任何包含命令退出状态的 SSH_MSG_CHANNEL_REQUEST
,或 SSH_MSG_CHANNEL_DATA
,如上例所示。 Wireshark 确认了这一点。
为什么会这样?如果我收到确认请求成功的 SSH_MSG_CHANNEL_SUCCESS
,为什么我没有收到结果?
我使用的所有不同的客户端库都会发生这种情况,它们会以某种方式超时。如果我打开 shell
channel ,一切正常,但我不想使用交互式 session 。对于有很多页的命令,你必须阅读每一行,看看你是否需要按什么来继续等等。
我应该放弃吗?也许 OpenSSH 4.5 不允许 exec
channel ?为什么没有任何错误?
最佳答案
很明显,服务器上的 SSH 设置是我没有收到任何响应或错误的罪魁祸首。
如果对某人有帮助: 如果您想调试客户端和服务器之间的 ssh 消息交换以准确查看它们交换的内容,而不必捕获 session key 并解密 ssh,您可以查看接收到的缓冲区:ClientSessionImpl:doHandleMessage(Buffer) for Apache Mina SSH 客户端。哦,这是看你从服务器收到什么,看你发送什么应该很容易,看看你在代码中使用的方法。
关于java - 使用 JSCH、apache mina sshd 或 sshj 的 Open SSH 的 SSH Exec channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19229501/