Route Any Linux Process Through a Proxy Without Touching Its Code
You've got a binary that needs to reach the internet through a SOCKS5 proxy, but it doesn't respect HTTP_PROXY, and you don't have the source code to patch it. Maybe it's a statically linked Go tool, or a vendor blob you can't rebuild. That's the exact gap graftcp fills: it redirects TCP connections from any Linux process to SOCKS5 or HTTP proxies, no LD_PRELOAD required.
What It Does
graftcp traces socket syscalls with ptrace(2) and redirects outgoing TCP connections to the proxy of your choice. Because it works at the syscall level rather than through dynamic linking tricks, it can trace statically linked binaries too—including most Go programs, which is where tools like tsocks and proxychains tend to fall over.
The project recently consolidated its runtime. The old graftcp + graftcp-local split is gone, merged into a single command. graftcp is now the primary entrypoint, and mgraftcp sticks around as a compatibility alias. There's no standalone local daemon, no FIFO, no /proc scanning, and no netlink socket reverse lookup. Instead, each intercepted connection gets a unique loopback token IP, and the embedded local proxy resolves that token in-process. Beyond plain TCP, it can also redirect UDP/53 DNS queries to an embedded DNS-over-TCP forwarder and proxy generic UDP through SOCKS5 UDP ASSOCIATE (or direct UDP) when you explicitly enable it.
Why It's Cool
It handles the binaries other tools can't. The LD_PRELOAD approach that tsocks and proxychains rely on simply doesn't work on statically linked executables. Since graftcp traces syscalls, a statically linked Go binary—the kind that's increasingly common in modern tooling—gets traced just like anything else. That alone makes it worth knowing about.
The architecture got simpler, not more complex. Merging the daemon into a single command removes a whole category of setup friction. No separate process to start, no socket path to configure between components. You run one binary and it handles interception and proxying internally via the loopback token scheme.
You get real control over what gets proxied. The --whiteip-file and --blackip-file options let you decide which destinations get redirected and which connect directly. The --select_proxy_mode flag gives you auto, random, only_http_proxy, only_socks5, or direct—useful when you want to force everything through one proxy type or deliberately bypass proxying for specific traffic.
Unix socket proxies are supported. You can point --socks5 at something like unix:/path/tor.sock rather than a TCP address, which is handy if you're running Tor locally and don't want to expose a listening port.
DNS and UDP aren't afterthoughts. With --enable-dns and a --dns-server, UDP/53 queries get forwarded over TCP to an embedded resolver, which helps when your network blocks plain DNS. Generic UDP proxying is available too, though it's opt-in rather than default.
How to Try It
You'll need Go and a C toolchain on a Linux machine. Clone and build:
git clone https://github.com/hmgle/graftcp.git
cd graftcp
make
The binary lands at local/graftcp (with local/mgraftcp as an alias). Install system-wide with sudo make install.
Then run whatever command you like through a proxy:
./local/graftcp --socks5 127.0.0.1:1080 curl https://example.com
./local/graftcp --http_proxy 127.0.0.1:8080 git clone https://github.com/hmgle/graftcp.git
./local/graftcp --enable-dns --dns-server 1.1.1.1:53 curl https://example.com
You can even drop into an interactive shell with the proxy active—the README shows passing bash --rcfile to set a custom prompt, which is a nice touch for longer sessions. Configuration can come from a file via --config or from a few default locations next to the binary or in your XDG config directory, so you don't have to retype flags every time.
Full details and the complete option list are in the repository.
Final Thoughts
graftcp is a focused tool that solves one specific problem well: getting traffic from stubborn binaries through a proxy. If you work with statically linked applications, vendor software, or anything that ignores standard proxy environment variables, it's a practical addition to your toolbox. The merged single-command design also means less setup overhead than the older split-runtime approach. It won't help you on non-Linux systems, and generic UDP proxying depends on your SOCKS5 server supporting it—but for the core TCP redirection job, it does exactly what it says.
Follow @githubprojects for more developer tools and open source projects.