【问题标题】:Send channel request from SSH server making `ssh_channel_accept_forward()` return on SSH client?从 SSH 服务器发送通道请求,使 SSH 客户端返回“ssh_channel_accept_forward()”?
【发布时间】:2018-01-12 04:02:39
【问题描述】:

我使用官方教程中的客户端代码进行直接和反向端口转发:http://api.libssh.org/master/libssh_tutor_forwarding.html

此代码在 Ubuntu 16.10 上将客户端连接到 OpenSSH 服务器时完美运行,即实现了直接和反向端口转发。

但是,请考虑用于反向端口转发 (web_server()) 的客户端代码,它使用以下调用:

ssh_channel_listen_forward()

ssh_channel_accept_forward()

使用我自己的 libssh 服务器,问题是客户端在调用 ssh_channel_accept_forward() 时超时并显示以下错误消息:

"No channel request of this type from server"

即等待1分钟后由如下客户端代码打印错误信息:

  channel = ssh_channel_accept_forward(session, 60000, &port);
  if (channel == NULL)
  {
    fprintf(stderr, "Error waiting for incoming connection: %s\n",
            ssh_get_error(session));
    return SSH_ERROR;
  }

如何在服务器端构造通道请求,使客户端不会在ssh_channel_forward_accept() 中超时并创建新的转发通道?我已经尝试了大多数 API 函数,但没有运气......

是否有特定的 API 函数用于发送此类频道请求?如果没有,如何完成请求频道的任务?

我在服务器端的代码如下所示,ssh_channel_listen_forward() 请求由以下回调函数捕获:

void global_request(ssh_session session, ssh_message message, void *userdata) {
    #ifdef DEBUG
    printf("[Debug] global_request()\n");
    #endif
    struct session_data_struct *session_data = (struct session_data_struct*) userdata;
    ssh_message_global_request_reply_success(message, 8080);
    const char *addr = ssh_message_global_request_address(message);
    int port = ssh_message_global_request_port(message);
    printf("Received global request: %s:%d\n", addr, port);
    session_data->channel = ssh_channel_new(session);
    ssh_channel ch = ssh_message_channel_request_channel(message);
    if (ssh_channel_is_open(session_data->channel)) {
        printf("Channel is open!\n");
    }
}

但是,如前所述,服务器没有让客户端在对ssh_channel_accept_forward() 的调用中接受新的转发通道。

有什么想法吗?

【问题讨论】:

  • + 1 用于询问实际上与编程或开发有关的 SSH 问题

标签: c linux networking network-programming libssh


【解决方案1】:

您的服务器代码不会向客户端发送打开反向隧道的请求。 此频道:session_data->channel 创建未绑定在服务器端。您可以尝试连接它,但在这种情况下您应该手动设置子类型"forwarded-tcpip"

此请求:ssh_message_channel_request_channel(message); 返回 NULL 因为端口转发请求没有通道字段。

要启动反向隧道,您可以使用ssh_channel_accept_forward() 接受 - 您应该连接到服务器端的绑定侦听端口。 (端口号来自ssh_channel_listen_forward() 你知道的)。

附:并且不要使用服务器回调来接受这个请求。 Libssh 仍然会从回调处理中过滤掉这个消息子类型。

P.P.S.阅读 RFC (https://www.rfc-editor.org/rfc/rfc4254#page-7) 和库源。它完全可读,而且不是那么大

【讨论】:

  • 我仍然有点不确定该怎么做。你能举一个启动反向隧道的例子吗?
  • 为了测试,您可以简单地使用 telnet 连接到转发端口。或者在服务器端创建一个套接字并将其连接到本地主机的转发端口。
  • 您能否更简单地描述一下服务器端收到转发监听消息后应该做什么?我是新手,所以我需要一些小步骤。顺便说一句,谢谢您的回答。
  • 要手动设置子类型,您必须使用内部库函数,如 rc = channel_open(channel, "direct-tcpip", CHANNEL_INITIAL_WINDOW, CHANNEL_MAX_PACKET, payload);,但如果不完全了解您在做什么,不建议这样做。
  • 在收到转发监听消息后,服务器应该回复byte SSH_MSG_REQUEST_SUCCESS uint32 port that was bound on the server 并等待绑定端口上的传入连接。当连接发生时,它应该请求类型为:byte SSH_MSG_CHANNEL_OPEN string "forwarded-tcpip" 的新通道并将数据从绑定端口传输到该通道并返回。
猜你喜欢
  • 2021-01-23
  • 1970-01-01
  • 2018-08-17
  • 1970-01-01
  • 2013-01-25
  • 1970-01-01
  • 2020-07-15
  • 2015-06-15
  • 2020-03-22
相关资源
最近更新 更多