Files
ai-xray/XRAY_ANTI_DPI_CONFIGURATIONS.md
2026-03-08 07:09:56 +00:00

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.