Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send channel request from SSH server making `ssh_channel_accept_forward()` return on SSH client?

I use the client code for direct and reverse port forwarding from the official tutorials: http://api.libssh.org/master/libssh_tutor_forwarding.html

This code works perfectly when connecting the client to an OpenSSH server on Ubuntu 16.10, i.e., direct and reverse port forwarding is achieved.

However, consider the client code for reverse port forwarding (web_server()), which makes use of the following calls:

ssh_channel_listen_forward()

ssh_channel_accept_forward()

Using my own libssh server, the problem is that the client times out in the call to ssh_channel_accept_forward() with the following error message:

"No channel request of this type from server"

That is, the error message is printed by the following client code after waiting 1 minute:

  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;
  }

How do I construct a channel request on the server side, such that the client doesn't time out in ssh_channel_forward_accept() and a new forward channel is created? I've tried most of the API functions without luck...

Is there a specific API function for sending such channel request? If not, how do I accomplish the task of requesting the channel?

My code on the server side goes along the following lines, where the ssh_channel_listen_forward() request is captured by the following callback function:

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");
    }
}

However, as stated, the server is not making the client accept a new forward channel in the call to ssh_channel_accept_forward().

Any ideas?

like image 989
Shuzheng Avatar asked Aug 04 '17 09:08

Shuzheng


People also ask

What is reverse SSH port forwarding?

Remote port forwarding (reverse tunneling) Also often called SSH reverse tunneling, remote port forwarding redirects the remote server's port to the localhost's port. When remote port forwarding is used, at first, the client connects to the server with SSH.

Does SSH require port forwarding?

You will need to configure port forwarding on your router, and you will also need to specify the ssh port that will be allowed through the router, and then the IP address of the computer that is going to be receiving Port 22 based connections from outside the network.

How do I enable SSH tunneling?

Set up SSH Tunneling in WindowsLaunch Putty and enter the SSH server IP Address in the Host name (or IP address) field. Under the Connection menu, expand SSH and select Tunnels . Check the Local radio button to setup local, Remote for remote, and Dynamic for dynamic port forwarding.

What is a reverse SSH tunnel?

Reverse SSH Tunneling enables you to access remote machines behind NAT. For instance, you can access your office from home. Therefore, Reverse SSH Tunneling is a technique that enables you to SSH your Linux-based system that doesn't have a public IP address.


1 Answers

Your server code don't send request to open reverse tunnel to client side. This channel: session_data->channel created not bound at server side. You can try to connect it, but in this case you should set subtype "forwarded-tcpip" manually.

This request: ssh_message_channel_request_channel(message); returns NULL because port forwarding request has no channel field.

For initiation of reverse tunnel, that you can accept with ssh_channel_accept_forward() - you should connect to the bound listening port at the server side. (port number from ssh_channel_listen_forward() you know).

P.S. And don't use server callbacks to accept this request. Libssh still filter this message subtype from callback processing.

P.P.S. Read RFC (https://www.rfc-editor.org/rfc/rfc4254#page-7) and library source. It's completely readable and not that big

like image 83
Anton Ornatsky Avatar answered Oct 21 '22 00:10

Anton Ornatsky