java - 使用 JSCH、apache mina sshd 或 sshj 的 Open SSH 的 SSH Exec channel

标签 java ssh exec jsch sshd

我在使用以下任何库 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 0SSH_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/

相关文章:

linux - 通过 SSH 远程运行脚本

java - 如何从 Java 使用 Telnet

php - 使用 php exec() 将用户输入回显到终端;

c - fork() 子执行命令输出奇怪

java - 嵌入式osgi框架,如何调用服务函数?

java - 如何使字符串的字节大小相同

Java.util.NoSuchElementException

java - org.hibernate.AnnotationException : Unknown mappedBy in: mdl. Complaint.jobDone,引用属性未知 : mdl. JobDone.jobDone

linux - 使用端口转发 SSH 连接到本地服务器?

linux - 显示来自远程 linux 服务器的统计信息