Setting Up V2Ray with NGINX + WebSocket + TLS
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 https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh)
Step 3. Install NGINX & Certbot
Run:
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,
"listen":"127.0.0.1",
"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
Run:
certbot certonly --nginx -d example.com
(Change example.com
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_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
server_name example.com;
location /yourpath/ {
if ($http_upgrade != "websocket") {
return 404;
}
proxy_redirect off;
proxy_pass http://127.0.0.1:10000;
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 pathexample.com
to your domain/yourpath/
to the path that matches your V2Ray configuration10000
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!
Troubleshooting
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 lineEnvironment="V2RAY_VMESS_AEAD_FORCED=false"
beforeExecStart
, so your service file should look like this:
[Unit]
Description=V2Ray Service
Documentation=https://www.v2fly.org/
After=network.target nss-lookup.target
[Service]
User=nobody
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
NoNewPrivileges=true
Environment="V2RAY_VMESS_AEAD_FORCED=false
ExecStart=/usr/local/bin/v2ray -config /usr/local/etc/v2ray/config.json
Restart=on-failure
RestartPreventExitStatus=23
[Install]
WantedBy=multi-user.target
2 Comments
What's the role of Nginx here? Since we can directly connect to the v2ray .
In v2ray client should we configure port 10000 or 443 ?
The reason why there is an nginx is because someone has the port 443 already exposed as a webserver.
That webserver could proxy to many services behind like a wireguard server, a wordpress blog and a jellyffin server.
if you want to share that port 443 among all these different services, then you would put an nginx box in front of the rest and have the nginx redirect traffic to different backend depending on which URL/URI is hit.
If someone want to make it look like the v2ray traffic is effective web https, then one of the requirement would be to use tcp 443 which is probably serving other web services already.
This guide was really good. Thanks to the author.