hmgle / graftcp

A flexible tool for redirecting a given program's TCP traffic to SOCKS5 or HTTP proxy.
GNU General Public License v3.0
2.07k stars 174 forks source link

Why not merge local and graftcp? #33

Closed chaoqing closed 3 years ago

chaoqing commented 3 years ago

May I ask whether there is any concern on merging the graftcp-local and graftcp into one single binary?

It seems strange to me if I just want to proxy one command but need to open another terminal for local to running.

If it is already designed behavior which make merging in framework level a hard task, we can do it the simple way by spawn another thread inside go for local. Is this a valid solution?

hmgle commented 3 years ago

Good question.

There are two points to explain:

  1. ptrace can only modify the memory of the traced process, but cannot expand this part of the memory
  2. The data size of SOCKS5 or HTTP proxy traffic will inevitably be larger than the raw TCP traffic. In other words, the memory requirement of the buffer that caches the proxy data is more than the raw TCP data.

Based on the above two points, we have no way to directly modify the internal traffic data of the traced process and convert it into SOCKS5 or HTTP proxy traffice data. The data must be taken out and convert to the proxy traffice outside the traced process.

The main job of graftcp-local is to receive the raw traffic data from the traced process and convert it to the proxy traffic data, so it contains a TCP server.

It is possible to merging the the graftcp-local and graftcp into one single binary, but this would make graftcp much more complex and difficult to implement. In order to avoid the TCP port conflicts caused by starting multiple instances, each instance must listen a different TCP port.

50 traced processes, one TCP server is simpler than 50 traced processes, 50 TCP server.

If you use graftcp often, you can alse add the graftcp-local service to systemd, to avoid opening another terminal for local to running every time:

make install_systemd
chaoqing commented 3 years ago

Thanks for the explanation and I expected the problem in merging in framework level. That's why I proposed another much more hacker way. We can first use the same method as busybox to merge two binary into one (which I have done in other project) and then open one goroutine for local server, another one for os/exec the graftcp command. We just need be sure to handle the input/output stream correctly.

The port conflicts should not be a big problem as we can still use the client mode without starting another proxy if like --grafttcp-proxy specified.

I can try this approach and make a pull request if success.

hmgle commented 3 years ago

Interesting. PR welcome!

hmgle commented 3 years ago

v0.4.0 has been released, a new command mgraftcp has been added to support this feature.