[Bug 2147] New: OpenSSH remote forwarding of dynamic ports doesn't work when you create more than one

bugzilla-daemon at mindrot.org bugzilla-daemon at mindrot.org
Sun Sep 1 03:06:21 EST 2013


https://bugzilla.mindrot.org/show_bug.cgi?id=2147

            Bug ID: 2147
           Summary: OpenSSH remote forwarding of dynamic ports doesn't
                    work when you create more than one
           Product: Portable OpenSSH
           Version: -current
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P5
         Component: sshd
          Assignee: unassigned-bugs at mindrot.org
          Reporter: ronf at timeheart.net

Created attachment 2330
  --> https://bugzilla.mindrot.org/attachment.cgi?id=2330&action=edit
Patch for remote forwarding of dynamic ports

I recently ran across a problem with remote port forwarding in OpenSSH
when trying to use dynamic ports. While it is possible to use OpenSSH
to request a dynamic port and the OpenSSH sshd handles it just fine,
the OpenSSH client gets confused when multiple ports are opened this
way, due to the information passed in the "forwarded-tcpip"
SSH_MSG_CHANNEL_OPEN message which is sent back to the client when
connections are opened. To illustrate this problem, I tried the
following with OpenSSH 6.2p1:

ssh -v -R 0:localhost:80 -R 0:localhost:81 localhost

In the debug output, I saw the lines:

debug1: remote forward success for: listen 0, connect localhost:80
Allocated port 60013 for remote forward to localhost:80
debug1: Updating allowed port 60013 for forwarding to host localhost
port 80
debug1: remote forward success for: listen 0, connect localhost:81
Allocated port 60014 for remote forward to localhost:81
debug1: Updating allowed port 60014 for forwarding to host localhost
port 81

So far, so good!

Connecting to port 60013 worked fine, causing the client to connect to
localhost:80 as requested, with the following debug output:

debug1: client_input_channel_open: ctype forwarded-tcpip rchan 5 win
2097152 max 32768
debug1: client_request_forwarded_tcpip: listen localhost port 0,
originator ::1 port 60153
debug1: connect_next: host localhost ([::1]:80) in progress, fd=9
debug1: channel 1: new [::1]
debug1: confirm forwarded-tcpip
debug1: channel 1: connected to localhost port 80

However, connecting to port 60014 did not work as expected. In that
case, I saw:

debug1: client_input_channel_open: ctype forwarded-tcpip rchan 5 win
2097152 max 32768
debug1: client_request_forwarded_tcpip: listen localhost port 0,
originator ::1 port 60182
debug1: connect_next: host localhost ([::1]:80) in progress, fd=9
debug1: channel 1: new [::1]
debug1: confirm forwarded-tcpip
debug1: channel 1: connected to localhost port 80

Note that even though this was to the second listening port I set up,
the connection was locally forwarded to port 80. The reason is that the
SSH_MSG_CHANNEL_OPEN of type "forwarded-tcpip" from sshd reported the
destination host & port as "localhost" port 0 for both the 60013 and
60014 connections, instead of reporting the actual listening port. The
client seems to expect the 0 value here and does the right thing when
you only have one dynamic listening port, but this breaks in the case
where there are multiple, since there's nothing in the
SSH_MSG_CHANNEL_OPEN which distinguishes between the two dynamic
listeners. RFC 4254 is not completely clear on what is expected in the
message. It says:

  When a connection comes to a port for which remote forwarding has
  been requested, a channel is opened to forward the port to the other
  side.

     byte      SSH_MSG_CHANNEL_OPEN
     string    "forwarded-tcpip"
     uint32    sender channel
     uint32    initial window size
     uint32    maximum packet size
     string    address that was connected
     uint32    port that was connected
     string    originator IP address
     uint32    originator port

I was expecting "port that was connected" in this message to be the
dynamically allocated port so that it would always be a unique value,
but this is not the case (at least with OpenSSH's sshd). Instead, it
always seems to be the "port number to bind" value passed in the
original SSH_MSG_GLOBAL_REQUEST "tcpip-forward" message (which is 0
since we're asking for a dynamic port).

I did an experiment and was pleasantly surprised to find that the
OpenSSH client does work correctly when the real port number is
returned by the server. So, it won't break existing clients out there
if this is fixed. Both the "address that was connected" and the "port
that was connected" can be the real address and port rather than the
values passed in the original SSH_MSG_GLOBAL_REQUEST and everything
works fine.

I have attached a patch which can be applied to OpenSSH 6.2p2 which
fixes this problem. I would appreciate it if you would consider
including it in a future release.

One minor ugliness here is that I had to use "get_sock_port()" instead
of get_local_port(), as get_local_port() doesn't take a socket as an
argument the way get_local_ipaddr() does and there's no equivalent
function under another name. Cleaning this up would impact other files,
though, and I wanted to keep the diff as clean as possible.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.


More information about the openssh-bugs mailing list