jpillora / chisel

A fast TCP/UDP tunnel over HTTP
MIT License
13.22k stars 1.37k forks source link

Non graceful closing of remote connection (reverse port forwarding) #535

Open liojacqs opened 1 week ago

liojacqs commented 1 week ago

(Note: not tried on a non-reverse scenario, but most probably the same)

In a reverse port forwarding scenario like: R:localhost:9221:remote:9100/tcp We are having an issue with a server which:

When using netcat to send a file to remote:9100 directly, like this: nc -N remote 9100 < file Then netcat is sending the FIN packet right after finishing to send the file. But the connection does not drop instantly, as netcat is waiting for the remote end FIN packet, which is actually sent AFTER the remote has sent some data. In this scenario the output looks like:

$ nc -v -N 10.12.14.16 9100 < file
Connection to 10.12.14.16 9100 port [tcp/*] succeeded!
0123456
$

And as the server was able to send back data, it's fine.

Doing the same thing through chisel, the output looks like:

$ nc -v -N localhost 9221 < file
Connection to localhost 9221 port [tcp/*] succeeded!
$

Feedback from the remote end is lost, and the server needs some manual operation because it's probably badly written, or didn't appreciate being censored...

What's happeining is the connection is closed directly on the input proxy side, which has no clue about how the remote end would behave, leaving no chance for the remote to delay it a little bit like in a direct TCP connection.

I don't know about the feasibility of this, but it would be nice, when a local or remote end is requesting to close the connection, not to close the connection on this side, but gracefully on the other side of the tunnel first, then only on the requesting side.

That way we would have no issue with such faulty servers...

liojacqs commented 6 days ago

Issue can be reproduced with the attached code as remote end, and netcat:

fake_server.go.zip