Setting up a V2Ray server with OpenResty as the reverse proxy and Cloudflare for added security can be a bit complex. I wrote this post to document my attempts and findings after a few hours of work, both for my reference and to assist others who might find it useful.

Prerequisites

  • A VPS server running CentOS

  • Docker and Docker Compose installed

  • OpenResty installed, better in docker as well

  • A domain managed by Cloudflare using TLS

Step 0: Preparing the DIR

mkdir -p /path/to/your/v2ray
cd /path/to/your/v2ray
touch docker-compose.yaml
mkdir config
cd config
touch config.json

Step 1: Docker Compose Configuration

Change the content of the docker-compose.yml file to define the V2Ray service.

services:
  v2ray:
    image: v2fly/v2fly-core
    container_name: v2ray
    entrypoint: ["/bin/sh", "-c", "while true; do sleep 30; done;"] # entrypoint for running container without initializing the v2ray, better for playing commands inside the container once it started.
    ports:
      - "1080:1080"  # Local proxy port for local applications on the VPS
      - "12345:12345"  # Main port for external V2Ray clients
    volumes:
      - ./config/config.json:/etc/v2ray/config.json  # the config file which will be used as a the config for v2ray running in the container

Step 2: V2Ray Configuration

Change the content of config.json file in the config directory to define V2Ray settings.

{
  "log": {
    "access": "/etc/v2ray/access.log",
    "error": "/etc/v2ray/error.log",
    "loglevel": "debug"
  },
  "inbounds": [
    {
      "port": 12345, # port for v2ray to listen to as a container, not the port for the server
      "protocol": "vmess",
      "settings": {
        "clients": [
          {
            "id": "your-uuid-here", # generate online or using commands
            "alterId": 64
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "none",  // Disable TLS in V2Ray, let Nginx handle it
        "wsSettings": {
          "path": "/v2ray",
          "headers": {
            "Host": "Your-Host-Name" # Your host name
          }
        }
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "settings": {}
    }
  ]
}

Replace your-uuid-here with a UUID you generate for your V2Ray client and Your-Host-Name with your website host name which is proxied by Cloudflare

Step 3: OpenResty (Nginx) Configuration

Edit your OpenResty (Nginx) configuration file to include the reverse proxy settings. Ensure this configuration is added to your server block.

# nginx

server {
    # Regular server setups
	... ...
    # V2Ray WebSocket configuration
    location /v2ray {
        proxy_redirect off; 
        proxy_pass http://127.0.0.1:12345; # port for nginx to forward to, which will be listened by the v2ray container
        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; 
        proxy_set_header X-Forwarded-Proto $scheme; 
    }
	# Reverse proxy for all other traffics pointing to the website container
	location / { # notice this config, location / will handle all the traffic except the one used by v2ray: /v2ray
    proxy_pass http://127.0.0.1:8081; 
    proxy_set_header Host $host; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header REMOTE-HOST $remote_addr; 
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection "upgrade"; 
    proxy_set_header X-Forwarded-Proto $scheme; 
    proxy_http_version 1.1; 
    add_header X-Cache $upstream_cache_status; 
    add_header Strict-Transport-Security "max-age=31536000"; 
    add_header Cache-Control no-cache; 
	}

}

Step 4: Client Configuration

Configure your V2Ray client with the following settings:

{
  "v": "2",
  "ps": "yourprofilename",
  "add": "yourdomain.com",
  "port": "443",
  "id": "your-uuid-here",
  "aid": "64",
  "net": "ws",
  "type": "none",
  "host": "yourdomain.com",
  "path": "/v2ray",
  "tls": "tls"
}

Encode this configuration into a VMess URI using an online encoder or script. You should eventually get something like:

vmess://... ...

Step 5: Import URI to your V2Ray Client

You can search for clients in IOS/ Android App stores or checking here:

https://www.v2ray.com/en/awesome/tools.html

Advantages:

1. Enhanced Security and Privacy

  • IP Masking: Cloudflare masks your server's IP address, providing an additional layer of security against DDoS attacks and other threats.

  • Encryption: TLS encryption ensures that all traffic between the client and the server is encrypted, preventing eavesdropping and man-in-the-middle attacks.

2. Bypass Censorship

  • Obfuscation: By using WebSockets and disguising traffic as regular HTTPS traffic, it becomes much harder for firewalls and censorship mechanisms to detect and block your VPN traffic.

  • Domain Fronting: With Cloudflare, your traffic appears to be going to a legitimate website, making it difficult for censorship tools to identify and block the VPN usage.

3. Improved Performance

  • CDN Benefits: Cloudflare's CDN can cache and serve static content, potentially improving the load times for your website for users around the world.

  • Load Balancing: Cloudflare offers load balancing features that can distribute traffic across multiple servers, enhancing performance and reliability.

4. Flexible Configuration

  • Reverse Proxy: OpenResty (Nginx) acts as a reverse proxy, allowing you to easily manage and route traffic to different services (such as your website and V2Ray server) on the same domain.

  • Modular Setup: The configuration is modular, meaning you can adjust and scale each component (V2Ray, OpenResty, Cloudflare) independently based on your needs.

5. Anonymity

  • Client Anonymity: The client's IP is hidden from the destination websites, as the traffic appears to come from your V2Ray server. This provides an additional layer of anonymity for the client.

  • Traffic Concealment: External observers will see the traffic as regular HTTPS traffic to your domain, making it difficult to detect that a VPN or proxy service is being used.

6. Easy Management

  • Dockerized Deployment: Using Docker and Docker Compose simplifies the deployment and management of your V2Ray server, making it easy to start, stop, and update the service.

  • Logging and Debugging: Both V2Ray and OpenResty provide logging mechanisms, allowing you to monitor traffic, detect issues, and perform troubleshooting effectively.

7. Scalability

  • Scalable Infrastructure: With Cloudflare in front, you can easily scale your backend servers without changing the client configuration. Cloudflare will continue to handle the load balancing and IP masking.

8. Cost-Effective

  • Free Features: Many of Cloudflare's basic features, including CDN, DNS, and DDoS protection, are available for free, making it a cost-effective solution for enhancing security and performance.