tun2proxy

repository·master·Indexed 23 days ago

https://github.com/tun2proxy/tun2proxy

A tool that creates a tunnel interface to route all system traffic through an HTTP or SOCKS proxy. It supports Linux, Android, macOS, iOS, and Windows. Key features include automated system routing setup via the --setup flag, multiple DNS handling strategies (virtual, direct, over-tcp), and support for per-app routing on Android 10+. The tool can be installed via binary or Rust's cargo, and is available for use within Docker containers using network namespace sharing.

Tokens
7.8K
Snippets
14
Records
47
Agent score
80%

What's inside tun2proxy

  1. Enable per-app routing on Android using Session Info

    master

    On Android 10+, you can enable per-app traffic routing by embedding session information (protocol, source IP, and source port) into the SOCKS5 username field. To do this, append +info to your username in the proxy URL.

    The proxy server will receive the username in the following format: original_username|protocol|src_ip|src_port

    Important: The original username must not contain the | character, as it is used as a literal field delimiter. If the username contains |, the server-side parser may fail or become ambiguous.

  2. Understand tun2proxy DNS handling strategies

    master

    The --dns option controls how DNS queries are handled. The available strategies are:

    • virtual (Default behavior for virtual DNS): When a DNS packet to port 53 is detected, an IP address from a pool (default 198.18.0.0/15) is chosen and mapped to the query name. Connections to this IP range will supply the proxy with the mapped query name instead of the IP. This allows DNS over TCP/UDP to work even if the proxy only supports TCP.
    • direct: DNS queries are handled directly. You may need an external tool like dnsproxy to handle upstream communication.
    • over-tcp: DNS queries are sent over TCP.
  3. Use tun2proxy with Docker

    master

    You can use tun2proxy as a proxy for other Docker containers by running it in a container and sharing its network namespace with worker containers.

    1. Build the image

    You can build a statically linked image (based on musl) or images based on Ubuntu or Alpine:

    # Build static image
    docker buildx build -t tun2proxy .
    
    # Build Ubuntu-based image
    docker buildx build -t tun2proxy --target tun2proxy-ubuntu .
    
    # Build Alpine-based image
    docker buildx build -t tun2proxy --target tun2proxy-alpine .

    2. Run the tun2proxy container

    Start the container with necessary permissions (NET_ADMIN) and access to the TUN device:

    docker run -d \
    	-v /dev/net/tun:/dev/net/tun \
    	--sysctl net.ipv6.conf.default.disable_ipv6=0 \
    	--cap-add NET_ADMIN \
    	--name tun2proxy \
    tun2proxy --proxy proto://[username[:password]@]host:port

    3. Connect worker containers

    To route a worker container's traffic through tun2proxy, use the --network flag to join the tun2proxy container's network namespace:

    docker run -it \
    	--network "container:tun2proxy" \
    	ubuntu:latest
    docker buildx build -t tun2proxy .
    
    docker run -d \
    	-v /dev/net/tun:/dev/net/tun \
    	--sysctl net.ipv6.conf.default.disable_ipv6=0 \
    	--cap-add NET_ADMIN \
    	--name tun2proxy \
    tun2proxy --proxy proto://[username[:password]@]host:port
    
    docker run -it \
    	--network "container:tun2proxy" \
    	ubuntu:latest
  4. Automated system setup with --setup

    master

    The --setup flag allows tun2proxy to automatically configure your system routing to direct all traffic through the specified proxy. This requires root privileges.

    On Linux, this performs routing configuration and uses a bind mount to overlay /etc/resolv.conf.

    Note on non-global IPs: If your proxy is a non-global IP (e.g., a local tunneling tool), you must provide the public IP of the actual exit server using the --bypass <IP/CIDR> flag to prevent routing loops.

    sudo ./target/release/tun2proxy-bin --setup --proxy "socks5://1.2.3.4:1080"
  5. Install Rust build tools for iOS development

    master

    Before building the iOS xcframework, ensure your environment has the necessary Rust and Apple development tools installed:

    1. Xcode Command Line Tools: Required for Apple platform compilation.
    2. Rust Programming Language: The core build toolchain.
    3. iOS Target Support: You must add specific targets for physical devices and simulators.
    4. cbindgen: A tool used to generate C bindings for Rust code.
    xcode-select --install
    curl https://sh.rustup.rs -sSf | sh
    rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios
    cargo install cbindgen
  6. Build the iOS/macOS xcframework

    master

    To build the tun2proxy xcframework for iOS and macOS, use the provided build script. The resulting framework will be output to ./tun2proxy.xcframework.

    Full Build

    Run the full build script from your shell (zsh or bash):

    cd tun2proxy
    ./build-apple.sh

    Optimized Build (Faster)

    If you only need the aarch64-apple-ios target (for physical iOS devices), you can use specific scripts to save build time:

    • For a debug build: ./build-aarch64-apple-ios-debug.sh
    • For a release build: ./build-aarch64-apple-ios.sh
  7. Manual system setup for Linux

    master

    To manually route traffic through a tunnel interface without running tun2proxy as root, follow these steps:

    1. Create and enable a TUN interface:
      sudo ip tuntap add name tun0 mode tun
      sudo ip link set tun0 up
    
    2. **Prevent routing loops:** Add a route to your proxy server that mimics the default route (replace `$BYPASS_IP` with your proxy's public IP):
       ```shell
    sudo ip route add "$BYPASS_IP" $(ip route | grep '^default' | cut -d ' ' -f 2-)
    1. Route traffic through the tunnel:
      sudo ip route add 128.0.0.0/1 dev tun0
      sudo ip route add 0.0.0.0/1 dev tun0

    For IPv6:

    sudo ip route add ::/1 dev tun0 sudo ip route add 8000::/1 dev tun0

    
    4. **Configure DNS:**
       ```shell
    sudo sh -c "echo nameserver 198.18.0.1 > /etc/resolv.conf"
    1. Run tun2proxy:
      ./target/release/tun2proxy-bin --tun tun0 --proxy "$PROXY_TYPE://$PROXY_IP:$PROXY_PORT"
    
    **Cleanup:** To remove the routes and interface, delete the tunnel device:
    ```shell
    sudo ip link del tun0
  8. Install tun2proxy from binary or source

    master

    Install from binary

    Download the binary from the releases page and add it to your PATH.

    To verify the authenticity of the build files, you can use the GitHub CLI:

    gh attestation verify <*.zip file> --owner tun2proxy

    Install from source

    If you have the Rust toolchain installed, run:

    cargo install tun2proxy

    Note for Windows users: You must copy the wintun DLL to the same directory as the binary (e.g., %USERPROFILE%\.cargo\bin).

  9. Use DNS strategies in tun2proxy

    master

    tun2proxy supports three DNS handling strategies via the --dns flag:

    1. direct (Default): Does not handle DNS internally; relies on DNS server bypassing.
    2. virtual: Uses a virtual DNS server to handle queries (also known as Fake-IP mode). This uses the --virtual-dns-pool to assign IPs.
    3. over-tcp: Sends DNS queries to the DNS server over TCP.
  10. Understand the UDP Gateway (UDPGW) packet format

    master

    The UDP Gateway protocol uses a specific packet format to encapsulate UDP traffic. The format is based on SOCKS5 but includes additional fields for flags and connection IDs. All multi-byte fields are in big-endian byte order.

    Packet Structure

    FieldSizeDescription
    LEN2 bytesLength of the packet, excluding the length field itself
    FLAGS1 byteIndicates packet type (see UdpFlag)
    CONN_ID2 bytesUnique connection ID for the packet
    ATYP1 byteAddress Type (0x01: IPv4, 0x04: IPv6, 0x03: Domain Name)
    DST.ADDRVariableDestination Address (format depends on ATYP)
    DST.PORT2 bytesDestination Port
    DATAVariableThe actual payload data

    Flag Definitions (UdpFlag)

    • 0x01 (KEEPALIVE): Keepalive packet without address and data.
    • 0x20 (ERR): Error packet without address and data.
    • 0x02 (DATA): Data packet containing address and data.
  11. Run tun2proxy in unprivileged mode using unshare (Linux)

    master

    On Linux, you can run tun2proxy in an unprivileged mode using the --unshare flag. This uses the unshare(1) utility to create new user, network, mount, and PID namespaces.

    Requirements:

    • The unshare executable must be in your PATH (e.g., via apt install util-linux).
    • If you need to run a process that requires root-like capabilities (like openvpn) within this environment, use the following pattern: tun2proxy-bin --unshare --setup [...] -- openvpn --config [...]

    Running applications in the namespace: Once the proxy is running in unprivileged mode, you can run other processes (like a Flatpak app) inside the same namespace using nsenter: nsenter --preserve-credentials --user --net --mount --target <unshare_pid> /bin/sh