mirror of
https://github.com/XTLS/Xray-docs-next.git
synced 2026-09-26 16:48:32 +03:00
237 lines
8.5 KiB
Markdown
237 lines
8.5 KiB
Markdown
# Transparent Proxy: Bypassing Xray Traffic via GID
|
|
|
|
In existing `iptables` transparent proxy guides (**[New V2Ray Plain English Guide - Transparent Proxy](https://guide.v2fly.org/app/transparent_proxy.html)**, **[New V2Ray Plain English Guide - Transparent Proxy (TPROXY)](https://guide.v2fly.org/app/tproxy.html)**, **[Transparent Proxy (TProxy) Configuration Tutorial](./tproxy)**), the method used to bypass Xray traffic (to prevent routing loops) involves marking packets (`mark`). Specifically, marks are applied to Xray's outbound traffic, and `iptables` rules are set to direct traffic with corresponding marks to go out directly, thus bypassing the Xray proxy process.
|
|
|
|
There are several issues with this approach:
|
|
|
|
1. **[Unexplained traffic entering the PREROUTING chain](https://github.com/v2ray/v2ray-core/issues/2621)**.
|
|
2. Android systems have their own marking mechanism, making this solution unusable on Android.
|
|
|
|
The solution in this tutorial does not require setting marks. Theoretically, it offers higher performance and avoids the issues mentioned above.
|
|
|
|
## Concept
|
|
|
|
TProxy traffic can only be received by the root user (`uid==0`) or other users with `CAP_NET_ADMIN` privileges.
|
|
|
|
`iptables` rules can route traffic based on UID (User ID) and GID (Group ID).
|
|
|
|
By running Xray as a user with `uid==0` but `gid!=0`, we can set `iptables` rules to exclude traffic from that specific GID, thereby bypassing Xray traffic.
|
|
|
|
## Configuration Process
|
|
|
|
### 1. Prerequisites
|
|
|
|
**Android System**
|
|
|
|
1. System must be rooted.
|
|
2. Install **[busybox](https://play.google.com/store/apps/details?id=stericson.busybox)**.
|
|
3. Have a terminal capable of executing commands, such as `adb shell`, `termux`, etc.
|
|
|
|
**Other Linux Systems**
|
|
|
|
Requires dependencies: `sudo`, `iptables-mod-tproxy`, and `iptables-mod-extra`.
|
|
|
|
Most systems come with these built-in. For OpenWrt, run:
|
|
|
|
```bash
|
|
opkg install sudo iptables-mod-tproxy iptables-mod-extra
|
|
```
|
|
|
|
Here are some common dependencies for OpenWrt. Missing them might prevent Xray from running:
|
|
|
|
```bash
|
|
opkg install libopenssl ca-certificates
|
|
```
|
|
|
|
### 2. Add User (Skip for Android users)
|
|
|
|
Android systems do not support managing users via the `/etc/passwd` file, so please ignore this and proceed to the next step.
|
|
|
|
```bash
|
|
grep -qw xray_tproxy /etc/passwd || echo "xray_tproxy:x:0:23333:::" >> /etc/passwd
|
|
```
|
|
|
|
Here, `xray_tproxy` is the username, `0` is the UID, and `23333` is the GID. The username and GID can be customized, but the UID must be 0.
|
|
To check if the user was added successfully, run:
|
|
|
|
```bash
|
|
sudo -u xray_tproxy id
|
|
```
|
|
|
|
The displayed result should show UID as 0 and GID as 23333.
|
|
|
|
### 3. Configure/Run Xray and Set iptables Rules
|
|
|
|
Modify based on the existing `iptables` transparent proxy guides (**[New V2Ray Plain English Guide - Transparent Proxy](https://guide.v2fly.org/app/transparent_proxy.html)**, **[New V2Ray Plain English Guide - Transparent Proxy (TPROXY)](https://guide.v2fly.org/app/tproxy.html)**, **[Transparent Proxy (TProxy) Configuration Tutorial](./tproxy)**):
|
|
|
|
1. Modify the JSON configuration file to delete content related to `mark`.
|
|
2. Modify `iptables` rules to delete content related to `mark`, and add the option `-m owner ! --gid-owner 23333` to the rule applied in the OUTPUT chain.
|
|
|
|
For example:
|
|
|
|
```bash
|
|
iptables -t mangle -A OUTPUT -j XRAY_SELF
|
|
```
|
|
|
|
Change to:
|
|
|
|
```bash
|
|
iptables -t mangle -A OUTPUT -m owner ! --gid-owner 23333 -j XRAY_SELF
|
|
```
|
|
|
|
1. Modify the way Xray is run so that it runs as a user with `uid=0` and `gid=23333`. Refer to [this section](#_3-configure-max-open-files-run-xray-client).
|
|
|
|
## Below is a complete configuration process for implementing global TProxy
|
|
|
|
### 1. Complete the Prerequisites and User Addition steps above
|
|
|
|
### 2. Prepare Xray Configuration File
|
|
|
|
Configure Xray `dokodemo-door` to listen on port 12345, enable `followRedirect` and `tproxy`. Setting `sniffing` is not required:
|
|
|
|
```json
|
|
{
|
|
"inbounds": [
|
|
{
|
|
"port": 12345,
|
|
"protocol": "dokodemo-door",
|
|
"settings": {
|
|
"network": "tcp,udp",
|
|
"followRedirect": true
|
|
},
|
|
"streamSettings": {
|
|
"sockopt": {
|
|
"tproxy": "tproxy"
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
Your Server Configuration
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 3. Configure Max Open Files & Run Xray Client
|
|
|
|
For issues regarding the maximum number of open files, see: **[Too many open files issue](https://guide.v2fly.org/app/tproxy.html#解决-too-many-open-files-问题)**.
|
|
|
|
Currently, Xray servers installed using the official script automatically configure the maximum open file limit, so no further modification is needed.
|
|
|
|
**Android System**
|
|
|
|
```bash
|
|
ulimit -SHn 1000000
|
|
setuidgid 0:23333 "Command to run Xray"&
|
|
```
|
|
|
|
**Other Linux Systems**
|
|
|
|
```bash
|
|
ulimit -SHn 1000000
|
|
sudo -u xray_tproxy "Command to run Xray"&
|
|
```
|
|
|
|
For example:
|
|
|
|
```bash
|
|
ulimit -SHn 1000000
|
|
sudo -u xray_tproxy xray -c /etc/xray/config.json &
|
|
```
|
|
|
|
_First command:_
|
|
|
|
Changes the maximum number of open files. It is only effective for the current terminal and must be run every time before starting Xray. This command sets the maximum file limit for the client.
|
|
|
|
_Second command:_
|
|
|
|
Runs the Xray client as a user with `uid=0` and a non-zero `gid`. The `&` at the end indicates running in the background.
|
|
|
|
**Check if Max Open Files was set successfully**
|
|
|
|
```bash
|
|
cat /proc/PID_OF_XRAY/limits
|
|
```
|
|
|
|
Find the `max open files` item; it should match the value you set. You can get the PID by running `ps`, `ps -aux`, `ps -a`, or `pidof xray`.
|
|
|
|
Check both the server and the client.
|
|
|
|
### 4. Set iptables Rules
|
|
|
|
**Proxy IPv4**
|
|
|
|
```bash
|
|
ip rule add fwmark 1 table 100
|
|
ip route add local 0.0.0.0/0 dev lo table 100
|
|
|
|
# Proxy LAN devices
|
|
iptables -t mangle -N XRAY
|
|
# "Gateway IPv4 subnet" is obtained by running "ip address | grep -w inet | awk '{print $2}'". There are usually multiple.
|
|
iptables -t mangle -A XRAY -d Gateway_IPv4_Subnet_1 -j RETURN
|
|
iptables -t mangle -A XRAY -d Gateway_IPv4_Subnet_2 -j RETURN
|
|
...
|
|
|
|
# Direct connection for Multicast/Class E/Broadcast addresses
|
|
iptables -t mangle -A XRAY -d 224.0.0.0/3 -j RETURN
|
|
|
|
|
|
# If the gateway serves as the main router, add this line.
|
|
# See: https://xtls.github.io/en/document/level-2/transparent_proxy/transparent_proxy.html#other-notes-on-iptables-transparent-proxy
|
|
# Gateway_LAN_IPv4_Subnet is one of the results from "ip address | grep -w "inet" | awk '{print $2}'".
|
|
iptables -t mangle -A XRAY ! -s Gateway_LAN_IPv4_Subnet -j RETURN
|
|
|
|
# Mark TCP packets with 1, forward to port 12345
|
|
# Traffic is accepted by Xray dokodemo-door only if mark is set to 1
|
|
iptables -t mangle -A XRAY -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1
|
|
iptables -t mangle -A XRAY -p udp -j TPROXY --on-port 12345 --tproxy-mark 1
|
|
# Apply rules
|
|
iptables -t mangle -A PREROUTING -j XRAY
|
|
|
|
# Proxy the Gateway itself
|
|
iptables -t mangle -N XRAY_MASK
|
|
iptables -t mangle -A XRAY_MASK -m owner --gid-owner 23333 -j RETURN
|
|
iptables -t mangle -A XRAY_MASK -d Gateway_IPv4_Subnet_1 -j RETURN
|
|
iptables -t mangle -A XRAY_MASK -d Gateway_IPv4_Subnet_2 -j RETURN
|
|
...
|
|
iptables -t mangle -A XRAY_MASK -d 224.0.0.0/3 -j RETURN
|
|
iptables -t mangle -A XRAY_MASK -j MARK --set-mark 1
|
|
iptables -t mangle -A OUTPUT -p tcp -j XRAY_MASK
|
|
iptables -t mangle -A OUTPUT -p udp -j XRAY_MASK
|
|
```
|
|
|
|
**Proxy IPv6 (Optional)**
|
|
|
|
```bash
|
|
ip -6 rule add fwmark 1 table 106
|
|
ip -6 route add local ::/0 dev lo table 106
|
|
|
|
# Proxy LAN devices
|
|
ip6tables -t mangle -N XRAY6
|
|
# "Gateway IPv6 subnet" is obtained by running "ip address | grep -w inet6 | awk '{print $2}'".
|
|
ip6tables -t mangle -A XRAY6 -d Gateway_IPv6_Subnet_1 -j RETURN
|
|
ip6tables -t mangle -A XRAY6 -d Gateway_IPv6_Subnet_2 -j RETURN
|
|
...
|
|
|
|
# If the gateway serves as the main router, add this line.
|
|
# See: https://xtls.github.io/en/document/level-2/transparent_proxy/transparent_proxy.html#other-notes-on-iptables-transparent-proxy
|
|
# Gateway_LAN_IPv6_Subnet is one of the results from "ip address | grep -w "inet6" | awk '{print $2}'".
|
|
ip6tables -t mangle -A XRAY6 ! -s Gateway_LAN_IPv6_Subnet -j RETURN
|
|
|
|
ip6tables -t mangle -A XRAY6 -p udp -j TPROXY --on-port 12345 --tproxy-mark 1
|
|
ip6tables -t mangle -A XRAY6 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1
|
|
ip6tables -t mangle -A PREROUTING -j XRAY6
|
|
|
|
# Proxy the Gateway itself
|
|
ip6tables -t mangle -N XRAY6_MASK
|
|
ip6tables -t mangle -A XRAY6_MASK -m owner --gid-owner 23333 -j RETURN
|
|
ip6tables -t mangle -A XRAY6_MASK -d Gateway_IPv6_Subnet_1 -j RETURN
|
|
ip6tables -t mangle -A XRAY6_MASK -d Gateway_IPv6_Subnet_2 -j RETURN
|
|
...
|
|
ip6tables -t mangle -A XRAY6_MASK -j MARK --set-mark 1
|
|
ip6tables -t mangle -A OUTPUT -p tcp -j XRAY6_MASK
|
|
ip6tables -t mangle -A OUTPUT -p udp -j XRAY6_MASK
|
|
```
|