Setting Up V2Ray with NGINX + WebSocket + TLS

2 years ago

V2Ray is a platform for building proxies to bypass network restrictions.

The following instructions are based on Ubuntu Server 20.04.

Step 1. Domain & DNS

Buy a domain name and configure its DNS records to point to your server.

Step 2. Install V2Ray

We will use fhs-install-v2ray installing script for convenience.

Simply run:

bash <(curl -L

Step 3. Install NGINX & Certbot


apt update
apt install nginx certbot python3-certbot-nginx

Step 4. Configure V2Ray

Edit /usr/local/etc/v2ray/config.json:

nano /usr/local/etc/v2ray/config.json

Use this configuration:

  "inbounds": [
      "port": 10000,
      "protocol": "vmess",
      "settings": {
        "clients": [
            "id": "your-uuid",
            "alterId": 0
      "streamSettings": {
        "network": "ws",
        "wsSettings": {
        "path": "/yourpath/"
  "outbounds": [
      "protocol": "freedom",
      "settings": {}

Please replace your-uuid with your own UUID.

You can use this tool to generate a new UUID.

And please replace your-path with an arbitrary valid path, e.g. /10086/, /test/.

You can also change the inbound port (which is 10000 in the example), but you have to make sure that the inbound port here is equal to to port in the NGINX configuration (which will be covered later).

Step 5. Get The SSL Certificate by Certbot


certbot certonly --nginx -d

(Change to your own domain)

Your certificate will be stored under /etc/letsencrypt/live/, check it out and we will use it in the next step.

Step 6. Configure NGINX

Create a new NGINX configure file with the following configurations:

server {
  listen 443 ssl;
  listen [::]:443 ssl;

  ssl_certificate       /path/to/your/certificate;
  ssl_certificate_key   /path/to/your/certificate_key;
  ssl_session_timeout 1d;
  ssl_session_cache shared:MozSSL:10m;
  ssl_session_tickets off;

  ssl_protocols         TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers off;

  server_name ;
  location /yourpath/ {
    if ($http_upgrade != "websocket") {
        return 404;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
    # Show real IP in v2ray access.log
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Remember to change:

  • /path/to/your/certificate to the real path
  • /path/to/your/certificate_key to the real path
  • to your domain
  • /yourpath/ to the path that matches your V2Ray configuration
  • 10000 to the real inbound port number of V2Ray service

Please note that /yourpath/ is not /yourpath!

After completing the configuration, execute:

service nginx restart

to restart the NGINX.

Step 7. Enjoy!

Enjoy your free and secure internet journey!


After finishing the setup, my V2Ray client cannot connect to the server. Initially I thought the problem is caused by NGINX configuration, but it turns out to be a problem in V2Ray.

After 2022.1.1, V2Ray disables compatibility with MD5 authentication by default and forces VMESS AEAD encryption.

So, if your V2Ray client's version is lower than v4.28.1, you probably will get this error in your V2Ray's logs (if you set the log level to info or debug):

proxy/vmess/encoding: invalid user: VMessAEAD is enforced and a non VMessAEAD connection is received. You can still disable this security feature with environment variable v2ray.vmess.aead.forced = false . You will not be able to enable legacy header workaround in the future.

You have two choices to fix this problem:

  • Update your client's core version to v4.28.1 or newer
  • edit /etc/systemd/system/v2ray.service, add the line Environment="V2RAY_VMESS_AEAD_FORCED=false" before ExecStart, so your service file should look like this:
Description=V2Ray Service

ExecStart=/usr/local/bin/v2ray -config /usr/local/etc/v2ray/config.json