Skip to content

VLESS + XTLS + Reality with Nginx Proxy

Please follow the local regulations and use VPN responsibly.

MacOS Hosting

Install pre-requisites

Install homebrew if you haven't already, and install xray.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install xray

Get the credentials

Get xray uuid by

xray uuid

Get the reality public and private keys by

xray x25519

Configure xray

The following is a sample configuration for xray with VLESS, XTLS, and Reality. Adjust the IP address and other parameters as needed. This file should be saved as /opt/homebrew/etc/xray/config.json.

{
  "log": {
    "loglevel": "warning" 
  },
  "inbounds": [
    {
      "listen": "0.0.0.0",
      "_comment": "Change to your server's IP address, or keep as 0.0.0.0 if you want to listen on all interfaces",
      "port": 443,
      "_comment": "Advise to use port 443 for obfuscation, but you can change it to any port you prefer",
      "protocol": "vless",
      "settings": {
        "clients": [
          {
            "id": "",
            "_comment": "Replace with your xray uuid",
            "flow": "xtls-rprx-vision"
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "raw",
        "security": "reality",
        "realitySettings": {
          "show": true,
          "target": "hostname:443",
          "_comment": "Replace 'hostname' with a server name you prefer that you want to obfuscate with",
          "serverNames": [
            "hostname"
          ],
          "_comment": "Replace 'hostname' with the same server name as above",
          "privateKey": "private_key_here",
          "_comment": "Replace with your reality private key",
          "shortIds": [
            "short_id_here"
          ],
          "_comment": "Replace with your reality short ID, can be any random string, or you can generate it with `openssl rand -hex 16` or any hex with even length",
        }
      },
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls", "quic"]
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "settings": {}
    },
    {
      "protocol": "blackhole",
      "settings": {},
      "tag": "blocked"
    }
  ],
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
    ]
  }
}

Firewall Configuration

If you are using a firewall, ensure that port 443 (the port that you wish to use) is open for incoming connections. For example, if you are using pfctl on MacOS, you can add a rule like this:

echo "pass in proto tcp from any to any port 443" | sudo pfctl -f /etc/pf.conf
sudo pfctl -f /etc/pf.conf
sudo pfctl -e

xray Service

To run xray as a service, you can generate a launch daemon plist file. Create a file at /Library/LaunchDaemons/org.xray.plist with the following content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.xray.server</string>
        <key>ProgramArguments</key>
        <array>
            <string>/opt/homebrew/bin/xray</string>
            <string>run</string>
            <string>-c</string>
            <string>/opt/homebrew/etc/xray/config.json</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>KeepAlive</key>
        <true/>
        <key>StandardOutPath</key>
        <string>/var/log/xray/out.log</string>  
        <key>StandardErrorPath</key>
        <string>/var/log/xray/error.log</string> 
    </dict>
</plist>

You can load this service with (start it automatically at boot):

sudo launchctl load /Library/LaunchDaemons/org.xray.plist

and unload it with (stop it):

sudo launchctl unload /Library/LaunchDaemons/org.xray.plist

Linux Hosting

Install pre-requisites

Install xray on your Linux server. (Ubuntu/Debian example)

sudo apt update
sudo apt install xray

Get the credentials

Get xray uuid by

xray uuid

Get the reality public and private keys by

xray x25519

Configure xray

The following is a sample configuration for xray with VLESS, XTLS, and Reality. Adjust the IP address and other parameters as needed. This file should be saved as /usr/local/etc/xray/config.json.

{
  "log": {
    "loglevel": "warning" 
  },
  "inbounds": [
    {
      "listen": "0.0.0.0",
      "_comment": "Change to your server's IP address, or keep as 0.0.0.0 if you want to listen on all interfaces",
      "port": 443,
      "_comment": "Advise to use port 443 for obfuscation, but you can change it to any port you prefer",
      "protocol": "vless",
      "settings": {
        "clients": [
          {
            "id": "",
            "_comment": "Replace with your xray uuid",
            "flow": "xtls-rprx-vision"
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "raw",
        "security": "reality",
        "realitySettings": {
          "show": true,
          "target": "hostname:443",
          "_comment": "Replace 'hostname' with a server name you prefer that you want to obfuscate with",
          "serverNames": [
            "hostname"
          ],
          "_comment": "Replace 'hostname' with the same server name as above",
          "privateKey": "private_key_here",
          "_comment": "Replace with your reality private key",
          "shortIds": [
            "short_id_here"
          ],
          "_comment": "Replace with your reality short ID, can be any random string, or you can generate it with `openssl rand -hex 16` or any hex with even length",
        }
      },
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls", "quic"]
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "settings": {}
    },
    {
      "protocol": "blackhole",
      "settings": {},
      "tag": "blocked"
    }
  ],
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
    ]
  }
}

Remember to configure your firewall to allow incoming connections.

xray Service

To run xray as a service, you can create a systemd service file. Create a file at /etc/systemd/system/xray.service with the following content:

[Unit]
Description=Xray Service
After=network.target
[Service]
ExecStart=/usr/bin/xray run -c /usr/local/etc/xray/config.json
Restart=on-failure
[Install]
WantedBy=multi-user.target

Which can be enabled to start at boot with:

sudo systemctl enable xray
sudo systemctl start xray

Nginx Proxy Server

In the nginx.conf file, you can set up a block to forward the requests (not inside the http block):

stream {
    server {
        listen 443;
        proxy_pass hostname:443;
    }
}

Configuration (Shadowrocket)

  • Server Type: VLESS
  • Address: Your server's IP or domain (nginx proxy server if used)
  • Port: 443 (or the port you configured/nginx proxy port if used)
  • UUID: Your xray UUID
  • Transport: none
  • TLS:
    • TLS: on
    • Allow Insecure: on
      • SNI: hostname (the same as in the xray config)
    • HTTP2: on
    • XTLS: xtls-rprx-vision
    • Public Key: Your Reality public key
    • Short ID: Your Reality short ID
    • Fragment: Off
  • Muxing: Off
  • TCP Fast Open: Off
  • UDP Relay: Off