[![Crates.io](https://img.shields.io/crates/v/cproxy)](https://crates.io/crates/cproxy) [![CI](https://github.com/NOBLES5E/cproxy/actions/workflows/build.yml/badge.svg)](https://github.com/NOBLES5E/cproxy/actions/workflows/build.yml) ![Crates.io](https://img.shields.io/crates/d/cproxy) ![Crates.io](https://img.shields.io/crates/l/cproxy)
`cproxy` can redirect TCP and UDP traffic made by a program to a proxy, without requiring the program supporting a
proxy.
What you can achieve with `cproxy`: All the things listed on for
example [V2Ray Guide](https://guide.v2fly.org/en_US/app/app.html), including advanced configurations like reverse proxy
for NAT traversal, and you can **apply different proxy on different applications**.
Compared to many existing complicated transparent proxy setup, `cproxy` usage is as easy as `proxychains`, but
unlike `proxychains`, it works on any program (including static linked Go programs) and redirects DNS requests.
Note: The proxy used by `cproxy` should be a transparent proxy port (such as V2Ray's `dokodemo-door` inbound and
shadowsocks `ss-redir`). A good news is that even if you only have a SOCKS5 or HTTP proxy, there are tools that can
convert it to a transparent proxy for you (for example, [transocks](https://github.com/cybozu-go/transocks)
, [ipt2socks](https://github.com/zfl9/ipt2socks) and [ip2socks-go](https://github.com/lcdbin/ip2socks-go)).
## Installation
You can install by downloading the binary from the [release page](https://github.com/NOBLES5E/cproxy/releases) or
install with `cargo`:
```
cargo install cproxy
```
Here's a oneliner that downloads the latest release and put it in your `/usr/local/bin/`:
```
curl -s https://api.github.com/repos/NOBLES5E/cproxy/releases/latest | grep "browser_download_url.*x86_64-unknown-linux-musl.zip" | cut -d : -f 2,3 | tr -d \" | wget -qi - -O /tmp/cproxy.zip && unzip -j /tmp/cproxy.zip cproxy -d /tmp && sudo mv /tmp/cproxy /usr/local/bin/ && sudo chmod +x /usr/local/bin/cproxy && rm /tmp/cproxy.zip
```
## Usage
### Simple usage: just like `proxychains`
You can launch a new program with `cproxy` with:
```
sudo cproxy --port -- --arg1 --arg2 ...
```
All TCP connections requests will be proxied. If your local transparent proxy support DNS address overriding, you can
also redirect DNS traffic with `--redirect-dns`:
```
sudo cproxy --port --redirect-dns -- --arg1 --arg2 ...
```
For an example setup, see [wiki](https://github.com/NOBLES5E/cproxy/wiki/Example-setup-with-V2Ray).
### Simple usage: use iptables tproxy
If your system support `tproxy`, you can use `tproxy` with `--mode tproxy`:
```bash
sudo cproxy --port --mode tproxy -- --arg1 --arg2 ...
# or for existing process
sudo cproxy --port --mode tproxy --pid
```
With `--mode tproxy`, there are several differences:
* All UDP traffic are proxied instead of only DNS UDP traffic to port 53.
* Your V2Ray or shadowsocks service should have `tproxy` enabled on the inbound port. For V2Ray, you
need `"tproxy": "tproxy"` as
in [V2Ray Documentation](https://www.v2ray.com/en/configuration/transport.html#sockoptobject). For shadowsocks, you
need `-u` as shown in [shadowsocks manpage](http://manpages.org/ss-redir).
An example setup can be found [here](https://github.com/NOBLES5E/cproxy/wiki/Example-setup-with-V2Ray).
Note that when you are using the `tproxy` mode, you can override the DNS server address
with `cproxy --mode tproxy --override-dns ...`. This is useful when you want to use a different
DNS server for a specific application.
### Advanced usage: proxy an existing process
With `cproxy`, you can even proxy an existing process. This is very handy when you want to proxy existing system
services such as `docker`. To do this, just run
```
sudo cproxy --port --pid
```
The target process will be proxied as long as this `cproxy` command is running. You can press Ctrl-C to stop proxying.
### Advanced usage: debug a program's network activity with iptables LOG target
With `cproxy`, you can easily debug a program's traffic in netfilter. Just run the program with
```bash
sudo cproxy --mode trace
```
You will be able to see log in `dmesg`. Note that this requires a recent enough kernel and iptables.
## How does it work?
`cproxy` creates a unique `cgroup` for the proxied program, and redirect its traffic with packet rules.
## Limitations
* `cproxy` requires root access to modify `cgroup`.
* Currently only tested on Linux.
## Similar projects
There are some awesome existing work:
* [graftcp](https://github.com/hmgle/graftcp): work on most programs, but cannot proxy UDP (such as DNS)
requests. `graftcp` also has performance hit on the underlying program, since it uses `ptrace`.
* [proxychains](https://github.com/haad/proxychains): easy to use, but not working on static linked programs (such as Go
programs).
* [proxychains-ng](https://github.com/rofl0r/proxychains-ng): similar to proxychains.
* [cgproxy](https://github.com/springzfx/cgproxy): `cgproxy` also uses cgroup to do transparent proxy, and the idea is
similar to `cproxy`'s. There are some differences in UX and system requirements:
* `cgproxy` requires system `cgroup` v2 support, while `cproxy` works with both v1 and v2.
* `cgproxy` requires a background daemon process `cgproxyd` running, while `cproxy` does not.
* `cgproxy` requires `tproxy`, which is optional in `cproxy`.
* `cgproxy` can be used to do global proxy, while `cproxy` does not intended to support global proxy.