1428 lines
37 KiB
Markdown
1428 lines
37 KiB
Markdown
# State-of-the-Art Xray Anti-DPI Configurations for Russia (2025-2026)
|
|
|
|
## Table of Contents
|
|
1. [Background: Russian DPI (TSPU) Current Capabilities](#background)
|
|
2. [Configuration #1: VLESS + XHTTP + Reality (RANKED #1)](#config-1)
|
|
3. [Configuration #2: Chain Relay — VLESS + XHTTP via Russian Bridge Node (RANKED #2)](#config-2)
|
|
4. [Configuration #3: VLESS + gRPC + Reality (RANKED #3)](#config-3)
|
|
5. [Configuration #4: VLESS + TCP + Reality + Fragment/Noise Chains (RANKED #4)](#config-4)
|
|
6. [Configuration #5: VLESS + WebSocket + TLS behind CDN (RANKED #5)](#config-5)
|
|
7. [Configuration #6: Shadowsocks 2022 + XHTTP (Bonus)](#config-6)
|
|
8. [Cross-Cutting Techniques](#cross-cutting)
|
|
9. [Performance Comparison](#performance)
|
|
10. [DNS Strategies](#dns)
|
|
|
|
---
|
|
|
|
## Background: Russian DPI (TSPU) Current Capabilities <a name="background"></a>
|
|
|
|
As of late 2025 / early 2026, Roskomnadzor's TSPU (Technical Means of Countering Threats) has deployed the following detection capabilities:
|
|
|
|
1. **Volume-based TCP freezing**: If a client connects via TCP+HTTPS+TLS1.3 to a "suspicious" foreign IP (Hetzner, DigitalOcean, OVH, etc.), and data received exceeds ~15-20 KB in a single TCP connection, the connection is "frozen" — packets simply stop arriving. No RST is sent.
|
|
|
|
2. **SNI whitelisting**: The censor maintains whitelists based on SNI values in the TLS ClientHello. Connections to non-whitelisted SNIs on foreign IPs face increased scrutiny.
|
|
|
|
3. **CIDR-based whitelisting**: Destination IP subnets are classified. Traffic to known datacenter ranges outside Russia faces stricter filtering.
|
|
|
|
4. **Port 443 targeting**: Blocking is often stricter on port 443. Moving to high random ports (47000+) allows ~80% of packets through in many regions.
|
|
|
|
5. **TLS fingerprint analysis**: TSPU inspects TLS ClientHello fingerprints. Empty SNI or Go default fingerprints can paradoxically help bypass some filters.
|
|
|
|
6. **NewSessionTicket analysis**: Xray-core >= v25.12.8 is required to avoid detection through TLS 1.3 NewSessionTicket patterns.
|
|
|
|
**Critical minimum version**: Xray-core >= v25.12.8. Recommended: v26.1.23 or v26.2.6 for TUN support, Hysteria outbound, XICMP finalmask, and latest XHTTP improvements.
|
|
|
|
---
|
|
|
|
## Configuration #1: VLESS + XHTTP + Reality (Direct Mode) <a name="config-1"></a>
|
|
|
|
**Effectiveness: HIGHEST for direct connections**
|
|
|
|
XHTTP (evolved from SplitHTTP) is the newest recommended transport in the Xray ecosystem. It separates upload and download into different HTTP requests, making traffic patterns fundamentally different from a persistent TLS tunnel. Combined with Reality, it provides state-of-the-art stealth.
|
|
|
|
### Why This Works Against TSPU
|
|
|
|
- Upload is split into multiple small POST requests (each well under 15-20 KB), defeating volume-based freezing
|
|
- Download streams via long-lived response, appearing as normal CDN-like content delivery
|
|
- XHTTP padding (`xPaddingBytes`) randomizes packet sizes to defeat statistical analysis
|
|
- XMUX connection multiplexing with randomized parameters prevents fixed-pattern recognition
|
|
- No distinctive "ALPN is http/1.1" fingerprint that plagues older transports
|
|
|
|
### XHTTP Modes
|
|
|
|
| Mode | Upload | Download | Best For |
|
|
|------|--------|----------|----------|
|
|
| `packet-up` | Multiple POST requests | Streaming response | Most compatible, default for H3 |
|
|
| `stream-up` | Single streaming POST | Streaming response | Best performance via H2/gRPC |
|
|
| `stream-one` | Single POST (both dirs) | Same POST response | Fallback when stream-up fails |
|
|
|
|
### Server Configuration
|
|
|
|
```json
|
|
{
|
|
"log": {
|
|
"loglevel": "warning"
|
|
},
|
|
"inbounds": [
|
|
{
|
|
"tag": "xhttp-in",
|
|
"listen": "0.0.0.0",
|
|
"port": 443,
|
|
"protocol": "vless",
|
|
"settings": {
|
|
"clients": [
|
|
{
|
|
"id": "YOUR-UUID-HERE",
|
|
"flow": ""
|
|
}
|
|
],
|
|
"decryption": "none"
|
|
},
|
|
"streamSettings": {
|
|
"network": "xhttp",
|
|
"xhttpSettings": {
|
|
"path": "/your-secret-path"
|
|
},
|
|
"security": "reality",
|
|
"realitySettings": {
|
|
"dest": "www.microsoft.com:443",
|
|
"serverNames": [
|
|
"www.microsoft.com"
|
|
],
|
|
"privateKey": "YOUR-PRIVATE-KEY",
|
|
"shortIds": [
|
|
"a1b2c3d4"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
"protocol": "freedom",
|
|
"tag": "direct"
|
|
},
|
|
{
|
|
"protocol": "blackhole",
|
|
"tag": "block"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Client Configuration
|
|
|
|
```json
|
|
{
|
|
"log": {
|
|
"loglevel": "warning"
|
|
},
|
|
"inbounds": [
|
|
{
|
|
"tag": "socks-in",
|
|
"listen": "127.0.0.1",
|
|
"port": 10808,
|
|
"protocol": "socks",
|
|
"settings": {
|
|
"udp": true
|
|
}
|
|
},
|
|
{
|
|
"tag": "http-in",
|
|
"listen": "127.0.0.1",
|
|
"port": 10809,
|
|
"protocol": "http"
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
"tag": "proxy",
|
|
"protocol": "vless",
|
|
"settings": {
|
|
"vnext": [
|
|
{
|
|
"address": "YOUR-SERVER-IP",
|
|
"port": 443,
|
|
"users": [
|
|
{
|
|
"id": "YOUR-UUID-HERE",
|
|
"encryption": "none",
|
|
"flow": ""
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"streamSettings": {
|
|
"network": "xhttp",
|
|
"xhttpSettings": {
|
|
"path": "/your-secret-path",
|
|
"mode": "auto",
|
|
"extra": {
|
|
"xPaddingBytes": "100-1000",
|
|
"xmux": {
|
|
"maxConcurrency": "16-32",
|
|
"cMaxReuseTimes": "64-128",
|
|
"cMaxLifetimeMs": "0",
|
|
"hMaxRequestTimes": "600-900",
|
|
"hMaxReusableSecs": "1800-3000"
|
|
}
|
|
}
|
|
},
|
|
"security": "reality",
|
|
"realitySettings": {
|
|
"fingerprint": "chrome",
|
|
"serverName": "www.microsoft.com",
|
|
"publicKey": "YOUR-PUBLIC-KEY",
|
|
"shortId": "a1b2c3d4",
|
|
"spiderX": "/"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"tag": "direct",
|
|
"protocol": "freedom"
|
|
}
|
|
],
|
|
"routing": {
|
|
"domainStrategy": "AsIs",
|
|
"rules": [
|
|
{
|
|
"type": "field",
|
|
"domain": [
|
|
"geosite:private"
|
|
],
|
|
"outboundTag": "direct"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Pros
|
|
- Strongest anti-detection: upload splitting defeats volume-based TCP freezing
|
|
- Built-in padding and multiplexing randomization
|
|
- Can work through CDNs as a fallback (switch mode to `packet-up` with CDN)
|
|
- Newer protocol = less studied by censors
|
|
- Lower latency than Vision in some scenarios
|
|
|
|
### Cons
|
|
- Requires Xray-core >= v24.9.15 (realistically >= v25.12.8 for Russia)
|
|
- Slightly more complex configuration
|
|
- `stream-up` mode may not work with all reverse proxies
|
|
- Newer = less battle-tested than TCP+Vision
|
|
|
|
### When to Use
|
|
- Primary configuration for direct connections from Russia
|
|
- When TCP+Vision connections get frozen after 15-20 KB
|
|
- When you need good performance AND stealth
|
|
|
|
---
|
|
|
|
## Configuration #2: Chain Relay via Russian Bridge Node <a name="config-2"></a>
|
|
|
|
**Effectiveness: HIGHEST for surviving whitelist/CIDR blocking**
|
|
|
|
This is the architecture recommended by the most experienced Russian anti-censorship community when direct connections to foreign servers are being blocked or throttled. A Russian VPS acts as a bridge, making the traffic appear as domestic server-to-server communication.
|
|
|
|
### Architecture
|
|
|
|
```
|
|
Client (Russia) --[XHTTP+Reality]--> Russian VPS (bridge) --[XHTTP+Reality]--> European VPS (exit) --> Internet
|
|
```
|
|
|
|
The TSPU applies lighter scrutiny to server-to-server traffic within Russian IP ranges. The bridge node uses a "clean" Russian IP (Yandex Cloud, VK Cloud, etc.).
|
|
|
|
### Bridge Node (Russian VPS) Configuration
|
|
|
|
```json
|
|
{
|
|
"log": {
|
|
"loglevel": "warning"
|
|
},
|
|
"inbounds": [
|
|
{
|
|
"tag": "from-client",
|
|
"listen": "0.0.0.0",
|
|
"port": 443,
|
|
"protocol": "vless",
|
|
"settings": {
|
|
"clients": [
|
|
{
|
|
"id": "UUID-FOR-CLIENT",
|
|
"flow": ""
|
|
}
|
|
],
|
|
"decryption": "none"
|
|
},
|
|
"streamSettings": {
|
|
"network": "xhttp",
|
|
"xhttpSettings": {
|
|
"path": "/bridge-path"
|
|
},
|
|
"security": "reality",
|
|
"realitySettings": {
|
|
"dest": "vkvideo.ru:443",
|
|
"serverNames": [
|
|
"vkvideo.ru"
|
|
],
|
|
"privateKey": "BRIDGE-PRIVATE-KEY",
|
|
"shortIds": [
|
|
"ab01"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
"tag": "to-exit",
|
|
"protocol": "vless",
|
|
"settings": {
|
|
"vnext": [
|
|
{
|
|
"address": "EXIT-SERVER-IP",
|
|
"port": 443,
|
|
"users": [
|
|
{
|
|
"id": "UUID-FOR-EXIT",
|
|
"encryption": "none",
|
|
"flow": ""
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"streamSettings": {
|
|
"network": "xhttp",
|
|
"xhttpSettings": {
|
|
"path": "/exit-path",
|
|
"mode": "auto",
|
|
"extra": {
|
|
"xPaddingBytes": "100-1000"
|
|
}
|
|
},
|
|
"security": "reality",
|
|
"realitySettings": {
|
|
"fingerprint": "chrome",
|
|
"serverName": "www.google.com",
|
|
"publicKey": "EXIT-PUBLIC-KEY",
|
|
"shortId": "cd02"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"tag": "direct",
|
|
"protocol": "freedom"
|
|
},
|
|
{
|
|
"tag": "block",
|
|
"protocol": "blackhole"
|
|
}
|
|
],
|
|
"routing": {
|
|
"domainStrategy": "AsIs",
|
|
"rules": [
|
|
{
|
|
"type": "field",
|
|
"inboundTag": ["from-client"],
|
|
"outboundTag": "to-exit"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Exit Node (European VPS) Configuration
|
|
|
|
```json
|
|
{
|
|
"log": {
|
|
"loglevel": "warning"
|
|
},
|
|
"inbounds": [
|
|
{
|
|
"tag": "from-bridge",
|
|
"listen": "0.0.0.0",
|
|
"port": 443,
|
|
"protocol": "vless",
|
|
"settings": {
|
|
"clients": [
|
|
{
|
|
"id": "UUID-FOR-EXIT",
|
|
"flow": ""
|
|
}
|
|
],
|
|
"decryption": "none"
|
|
},
|
|
"streamSettings": {
|
|
"network": "xhttp",
|
|
"xhttpSettings": {
|
|
"path": "/exit-path"
|
|
},
|
|
"security": "reality",
|
|
"realitySettings": {
|
|
"dest": "www.google.com:443",
|
|
"serverNames": [
|
|
"www.google.com"
|
|
],
|
|
"privateKey": "EXIT-PRIVATE-KEY",
|
|
"shortIds": [
|
|
"cd02"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
"tag": "direct",
|
|
"protocol": "freedom"
|
|
},
|
|
{
|
|
"tag": "block",
|
|
"protocol": "blackhole"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Client Configuration
|
|
|
|
```json
|
|
{
|
|
"log": {
|
|
"loglevel": "warning"
|
|
},
|
|
"inbounds": [
|
|
{
|
|
"tag": "socks-in",
|
|
"listen": "127.0.0.1",
|
|
"port": 10808,
|
|
"protocol": "socks",
|
|
"settings": {
|
|
"udp": true
|
|
}
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
"tag": "proxy",
|
|
"protocol": "vless",
|
|
"settings": {
|
|
"vnext": [
|
|
{
|
|
"address": "RUSSIAN-BRIDGE-IP",
|
|
"port": 443,
|
|
"users": [
|
|
{
|
|
"id": "UUID-FOR-CLIENT",
|
|
"encryption": "none",
|
|
"flow": ""
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"streamSettings": {
|
|
"network": "xhttp",
|
|
"xhttpSettings": {
|
|
"path": "/bridge-path",
|
|
"mode": "auto",
|
|
"extra": {
|
|
"xPaddingBytes": "100-1000",
|
|
"xmux": {
|
|
"maxConcurrency": "16-32",
|
|
"hMaxRequestTimes": "600-900",
|
|
"hMaxReusableSecs": "1800-3000"
|
|
}
|
|
}
|
|
},
|
|
"security": "reality",
|
|
"realitySettings": {
|
|
"fingerprint": "chrome",
|
|
"serverName": "vkvideo.ru",
|
|
"publicKey": "BRIDGE-PUBLIC-KEY",
|
|
"shortId": "ab01"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"tag": "direct",
|
|
"protocol": "freedom"
|
|
}
|
|
],
|
|
"routing": {
|
|
"domainStrategy": "AsIs",
|
|
"rules": [
|
|
{
|
|
"type": "field",
|
|
"domain": [
|
|
"geosite:private",
|
|
"geosite:category-ru"
|
|
],
|
|
"outboundTag": "direct"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Key Details
|
|
- **SNI for bridge**: Use a Russian domain (vkvideo.ru, yandex.ru, mail.ru) to blend with domestic traffic
|
|
- **SNI for exit**: Use a major global domain (google.com, microsoft.com, cloudflare.com)
|
|
- **XHTTP in `packet-up` mode**: Minimizes memory on the bridge node
|
|
- **Minimum xray-core version**: v25.12.8 on ALL nodes (to avoid NewSessionTicket fingerprinting)
|
|
|
|
### Pros
|
|
- Survives CIDR whitelisting (bridge is on a Russian IP)
|
|
- Server-to-server traffic gets lighter TSPU scrutiny
|
|
- Double Reality encryption layers
|
|
- Even if the bridge is identified, the exit node remains hidden
|
|
|
|
### Cons
|
|
- Requires two VPS (doubles cost)
|
|
- Finding "clean" Russian IPs is increasingly difficult
|
|
- Added latency from the extra hop (~20-50ms typically)
|
|
- More complex to maintain
|
|
|
|
### When to Use
|
|
- When direct connections to foreign IPs are blocked or throttled
|
|
- On mobile networks (which often have stricter filtering)
|
|
- When CIDR-based whitelisting is active in your region
|
|
- As the ultimate fallback when everything else fails
|
|
|
|
---
|
|
|
|
## Configuration #3: VLESS + gRPC + Reality <a name="config-3"></a>
|
|
|
|
**Effectiveness: HIGH — good balance of stealth and performance**
|
|
|
|
gRPC transport makes traffic look like legitimate gRPC API calls (used by Google, Cloudflare, and countless microservices). Combined with Reality, it presents as standard H2 traffic to an enterprise service.
|
|
|
|
### Why This Works Against TSPU
|
|
|
|
- gRPC over H2 is extremely common in modern infrastructure
|
|
- Multi-mode gRPC allows efficient multiplexing
|
|
- Different traffic pattern than TCP+Vision (no distinctive XTLS flow signature)
|
|
- Can be fronted through Cloudflare CDN as fallback (enable gRPC in CF dashboard)
|
|
|
|
### Server Configuration
|
|
|
|
```json
|
|
{
|
|
"log": {
|
|
"loglevel": "warning"
|
|
},
|
|
"inbounds": [
|
|
{
|
|
"tag": "grpc-reality-in",
|
|
"listen": "0.0.0.0",
|
|
"port": 443,
|
|
"protocol": "vless",
|
|
"settings": {
|
|
"clients": [
|
|
{
|
|
"id": "YOUR-UUID-HERE",
|
|
"flow": ""
|
|
}
|
|
],
|
|
"decryption": "none"
|
|
},
|
|
"streamSettings": {
|
|
"network": "grpc",
|
|
"grpcSettings": {
|
|
"serviceName": "your-secret-service-name",
|
|
"multiMode": true,
|
|
"idle_timeout": 60,
|
|
"health_check_timeout": 20,
|
|
"initial_windows_size": 65536
|
|
},
|
|
"security": "reality",
|
|
"realitySettings": {
|
|
"dest": "www.microsoft.com:443",
|
|
"serverNames": [
|
|
"www.microsoft.com",
|
|
"microsoft.com"
|
|
],
|
|
"privateKey": "YOUR-PRIVATE-KEY",
|
|
"shortIds": [
|
|
"a1",
|
|
"b2c3d4e5"
|
|
]
|
|
}
|
|
},
|
|
"sniffing": {
|
|
"enabled": true,
|
|
"destOverride": [
|
|
"http",
|
|
"tls",
|
|
"quic"
|
|
]
|
|
}
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
"protocol": "freedom",
|
|
"tag": "direct"
|
|
},
|
|
{
|
|
"protocol": "blackhole",
|
|
"tag": "block"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Client Configuration
|
|
|
|
```json
|
|
{
|
|
"log": {
|
|
"loglevel": "warning"
|
|
},
|
|
"inbounds": [
|
|
{
|
|
"tag": "socks-in",
|
|
"listen": "127.0.0.1",
|
|
"port": 10808,
|
|
"protocol": "socks",
|
|
"settings": {
|
|
"udp": true
|
|
}
|
|
},
|
|
{
|
|
"tag": "http-in",
|
|
"listen": "127.0.0.1",
|
|
"port": 10809,
|
|
"protocol": "http"
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
"tag": "proxy",
|
|
"protocol": "vless",
|
|
"settings": {
|
|
"vnext": [
|
|
{
|
|
"address": "YOUR-SERVER-IP",
|
|
"port": 443,
|
|
"users": [
|
|
{
|
|
"id": "YOUR-UUID-HERE",
|
|
"encryption": "none",
|
|
"flow": ""
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"streamSettings": {
|
|
"network": "grpc",
|
|
"grpcSettings": {
|
|
"serviceName": "your-secret-service-name",
|
|
"multiMode": true,
|
|
"idle_timeout": 60,
|
|
"health_check_timeout": 20,
|
|
"initial_windows_size": 65536
|
|
},
|
|
"security": "reality",
|
|
"realitySettings": {
|
|
"fingerprint": "chrome",
|
|
"serverName": "www.microsoft.com",
|
|
"publicKey": "YOUR-PUBLIC-KEY",
|
|
"shortId": "a1",
|
|
"spiderX": "/"
|
|
}
|
|
},
|
|
"mux": {
|
|
"enabled": false
|
|
}
|
|
},
|
|
{
|
|
"tag": "direct",
|
|
"protocol": "freedom"
|
|
}
|
|
],
|
|
"routing": {
|
|
"domainStrategy": "AsIs",
|
|
"rules": [
|
|
{
|
|
"type": "field",
|
|
"domain": [
|
|
"geosite:private"
|
|
],
|
|
"outboundTag": "direct"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Pros
|
|
- gRPC is extremely common traffic — blends well
|
|
- H2 multiplexing reduces handshake overhead
|
|
- `multiMode: true` improves throughput for large transfers
|
|
- Can be CDN-fronted via Cloudflare gRPC support as emergency fallback
|
|
- Good performance for streaming and downloads
|
|
- `initial_windows_size` tuning allows better throughput
|
|
|
|
### Cons
|
|
- gRPC path (`/${serviceName}/Tun` or `/TunMulti`) may be fingerprintable
|
|
- No `flow: xtls-rprx-vision` support (gRPC does not support Vision)
|
|
- Double encryption overhead (TLS inside Reality, unlike Vision which avoids this)
|
|
- Some networks throttle H2 specifically
|
|
|
|
### When to Use
|
|
- When TCP+Vision is being blocked but H2 traffic passes
|
|
- When you need CDN fallback capability
|
|
- For users needing good streaming performance
|
|
- As a secondary profile alongside XHTTP
|
|
|
|
---
|
|
|
|
## Configuration #4: VLESS + TCP + Reality + Fragment/Noise Chains <a name="config-4"></a>
|
|
|
|
**Effectiveness: MEDIUM-HIGH — extends the life of basic Reality**
|
|
|
|
This takes the standard VLESS+TCP+Reality+Vision configuration and adds chained fragmentation outbounds and UDP noise injection to defeat DPI analysis of the TLS handshake.
|
|
|
|
### Why This Works Against TSPU
|
|
|
|
- TLS ClientHello fragmentation breaks DPI signature matching
|
|
- Chained fragmentation applies multiple strategies sequentially
|
|
- UDP noise overwhelms statistical analysis
|
|
- Non-standard port avoids port-443-specific blocking
|
|
- Vision flow avoids double encryption (better performance)
|
|
|
|
### Server Configuration
|
|
|
|
```json
|
|
{
|
|
"log": {
|
|
"loglevel": "warning"
|
|
},
|
|
"inbounds": [
|
|
{
|
|
"tag": "vless-reality-in",
|
|
"listen": "0.0.0.0",
|
|
"port": 47832,
|
|
"protocol": "vless",
|
|
"settings": {
|
|
"clients": [
|
|
{
|
|
"id": "YOUR-UUID-HERE",
|
|
"flow": "xtls-rprx-vision"
|
|
}
|
|
],
|
|
"decryption": "none"
|
|
},
|
|
"streamSettings": {
|
|
"network": "tcp",
|
|
"tcpSettings": {},
|
|
"security": "reality",
|
|
"realitySettings": {
|
|
"dest": "www.microsoft.com:443",
|
|
"serverNames": [
|
|
"www.microsoft.com"
|
|
],
|
|
"privateKey": "YOUR-PRIVATE-KEY",
|
|
"shortIds": [
|
|
"a1b2c3"
|
|
]
|
|
}
|
|
},
|
|
"sniffing": {
|
|
"enabled": true,
|
|
"destOverride": [
|
|
"http",
|
|
"tls",
|
|
"quic"
|
|
]
|
|
}
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
"protocol": "freedom",
|
|
"tag": "direct"
|
|
},
|
|
{
|
|
"protocol": "blackhole",
|
|
"tag": "block"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Client Configuration (with chained fragment + noise)
|
|
|
|
```json
|
|
{
|
|
"log": {
|
|
"loglevel": "warning"
|
|
},
|
|
"inbounds": [
|
|
{
|
|
"tag": "socks-in",
|
|
"listen": "127.0.0.1",
|
|
"port": 10808,
|
|
"protocol": "socks",
|
|
"settings": {
|
|
"udp": true
|
|
}
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
"tag": "proxy",
|
|
"protocol": "vless",
|
|
"settings": {
|
|
"vnext": [
|
|
{
|
|
"address": "YOUR-SERVER-IP",
|
|
"port": 47832,
|
|
"users": [
|
|
{
|
|
"id": "YOUR-UUID-HERE",
|
|
"encryption": "none",
|
|
"flow": "xtls-rprx-vision"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"streamSettings": {
|
|
"network": "tcp",
|
|
"security": "reality",
|
|
"realitySettings": {
|
|
"fingerprint": "chrome",
|
|
"serverName": "www.microsoft.com",
|
|
"publicKey": "YOUR-PUBLIC-KEY",
|
|
"shortId": "a1b2c3",
|
|
"spiderX": "/"
|
|
},
|
|
"sockopt": {
|
|
"dialerProxy": "fragment-chain1"
|
|
}
|
|
},
|
|
"mux": {
|
|
"enabled": true,
|
|
"concurrency": 8,
|
|
"xudpConcurrency": 16,
|
|
"xudpProxyUDP443": "reject"
|
|
}
|
|
},
|
|
{
|
|
"tag": "fragment-chain1",
|
|
"protocol": "freedom",
|
|
"settings": {
|
|
"fragment": {
|
|
"packets": "tlshello",
|
|
"length": "100-200",
|
|
"interval": "10-20"
|
|
}
|
|
},
|
|
"streamSettings": {
|
|
"sockopt": {
|
|
"dialerProxy": "fragment-chain2"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"tag": "fragment-chain2",
|
|
"protocol": "freedom",
|
|
"settings": {
|
|
"fragment": {
|
|
"packets": "1-3",
|
|
"length": "1-5",
|
|
"interval": "1-2"
|
|
},
|
|
"noises": [
|
|
{
|
|
"type": "rand",
|
|
"packet": "50-150",
|
|
"delay": "10-16"
|
|
},
|
|
{
|
|
"type": "base64",
|
|
"packet": "7nQBAAABAAAAAAAABnQtcmluZwZtc2VkZ2UDbmV0AAABAAE=",
|
|
"delay": "10-16"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"tag": "direct",
|
|
"protocol": "freedom"
|
|
}
|
|
],
|
|
"routing": {
|
|
"domainStrategy": "AsIs",
|
|
"rules": [
|
|
{
|
|
"type": "field",
|
|
"domain": [
|
|
"geosite:private"
|
|
],
|
|
"outboundTag": "direct"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Fragment Chain Explanation
|
|
|
|
The client uses **chained fragmentation outbounds** connected via `sockopt.dialerProxy`:
|
|
|
|
1. **proxy** -> routes through `fragment-chain1`
|
|
2. **fragment-chain1**: Fragments TLS ClientHello into 100-200 byte chunks with 10-20ms delays. Routes through `fragment-chain2`.
|
|
3. **fragment-chain2**: Further fragments initial packets (1-3) into 1-5 byte micro-chunks with 1-2ms delays. Also injects UDP noise packets (random data + fake DNS-like queries).
|
|
|
|
This triple-layer approach makes TLS fingerprinting extremely difficult for TSPU.
|
|
|
|
### Key Tuning Notes
|
|
- **Port**: Use a high random port (47000+), NOT 443. Port 443 faces the strictest blocking.
|
|
- **Fingerprint**: `chrome` is recommended. Some reports suggest `random` or even empty fingerprint can work when chrome is blocked.
|
|
- **Mux**: Enabled to reduce repeated TLS handshakes (each handshake is a detection opportunity). `concurrency: 8` is a good balance.
|
|
- **Fragment `interval: 0`** with `tlshello`: All fragments go in a single TCP packet if they fit — useful when timing-based detection is used.
|
|
|
|
### Pros
|
|
- Vision flow = no double encryption, best raw performance
|
|
- Fragment chains defeat most DPI signature matching
|
|
- UDP noise adds a layer of traffic obfuscation
|
|
- Mux reduces handshake frequency
|
|
- Non-standard port avoids port-443 targeting
|
|
|
|
### Cons
|
|
- Still a single persistent TCP connection (vulnerable to volume-based freezing)
|
|
- Fragmentation adds latency to connection establishment
|
|
- Noise can occasionally disrupt connections
|
|
- More aggressive DPI can reassemble fragments
|
|
|
|
### When to Use
|
|
- When basic TCP+Reality stopped working but XHTTP is not yet configured
|
|
- As a quick enhancement to existing TCP+Reality setups
|
|
- When you specifically need Vision flow for performance
|
|
- When the primary issue is TLS handshake blocking (not volume-based freezing)
|
|
|
|
---
|
|
|
|
## Configuration #5: VLESS + WebSocket + TLS behind CDN <a name="config-5"></a>
|
|
|
|
**Effectiveness: MEDIUM — ultimate fallback when direct connections are impossible**
|
|
|
|
When all direct connections to foreign IPs are blocked, routing through a CDN (Cloudflare, Gcore, etc.) hides the actual server IP entirely. The CDN's IP ranges are typically whitelisted because blocking them would break too much of the internet.
|
|
|
|
### Server Configuration (with Nginx terminating TLS)
|
|
|
|
```json
|
|
{
|
|
"log": {
|
|
"loglevel": "warning"
|
|
},
|
|
"inbounds": [
|
|
{
|
|
"tag": "ws-in",
|
|
"listen": "127.0.0.1",
|
|
"port": 8080,
|
|
"protocol": "vless",
|
|
"settings": {
|
|
"clients": [
|
|
{
|
|
"id": "YOUR-UUID-HERE",
|
|
"flow": ""
|
|
}
|
|
],
|
|
"decryption": "none"
|
|
},
|
|
"streamSettings": {
|
|
"network": "ws",
|
|
"wsSettings": {
|
|
"path": "/your-ws-secret-path",
|
|
"headers": {
|
|
"Host": "your-domain.com"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
"protocol": "freedom",
|
|
"tag": "direct"
|
|
},
|
|
{
|
|
"protocol": "blackhole",
|
|
"tag": "block"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Nginx Configuration (snippet)**:
|
|
```nginx
|
|
server {
|
|
listen 443 ssl http2;
|
|
server_name your-domain.com;
|
|
|
|
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
|
|
|
|
location /your-ws-secret-path {
|
|
proxy_redirect off;
|
|
proxy_pass http://127.0.0.1:8080;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
}
|
|
|
|
location / {
|
|
# Serve a real website as camouflage
|
|
root /var/www/html;
|
|
index index.html;
|
|
}
|
|
}
|
|
```
|
|
|
|
### Client Configuration
|
|
|
|
```json
|
|
{
|
|
"log": {
|
|
"loglevel": "warning"
|
|
},
|
|
"inbounds": [
|
|
{
|
|
"tag": "socks-in",
|
|
"listen": "127.0.0.1",
|
|
"port": 10808,
|
|
"protocol": "socks",
|
|
"settings": {
|
|
"udp": true
|
|
}
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
"tag": "proxy",
|
|
"protocol": "vless",
|
|
"settings": {
|
|
"vnext": [
|
|
{
|
|
"address": "your-domain.com",
|
|
"port": 443,
|
|
"users": [
|
|
{
|
|
"id": "YOUR-UUID-HERE",
|
|
"encryption": "none",
|
|
"flow": ""
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"streamSettings": {
|
|
"network": "ws",
|
|
"wsSettings": {
|
|
"path": "/your-ws-secret-path",
|
|
"headers": {
|
|
"Host": "your-domain.com"
|
|
}
|
|
},
|
|
"security": "tls",
|
|
"tlsSettings": {
|
|
"serverName": "your-domain.com",
|
|
"fingerprint": "chrome",
|
|
"allowInsecure": false
|
|
}
|
|
},
|
|
"mux": {
|
|
"enabled": true,
|
|
"concurrency": 8,
|
|
"xudpConcurrency": 16,
|
|
"xudpProxyUDP443": "reject"
|
|
}
|
|
},
|
|
{
|
|
"tag": "direct",
|
|
"protocol": "freedom"
|
|
}
|
|
],
|
|
"routing": {
|
|
"domainStrategy": "AsIs",
|
|
"rules": [
|
|
{
|
|
"type": "field",
|
|
"domain": [
|
|
"geosite:private"
|
|
],
|
|
"outboundTag": "direct"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### CDN Setup Notes (Cloudflare)
|
|
1. Add your domain to Cloudflare
|
|
2. Point DNS A record to your server IP with orange cloud (proxied) enabled
|
|
3. SSL/TLS mode: Full (Strict)
|
|
4. Under Network, enable WebSockets
|
|
5. Optionally enable gRPC for a gRPC-based variant
|
|
|
|
### Pros
|
|
- Server IP is completely hidden behind CDN
|
|
- CDN IP ranges are almost never blocked (too much collateral damage)
|
|
- Real TLS certificate = perfect TLS fingerprint
|
|
- Serves a real website as camouflage
|
|
- Works even when all foreign datacenter IPs are blocked
|
|
|
|
### Cons
|
|
- Lower performance due to CDN overhead
|
|
- WebSocket is a somewhat distinctive protocol pattern
|
|
- Requires a domain name and real TLS certificates
|
|
- Cloudflare free tier has bandwidth considerations
|
|
- Double encryption (TLS at CDN + TLS to origin) adds overhead
|
|
- CDN can inspect your traffic in theory
|
|
|
|
### When to Use
|
|
- When ALL direct connections to foreign IPs are blocked
|
|
- As an emergency fallback
|
|
- When CIDR-based blocking is in effect and no Russian bridge is available
|
|
- For low-bandwidth usage (browsing, messaging)
|
|
|
|
---
|
|
|
|
## Configuration #6: Shadowsocks 2022 + XHTTP (Bonus) <a name="config-6"></a>
|
|
|
|
**Effectiveness: MEDIUM — alternative protocol with different fingerprint**
|
|
|
|
Shadowsocks 2022 (with `2022-blake3-aes-256-gcm` cipher) is a fundamentally different protocol from VLESS. Using it provides protocol diversity — if VLESS-specific signatures are being targeted, SS2022 presents a completely different pattern.
|
|
|
|
### Server Configuration
|
|
|
|
```json
|
|
{
|
|
"log": {
|
|
"loglevel": "warning"
|
|
},
|
|
"inbounds": [
|
|
{
|
|
"tag": "ss-in",
|
|
"listen": "0.0.0.0",
|
|
"port": 8388,
|
|
"protocol": "shadowsocks",
|
|
"settings": {
|
|
"method": "2022-blake3-aes-256-gcm",
|
|
"password": "BASE64-32-BYTE-KEY-HERE",
|
|
"network": "tcp,udp"
|
|
},
|
|
"streamSettings": {
|
|
"network": "tcp"
|
|
}
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
"protocol": "freedom",
|
|
"tag": "direct"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Client Configuration
|
|
|
|
```json
|
|
{
|
|
"log": {
|
|
"loglevel": "warning"
|
|
},
|
|
"inbounds": [
|
|
{
|
|
"tag": "socks-in",
|
|
"listen": "127.0.0.1",
|
|
"port": 10808,
|
|
"protocol": "socks",
|
|
"settings": {
|
|
"udp": true
|
|
}
|
|
}
|
|
],
|
|
"outbounds": [
|
|
{
|
|
"tag": "proxy",
|
|
"protocol": "shadowsocks",
|
|
"settings": {
|
|
"servers": [
|
|
{
|
|
"address": "YOUR-SERVER-IP",
|
|
"port": 8388,
|
|
"method": "2022-blake3-aes-256-gcm",
|
|
"password": "BASE64-32-BYTE-KEY-HERE"
|
|
}
|
|
]
|
|
},
|
|
"streamSettings": {
|
|
"network": "tcp",
|
|
"sockopt": {
|
|
"dialerProxy": "fragment-out"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"tag": "fragment-out",
|
|
"protocol": "freedom",
|
|
"settings": {
|
|
"fragment": {
|
|
"packets": "1-2",
|
|
"length": "100-200",
|
|
"interval": "10-20"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"tag": "direct",
|
|
"protocol": "freedom"
|
|
}
|
|
],
|
|
"routing": {
|
|
"domainStrategy": "AsIs",
|
|
"rules": [
|
|
{
|
|
"type": "field",
|
|
"domain": [
|
|
"geosite:private"
|
|
],
|
|
"outboundTag": "direct"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Note on Key Generation
|
|
Generate a 32-byte base64 key: `openssl rand -base64 32`
|
|
|
|
### Pros
|
|
- Different protocol fingerprint from VLESS (protocol diversity)
|
|
- Simpler configuration
|
|
- No TLS layer to fingerprint (encrypted from the start)
|
|
- Lightweight and fast
|
|
- SS2022 has replay protection and modern AEAD encryption
|
|
|
|
### Cons
|
|
- No Reality camouflage (traffic is encrypted but does not impersonate HTTPS)
|
|
- Easier to identify as "not standard traffic" by statistical analysis
|
|
- Cannot use Vision flow
|
|
- Less actively developed than VLESS in the Xray ecosystem
|
|
- Vulnerable to active probing (server responds differently to valid vs invalid packets)
|
|
|
|
### When to Use
|
|
- As a protocol diversity option alongside VLESS configurations
|
|
- When VLESS-specific blocking is suspected
|
|
- For quick, simple setups where maximum stealth is not required
|
|
- On networks where encrypted-but-unidentified traffic is not blocked
|
|
|
|
---
|
|
|
|
## Cross-Cutting Techniques <a name="cross-cutting"></a>
|
|
|
|
### TLS Fingerprint Selection
|
|
|
|
| Fingerprint | Recommendation | Notes |
|
|
|-------------|---------------|-------|
|
|
| `chrome` | **Primary choice** | Most common browser, blends best |
|
|
| `firefox` | Good alternative | Use if chrome is specifically targeted |
|
|
| `safari` | Niche | Less common on non-Apple platforms, may stand out |
|
|
| `random` | Experimental | Can work when specific fingerprints are blocked |
|
|
| `""` (empty/Go default) | Last resort | Paradoxically helps in some regions — removes the fingerprint entirely |
|
|
|
|
### Mux (Multiplexing) Configuration
|
|
|
|
Mux reduces the number of TLS handshakes by multiplexing multiple connections over one. This is important because each TLS handshake is a detection opportunity.
|
|
|
|
```json
|
|
{
|
|
"mux": {
|
|
"enabled": true,
|
|
"concurrency": 8,
|
|
"xudpConcurrency": 16,
|
|
"xudpProxyUDP443": "reject"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Important notes**:
|
|
- Mux reduces handshake latency, NOT throughput. Video/downloads may be slower.
|
|
- `xudpProxyUDP443: "reject"` forces QUIC traffic to fall back to TCP HTTP/2, which is better for stealth.
|
|
- Do NOT use Mux with `flow: xtls-rprx-vision` — they are incompatible.
|
|
- Mux is beneficial with gRPC, WebSocket, and XHTTP transports.
|
|
|
|
### UDP Noise Injection
|
|
|
|
Add to any `freedom` outbound to inject noise before UDP connections:
|
|
|
|
```json
|
|
{
|
|
"noises": [
|
|
{
|
|
"type": "rand",
|
|
"packet": "50-150",
|
|
"delay": "10-16"
|
|
},
|
|
{
|
|
"type": "base64",
|
|
"packet": "7nQBAAABAAAAAAAABnQtcmluZwZtc2VkZ2UDbmV0AAABAAE=",
|
|
"delay": "10-16"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Notes**: Noise automatically bypasses port 53 (DNS). The `base64` example above mimics a DNS query packet. The `rand` type generates random bytes of the specified length range.
|
|
|
|
### TCP Fragment Settings
|
|
|
|
Add to any `freedom` outbound used as a dialer proxy:
|
|
|
|
```json
|
|
{
|
|
"fragment": {
|
|
"packets": "tlshello",
|
|
"length": "100-200",
|
|
"interval": "10-20"
|
|
}
|
|
}
|
|
```
|
|
|
|
- `"packets": "tlshello"` — only fragment TLS ClientHello (most effective)
|
|
- `"packets": "1-3"` — fragment first 1-3 data writes (more aggressive)
|
|
- `"interval": "0"` — send all fragments in a single TCP packet (defeats timing-based analysis)
|
|
|
|
### XHTTP Padding (xPaddingBytes)
|
|
|
|
Unique to XHTTP transport — adds random padding to every request/response:
|
|
|
|
```json
|
|
"extra": {
|
|
"xPaddingBytes": "100-1000"
|
|
}
|
|
```
|
|
|
|
This randomizes packet sizes, defeating statistical traffic analysis.
|
|
|
|
---
|
|
|
|
## Performance Comparison <a name="performance"></a>
|
|
|
|
| Configuration | Throughput | Latency | Handshake Overhead | Stealth |
|
|
|--------------|------------|---------|-------------------|---------|
|
|
| XHTTP + Reality | High | Low | Low (multiplexed) | Highest |
|
|
| Chain Relay (XHTTP) | Medium | Medium (+hop) | Low | Highest |
|
|
| gRPC + Reality | High | Low | Low (H2 mux) | High |
|
|
| TCP + Reality + Vision + Fragment | Highest | Medium (fragments) | Medium | Medium-High |
|
|
| WebSocket + TLS + CDN | Low-Medium | High (+CDN) | High | High (IP hidden) |
|
|
| Shadowsocks 2022 | High | Low | Low | Medium |
|
|
|
|
### Throughput Optimization Tips
|
|
|
|
1. **For maximum throughput**: TCP + Reality + Vision (no double encryption)
|
|
2. **For XHTTP**: Set `maxConcurrency: 1` in xmux settings for speed tests; use `16-32` for normal browsing
|
|
3. **For gRPC**: Enable `multiMode: true` and set `initial_windows_size: 65536` or higher
|
|
4. **Buffer tuning**: On Linux servers, increase TCP buffer sizes:
|
|
```bash
|
|
sysctl -w net.core.rmem_max=16777216
|
|
sysctl -w net.core.wmem_max=16777216
|
|
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
|
|
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
|
|
```
|
|
5. **BBR congestion control**: Enable on the server:
|
|
```bash
|
|
sysctl -w net.core.default_qdisc=fq
|
|
sysctl -w net.ipv4.tcp_congestion_control=bbr
|
|
```
|
|
|
|
---
|
|
|
|
## DNS Strategies <a name="dns"></a>
|
|
|
|
### Recommended DNS Configuration for Russian Users
|
|
|
|
```json
|
|
{
|
|
"dns": {
|
|
"servers": [
|
|
{
|
|
"address": "https://1.1.1.1/dns-query",
|
|
"domains": [
|
|
"geosite:geolocation-!cn"
|
|
]
|
|
},
|
|
{
|
|
"address": "https://dns.google/dns-query",
|
|
"domains": [
|
|
"geosite:geolocation-!cn"
|
|
]
|
|
},
|
|
{
|
|
"address": "77.88.8.8",
|
|
"domains": [
|
|
"geosite:category-ru"
|
|
],
|
|
"expectIPs": [
|
|
"geoip:ru"
|
|
]
|
|
},
|
|
"localhost"
|
|
],
|
|
"queryStrategy": "UseIPv4"
|
|
}
|
|
}
|
|
```
|
|
|
|
### DNS Tips
|
|
- **Always use DoH (DNS over HTTPS)** for foreign domains — plain DNS is trivially intercepted by TSPU
|
|
- Use Yandex DNS (77.88.8.8) for Russian domains — faster and avoids routing issues
|
|
- `queryStrategy: "UseIPv4"` avoids IPv6 issues on networks that partially block it
|
|
- Enable DNS sniffing in inbound settings to correctly route DNS queries through the proxy
|
|
|
|
---
|
|
|
|
## New Features in Xray v26.x (2026)
|
|
|
|
Xray v26.1.23 and v26.2.6 introduced several features relevant to anti-censorship:
|
|
|
|
1. **TUN inbound**: Native transparent proxy on Windows, Linux, Android — no need for external tun2socks
|
|
2. **Hysteria 2 outbound + transport**: UDP-based protocol with UDP hop support — works when TCP is heavily throttled
|
|
3. **Finalmask options**:
|
|
- **XICMP**: Disguise traffic as ICMP packets
|
|
- **XDNS**: Tunnel traffic inside DNS queries (similar to DNSTT)
|
|
- **header-\*, mkcp-\*** variants
|
|
4. **Dynamic Chrome User-Agent**: HTTP requests use realistic Chrome UA by default instead of Go's default
|
|
5. **Removed `allowInsecure`**: Replaced with `pinnedPeerCertSha256` and `verifyPeerCertByName` for proper cert verification
|
|
6. **Reduced startup memory**: Improved geodat handling
|
|
7. **Upcoming XDRIVE transport**: Use cloud storage / S3 services for data transmission without requiring a public IP server
|
|
|
|
---
|
|
|
|
## Summary: Recommended Strategy for Russia (2025-2026)
|
|
|
|
**Primary**: VLESS + XHTTP + Reality (Config #1) on a non-443 port
|
|
|
|
**Secondary**: VLESS + gRPC + Reality (Config #3) — different traffic pattern, same stealth level
|
|
|
|
**Fallback**: VLESS + WebSocket + TLS behind Cloudflare CDN (Config #5) — when direct connections die
|
|
|
|
**Nuclear option**: Chain relay via Russian bridge (Config #2) — when CIDR whitelisting is active
|
|
|
|
**Always apply**: Fragment chains + noise on the client side (Config #4 techniques) regardless of transport choice
|
|
|
|
**Keep multiple configurations ready** — the TSPU blocking patterns change frequently (weekly in some regions), and what works today may not work tomorrow. The Russian anti-censorship community on ntc.party and net4people/bbs on GitHub are the best sources for real-time information about what is currently working.
|