--- title: 'Xray Subnet Mimicry (10.0.0.0/8)' description: 'Building a distributed private network with Xray-core and reverse tunneling' createdDate: 2026-03-20 tags: ['networking', 'guides', 'xray'] --- > **EDUCATIONAL PURPOSES ONLY** > This project is designed as a technical demonstration of Xray-core's routing capabilities and private subnet mimicry. It is NOT intended for restriction evasion or illegal activities. Use this knowledge responsibly and in compliance with your local laws. This guide describes how to deploy a private, distributed communications infrastructure across distinct remote servers using a contiguous `10.0.0.0/8` private subnet mimicked via **Xray-core**, **TPROXY**, and **VLESS reverse tunneling**. --- ## Technical Deep-Dive & Architecture ### The Virtual Subnet Concept We are constructing a Layer 3 "Flat Network" over the public internet. Each server node acts as an authoritative gateway for its own `/16` segment within the `10.0.0.0/8` private address space: - **Server A (Hub / Portal)**: Owns `10.1.0.0/16` - **Server B (Spoke / Bridge)**: Owns `10.2.0.0/16` - **Server C (Spoke / Bridge)**: Owns `10.3.0.0/16` This setup enables seamless inter-node communication as if all servers and hosted containers resided on the same local physical network. ### The Science of Interception (TPROXY) Unlike `REDIRECT`, which only supports TCP and modifies packet destination IP headers to match the proxy, **TPROXY** (Transparent Proxy) intercepts both TCP and UDP packets while preserving original source and destination IP headers. - **Marking**: When a packet destined for `10.x.x.x` enters the `PREROUTING` or `OUTPUT` iptables chain, the Mangle table marks it with `0x1`. - **Preservation**: Xray's `tunnel` inbound listens with `"sockopt": { "tproxy": "tproxy" }`, allowing it to read the original destination IP from socket metadata and route packets transparently. ### Policy Routing (Table 100) Firewall marks alone do not alter routing paths; standard Linux routing tables ignore firewall marks unless directed by **Policy Routing**: 1. **The Rule (`ip rule`)**: `ip rule add fwmark 0x1 lookup 100 priority 100` tells the kernel to route any packet marked with `0x1` using custom routing table 100. 2. **The Table (`ip route`)**: Table 100 contains `ip route add local 0.0.0.0/0 dev lo table 100`, forcing marked packets onto the local loopback interface. 3. **The Handoff**: Xray listens on `127.0.0.1:12345` with TPROXY enabled, grabbing the packet from loopback. 4. **Loop Prevention**: Xray outbounds append `"sockopt": { "mark": 255 }` (`0xff`) to bypass TPROXY interception rules for its own generated traffic, preventing infinite routing loops. --- ## 1. Setup Phase and Key Generation Generate four unique UUIDs to secure the VLESS tunnel connections between the Hub and Spokes: - `UUID_B_REVERSE`: Tunnel control for Server B (Bridge) - `UUID_B_DIRECT`: Data traffic for Server B - `UUID_C_REVERSE`: Tunnel control for Server C (Bridge) - `UUID_C_DIRECT`: Data traffic for Server C --- ## 2. Host Networking and TPROXY (routing.sh and before.rules) Before launching Xray containers, each server node requires kernel routing policy rules and UFW `mangle` firewall chains. ### A. Kernel Routing Initialization (routing.sh) The shell script [`routing.sh`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/routing.sh) enables IPv4 forwarding, registers firewall mark `0x1` to lookup table 100, and routes all table 100 traffic to loopback (`dev lo`). Run this script on **all** server nodes: ```bash #!/usr/bin/env bash set -euo pipefail echo "Applying routing configuration..." # 1. Enable IP Forwarding sudo sysctl -w net.ipv4.ip_forward=1 # 2. IP Rule for mark 0x1 -> table 100 if sudo ip rule show | grep -q 'fwmark 0x1 lookup 100'; then echo "IP rule for mark 0x1 already exists." else sudo ip rule add fwmark 0x1 lookup 100 priority 100 echo "IP rule added for mark 0x1." fi # 3. Local route in table 100 if sudo ip route show table 100 2>/dev/null | grep -q 'local default dev lo'; then echo "Local route in table 100 already exists." else sudo ip route add local 0.0.0.0/0 dev lo table 100 echo "Local route added to table 100." fi echo "Routing configuration applied successfully." ``` ### B. Hub Firewall Configuration (a/before.rules) On **Server A (Hub)**, append the TPROXY rules to `/etc/ufw/before.rules` (after the initial `COMMIT` line). The rule logic performs the following steps: 1. **Excludes Local Subnet**: Packets targeting Server A's local subnet (`10.1.0.0/16`) are returned to standard processing. 2. **Excludes External Traffic**: Packets outside `10.0.0.0/8` pass through unaffected. 3. **Excludes Xray Mark (`0xff`)**: Traffic generated by Xray itself is ignored to prevent routing loops. 4. **TPROXY Redirection**: Intercepts TCP and UDP traffic targeting `10.0.0.0/8` and redirects it to Xray on `127.0.0.1:12345` with mark `1`. Exact repository file: [`a/before.rules`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/a/before.rules) ```ini *mangle :XRAY - [0:0] :XRAY_MASK - [0:0] :DIVERT - [0:0] # --- PREROUTING CHAIN (Traffic from containers/nodes) --- -A XRAY -d 10.1.0.0/16 -j RETURN -A XRAY ! -d 10.0.0.0/8 -j RETURN -A XRAY -m mark --mark 0xff -j RETURN -A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1 -A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1 -A PREROUTING -j XRAY # --- OUTPUT CHAIN (Traffic originating from server host) --- -A XRAY_MASK -d 10.1.0.0/16 -j RETURN -A XRAY_MASK ! -d 10.0.0.0/8 -j RETURN -A XRAY_MASK -m mark --mark 0xff -j RETURN -A XRAY_MASK -p udp -j MARK --set-mark 1 -A XRAY_MASK -p tcp -j MARK --set-mark 1 -A OUTPUT -j XRAY_MASK # --- DIVERT Optimization --- -A DIVERT -j MARK --set-mark 1 -A DIVERT -j ACCEPT -I PREROUTING -p tcp -m socket -j DIVERT COMMIT *filter -A ufw-before-forward -s 10.1.0.0/16 -d 10.1.0.0/16 -j ACCEPT -A ufw-before-forward -s 10.1.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT -A ufw-before-input -s 10.1.0.0/16 -d 10.1.0.0/16 -j ACCEPT -A ufw-before-input -s 10.1.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT ``` ### C. Spoke Firewall Configuration (b/before.rules and c/before.rules) On **Server B (Spoke)** and **Server C (Spoke)**, apply the node-specific `/etc/ufw/before.rules`. For Server B (`10.2.0.0/16`), local traffic within `10.2.0.0/16` is exempted (`-d 10.2.0.0/16 -j RETURN`), while any packet destined for the rest of `10.0.0.0/8` (such as `10.1.x.x` or `10.3.x.x`) is intercepted via TPROXY and routed through the VLESS reverse tunnel back to Server A. Exact repository files: [`b/before.rules`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/b/before.rules) and [`c/before.rules`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/c/before.rules) ```ini *mangle :XRAY - [0:0] :XRAY_MASK - [0:0] :DIVERT - [0:0] -A XRAY -d 10.2.0.0/16 -j RETURN -A XRAY ! -d 10.0.0.0/8 -j RETURN -A XRAY -m mark --mark 0xff -j RETURN -A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1 -A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1 -A PREROUTING -j XRAY -A XRAY_MASK -d 10.2.0.0/16 -j RETURN -A XRAY_MASK ! -d 10.0.0.0/8 -j RETURN -A XRAY_MASK -m mark --mark 0xff -j RETURN -A XRAY_MASK -p udp -j MARK --set-mark 1 -A XRAY_MASK -p tcp -j MARK --set-mark 1 -A OUTPUT -j XRAY_MASK -A DIVERT -j MARK --set-mark 1 -A DIVERT -j ACCEPT -I PREROUTING -p tcp -m socket -j DIVERT COMMIT *filter -A ufw-before-forward -s 10.2.0.0/16 -d 10.2.0.0/16 -j ACCEPT -A ufw-before-forward -s 10.2.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT -A ufw-before-input -s 10.2.0.0/16 -d 10.2.0.0/16 -j ACCEPT -A ufw-before-input -s 10.2.0.0/16 -d 10.0.0.0/8 -m mark --mark 0x1 -j ACCEPT ``` Apply the changes on each node with `sudo ufw reload`. --- ## 3. Xray-core Configurations (xray.jsonc) ### A. Hub Configuration (a/xray.jsonc) The Hub listens on public port 443 with VLESS and XTLS-Vision. It maps reverse tunnel incoming connections (`reverse-b`, `reverse-c`) to their respective subnet destination rules. Exact repository file: [`a/xray.jsonc`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/a/xray.jsonc) ```jsonc { "inbounds": [ { "port": 443, "protocol": "vless", "tag": "proxy-direct", "settings": { "clients": [ { "id": "UUID_B_REVERSE", "reverse": { "tag": "reverse-b" } }, { "id": "UUID_B_DIRECT" }, { "id": "UUID_C_REVERSE", "reverse": { "tag": "reverse-c" } }, { "id": "UUID_C_DIRECT" } ] } }, { "port": 12345, "listen": "127.0.0.1", "protocol": "tunnel", "tag": "proxy-enclave", "streamSettings": { "sockopt": { "tproxy": "tproxy", "mark": 255 } } } ], "routing": { "rules": [ { "ip": ["10.2.0.0/16"], "outboundTag": "reverse-b" }, { "ip": ["10.3.0.0/16"], "outboundTag": "reverse-c" } ] } } ``` ### B. Spoke Configuration (b/xray.jsonc) The Spoke establishes VLESS client connections back to Server A (`A-EXTERNAL-IP`), maintaining a persistent reverse tunnel for incoming requests and forwarding outbound `10.0.0.0/8` traffic. Exact repository files: [`b/xray.jsonc`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/b/xray.jsonc) and [`c/xray.jsonc`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/c/xray.jsonc) ```jsonc { "outbounds": [ { "protocol": "vless", "tag": "forward-a-reverse", "settings": { "address": "A-EXTERNAL-IP", "id": "UUID_B_REVERSE", "reverse": { "tag": "reverse-b" } } }, { "protocol": "vless", "tag": "forward-a", "settings": { "address": "A-EXTERNAL-IP", "id": "UUID_B_DIRECT" } } ], "routing": { "rules": [ { "inboundTag": ["proxy-enclave"], "outboundTag": "forward-a" }, { "inboundTag": ["reverse-b"], "outboundTag": "forward-direct" }, { "ip": ["10.2.0.0/16"], "outboundTag": "forward-direct" }, { "ip": ["10.0.0.0/8"], "outboundTag": "forward-a" } ] } } ``` --- ## Resources & Reference For the complete, runnable repository containing Docker Compose files ([`a/docker-compose.yaml`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/a/docker-compose.yaml) and [`b/docker-compose.yaml`](https://github.com/deytenit/xray-core-subnet-mimicry/blob/main/b/docker-compose.yaml)), visit: - [xray-core-subnet-mimicry Repository on GitHub](https://github.com/deytenit/xray-core-subnet-mimicry/tree/main) Technical Documentation & Guides: - [Xray-core Official Documentation](https://xtls.github.io/) - [Understanding TPROXY (Cloudflare Blog)](https://blog.cloudflare.com/how-we-built-spectrum/) - [Linux Kernel TPROXY Documentation](https://www.kernel.org/doc/Documentation/networking/tproxy.txt)