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

37 KiB

State-of-the-Art Xray Anti-DPI Configurations for Russia (2025-2026)

Table of Contents

  1. Background: Russian DPI (TSPU) Current Capabilities
  2. Configuration #1: VLESS + XHTTP + Reality (RANKED #1)
  3. Configuration #2: Chain Relay — VLESS + XHTTP via Russian Bridge Node (RANKED #2)
  4. Configuration #3: VLESS + gRPC + Reality (RANKED #3)
  5. Configuration #4: VLESS + TCP + Reality + Fragment/Noise Chains (RANKED #4)
  6. Configuration #5: VLESS + WebSocket + TLS behind CDN (RANKED #5)
  7. Configuration #6: Shadowsocks 2022 + XHTTP (Bonus)
  8. Cross-Cutting Techniques
  9. Performance Comparison
  10. DNS Strategies

Background: Russian DPI (TSPU) Current Capabilities

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)

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

{
  "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

{
  "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

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

{
  "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

{
  "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

{
  "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

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

{
  "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

{
  "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

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

{
  "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)

{
  "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

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)

{
  "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):

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

{
  "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)

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

{
  "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

{
  "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

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.

{
  "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:

{
  "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:

{
  "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:

"extra": {
  "xPaddingBytes": "100-1000"
}

This randomizes packet sizes, defeating statistical traffic analysis.


Performance Comparison

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:
    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:
    sysctl -w net.core.default_qdisc=fq
    sysctl -w net.ipv4.tcp_congestion_control=bbr
    

DNS Strategies

{
  "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

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.