Trouble with port forwarding over proxy control socket
Damien Miller
djm at mindrot.org
Mon Dec 22 15:21:44 AEDT 2025
On Sun, 21 Dec 2025, ding wrote:
> Hi,
>
> This is attempt 3 at sending this email, apologies to the admins.
>
> I'm working on support for connecting to a control socket in the Go SSH
> package
> (a continuation of https://github.com/golang/crypto/pull/205), but I'm having
> trouble getting port forwarding to work correctly.
>
> As far as I can tell the comment at
> https://github.com/openssh/openssh-portable/blob/b652322cdc5e94f059b37a8fb87e44ccb1cdff33/channels.c#L3169
> suggests that it *should* work, but looking through the code I can't see how.
> The problem I'm hitting is that the response to the global "tcpip-forward"
> request never gets forwarded downstream back over the control socket.
>
> I can only assume that anyone currently using this is just not waiting for the
> response? If the port is known ahead of time and you don't care about handling
> a failure response then I guess you can just ignore it? It seems like it
> definitely breaks the ability to use port 0 for remote forwarding though as
> there's no way to find out which port was chosen on the server.
>
> This seems to break with the OpenSSH client with `-O proxy` as well. Running
> `ssh -R 0:127.0.0.1:<localport> -N <host>` allows connecting from a random
> port
> on the server to the local port (and the log shows "Allocated port <...> for
> remote forward to 127.0.0.1:<localport>"). Doing the same through a control
> socket with `ssh -O proxy -R 0:127.0.0.1:<localport> -N <host>` doesn't output
> the port to log, finding the port on the server with `lsof` and writing to it
> results in the control master process logging "WARNING: Server requests
> forwarding for unknown listen_port <...>".
>
> Building "ssh" with the attached patch fixes the issue for me (at least for
> the
> Go implementation), but including "clientloop.h" in "channels.c" seems wrong,
> and it breaks a bunch of build targets. There's a comment above
> `struct global_confirm` suggesting that it should be moved elsewhere, so I
> assume that problem can be solved by moving it and the related functions to a
> more accessible place. There could also be bigger technical problems with this
> approach that I'm not aware of.
>
> Before putting more effort into this I wanted to check if anyone had any
> thoughts or better ideas on what the problem might be, or how to fix it?
AFAIK your analysis is 100% correct, and thanks for looking so deeply
into this.
I don't have a great idea on how to fix this yet either, though perhaps
the queue of pending global confirms could move from clientloop.c to
channels.c, with the actual TAILQ anchor in struct ssh_channels.
This wouldn't be a layering violation because 1) global confirms *are*
channels-related, 2) both ssh and sshd could conceivably issue and
therefore want to track them (though sshd doesn't ATM) and 3) I think
you've demonstrated that the mux proxy code needs this facility to
function properly.
Anyway that's one possible approach...
-d
More information about the openssh-unix-dev
mailing list