Introduction: The Reverse Proxy as the First Line of Stealth
When deploying V2Ray using stealth transports like WebSocket (wSS), gRPC, or even Trojan, it is critically important to run the tunnel on the standard HTTPS Port 443. Doing so allows the V2Ray traffic to hide among the massive volume of legitimate, secure web traffic.
However, running V2Ray directly on Port 443 is often insufficient. What happens when a human user or an automated probe tries to load a real website from your server IP? If V2Ray only handles the proxy, the request fails, leading to suspicious behavior.
The solution is the Reverse Proxy. A reverse proxy (Nginx or Caddy) sits on Port 443 and acts as an intelligent traffic guard. It intercepts every incoming request and performs a critical check:
- If the request is for your secret V2Ray path or protocol, it is silently forwarded to V2Ray running on a private, local port (e.g.,
127.0.0.1:10000). - If the request is for a normal webpage (e.g.,
www.mydecoyblog.com), it is served by a real web server (Nginx/Caddy).
This setup ensures your server always responds like a normal, functioning web host, effectively defeating active probing and advanced censorship analysis.
Section 1: The Essential Role of Nginx
Nginx is the most popular choice for V2Ray integration due to its stability, low resource consumption, and powerful routing rules.
1. Nginx Prerequisites
Before configuring Nginx, V2Ray must be running on a private, local port, typically using the address 127.0.0.1.
// V2Ray Inbound listening on a private local port, ready to receive traffic from Nginx
"inbounds": [
{
"port": 10000, // Private port, only accessible by localhost
"listen": "127.0.0.1",
"protocol": "vless",
"streamSettings": {
"network": "ws",
"security": "none", // Nginx handles the public-facing TLS, so V2Ray's TLS is OFF here
// ... wsSettings with path ...
}
}
]
2. Nginx WebSocket Configuration
The Nginx configuration (in a file like /etc/nginx/conf.d/v2ray.conf) requires three critical directives to correctly handle the WebSocket upgrade process and forward the traffic to V2Ray.
proxy_pass: Directs traffic to the V2Ray’s local listening port.proxy_http_version 1.1: Essential for supporting WebSockets.Proxy Upgrade Headers: Crucial headers (UpgradeandConnection) are needed to signal to Nginx that this connection should be upgraded from a standard HTTP request to a persistent WebSocket tunnel.
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name my.domain.com;
# 1. Standard SSL Configuration (Nginx handles the public TLS)
ssl_certificate /path/to/fullchain.cer;
ssl_certificate_key /path/to/private.key;
# 2. Decoy Website Block (Handles normal browsing)
location / {
root /var/www/html/mydecoyblog;
index index.html;
}
# 3. V2Ray Tunnel Block (The Reverse Proxy Magic)
location /my-secret-path {
# Pass the traffic to V2Ray's local private port
proxy_pass [http://127.0.0.1:10000](http://127.0.0.1:10000);
# Mandatory headers for WebSocket upgrade
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Pass the client's original IP to V2Ray for logging/routing
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
}
Section 2: The Modern Alternative: Caddy
Caddy is a modern, HTTP/2-enabled web server that has become highly popular for V2Ray integration, particularly because of its automatic, integrated TLS management.
Caddy’s Automatic Advantages
- Zero-Configuration TLS: Caddy automatically obtains and renews Let’s Encrypt certificates for your domain, eliminating the manual steps of certificate management required by Nginx.
- Simplified Config: Caddy’s configuration file (Caddyfile) is much simpler and more readable than Nginx’s verbose structure.
Caddy WebSocket Configuration
Caddy handles the necessary upgrade headers automatically, simplifying the configuration dramatically.
Example Caddyfile:
my.domain.com:443 {
# Caddy automatically handles TLS acquisition and renewal here
# 1. Decoy Website Root (Handles normal browsing)
root * /var/www/html/mydecoyblog
file_server
# 2. V2Ray Tunnel Block (Reverse Proxy)
handle /my-secret-path {
# Reverse Proxy the WebSocket traffic to V2Ray's local port
reverse_proxy 127.0.0.1:10000 {
# Standard Caddy optimization flags for long-lived connections
header_up Host {http.request.host}
header_up X-Forwarded-For {http.request.remote}
header_up Connection "Upgrade"
header_up Upgrade "websocket"
}
}
}
The handle directive ensures that only traffic matching the /my-secret-path is forwarded to V2Ray, while all other traffic is handled by the static file_server.
Section 3: Trojan and gRPC Integration
While Nginx and Caddy are primarily known for HTTP/WebSocket handling, they are also essential for Trojan and gRPC deployments.
Trojan Fallback Integration
As detailed in Article 26, the Trojan protocol uses V2Ray’s internal fallbacks to redirect non-Trojan traffic. If you use this, the reverse proxy must redirect the traffic to V2Ray’s Inbound before the V2Ray Inbound redirects it to the Nginx decoy site. This creates a redirection loop that must be handled carefully.
- The Best Practice: Configure Nginx/Caddy on Port 443 with the SSL certificate, and use Nginx/Caddy’s configuration to redirect all normal HTTP (Port 80) traffic to HTTPS (Port 443). Then, use the V2Ray Fallback system to handle the final routing decision on Port 443, forwarding failed connections to Nginx/Caddy running on a non-standard local port (e.g., 8080) for the decoy page.
gRPC Service Proxying
For gRPC (Article 16), Nginx and Caddy must be configured to recognize the unique service request structure of HTTP/2.
- Nginx Requirement: Requires the use of
grpc_passdirective, which is designed specifically for HTTP/2 streaming. - Caddy Advantage: Caddy handles gRPC requests automatically because of its native HTTP/2 support. The
reverse_proxydirective is sufficient to manage the gRPC traffic.
Section 4: Importance of the X-Forwarded-For Header
When a reverse proxy is used, the source IP address V2Ray sees is no longer the client’s actual IP address. It is the IP address of the last hop—the reverse proxy (usually 127.0.0.1 or the internal network of Cloudflare).
- The Problem: Without the original IP, V2Ray cannot accurately log usage, track statistics, or apply Geo-IP routing rules (Article 19).
- The Solution: The
proxy_set_header X-Real-IP $remote_addr;directive in Nginx (or its equivalent in Caddy) forces the reverse proxy to extract the client’s original IP address from the request header and insert it into a new header, typicallyX-Forwarded-FororX-Real-IP.
V2Ray is configured to read this header and use the client’s true source IP for all routing, policy, and logging decisions, maintaining the integrity of the security and management system.
Conclusion: Securing the Public Face
Integrating V2Ray with a reverse proxy like Nginx or Caddy is a non-negotiable step for achieving professional-grade stealth. It solves the critical problem of masquerading your proxy as a legitimate web service by providing a clean, standard response to all external probes. Whether you prefer the granular control of Nginx or the automatic certificate management of Caddy, mastering the reverse proxy configuration is key to protecting your V2Ray server’s IP address and ensuring long-term operational resilience.