V2Ray (WebSocket+TLS) server setup notes
Contents
In the previous article, ShadowSocks server setup notes, I mentioned that V2Ray was the successor protocol. I actually ran that too, and I found my old notes, so I am putting them here.
What V2Ray is
V2Ray is a proxy tool developed as a successor to ShadowSocks. It supports multiple protocols and can disguise traffic as HTTPS using WebSocket or gRPC.
Compared with ShadowSocks:
- ShadowSocks: simple and lightweight, with easy setup
- V2Ray: more feature-rich and flexible. WebSocket+TLS makes censorship evasion stronger, but the configuration is more complex
Architecture
The setup is:
Client -> Cloudflare (CDN) -> Caddy (reverse proxy) -> V2Ray (WebSocket)
Putting Cloudflare in the middle gives you:
- Hides the server’s real IP
- Automatic SSL/TLS certificate management
- Faster delivery through CDN caching
Server setup
These steps are for CentOS 7.
Preparation
yum update -y && yum install curl -y
Cloudflare setup
- Add a subdomain in Cloudflare, for example
v2ray.example.com - Create an A record pointing to the server IP
- Enable the proxy setting (orange cloud)
- Wait for DNS propagation
Install V2Ray
Use the 233blog script:
bash <(curl -s -L https://git.io/v2ray.sh)
Installer choices:
- Select
1for V2Ray - Select
4for WebSocket+TLS - Port number: press Enter for the default, or use 443
- Enter the subdomain, for example
v2ray.example.com - Then mostly proceed with
YorN- Auto config:
Y - Enable ad blocking:
N(optional) - ShadowSocks:
N
- Auto config:
Note: If Cloudflare DNS has not propagated yet, the installer will stop midway. Make sure nslookup v2ray.example.com resolves first.
Verify the install
v2ray status
If both V2Ray and Caddy are active (running), you are good.
Caddy configuration
Edit /etc/caddy/Caddyfile:
v2ray.example.com {
root /var/www/html
tls your-email@example.com
log ./access.log
timeouts none
proxy / 127.0.0.1:54878 {
websocket
header_upstream -Origin
}
}
import sites/*
Key points:
- Replace the email address in
tlswith your own - Make sure the
proxyport,54878, matches the V2Ray config
Disable the firewall
systemctl stop firewalld
systemctl disable firewalld
Or just open the ports you need, such as 443.
Tune kernel parameters
Use the same settings as ShadowSocks. See the previous article for details.
/etc/security/limits.conf:
root soft nofile 51200
root hard nofile 51200
Set /etc/sysctl.conf to the same values as in the previous article, then run sysctl -p.
Enable BBR
v2ray bbr
Select 1 to enable BBR. A reboot is required:
reboot
Set the timezone
timedatectl set-timezone Asia/Tokyo
date # check
Configuration files
There are two V2Ray config files:
/etc/v2ray/config.json- main config/etc/v2ray/233blog_v2ray_config.json- config used by the 233blog script
Important: you need to set the UUID in both files or it will fail. Back them up before editing:
cp /etc/v2ray/config.json /etc/v2ray/config.json.bak
cp /etc/v2ray/233blog_v2ray_config.json /etc/v2ray/233blog_v2ray_config.json.bak
config.json structure
{
"log": {
"access": "/var/log/v2ray/access.log",
"error": "/var/log/v2ray/error.log",
"loglevel": "warning"
},
"inbounds": [
{
"port": 54878,
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"level": 1,
"alterId": 233
}
]
},
"streamSettings": {
"network": "ws"
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
}
],
"outbounds": [
{
"protocol": "freedom",
"settings": {}
},
{
"protocol": "blackhole",
"settings": {},
"tag": "blocked"
}
],
"dns": {
"server": ["1.1.1.1", "1.0.0.1", "8.8.8.8", "8.8.4.4", "localhost"]
},
"routing": {
"domainStrategy": "IPOnDemand",
"rules": [
{
"type": "field",
"ip": [
"0.0.0.0/8",
"10.0.0.0/8",
"127.0.0.0/8",
"192.168.0.0/16"
],
"outboundTag": "blocked"
}
]
},
"transport": {
"kcpSettings": {
"uplinkCapacity": 100,
"downlinkCapacity": 100,
"congestion": true
},
"sockopt": {
"tcpFastOpen": true
}
}
}
Key points:
inbounds.portmust match the port used in Caddy’sproxyclients.idmust be the same UUID on the client siderouting.rulesblocks access to private IP ranges
Multiple users
Add more users to the clients array:
"clients": [
{
"id": "uuid-for-user1",
"level": 1,
"alterId": 233
},
{
"id": "uuid-for-user2",
"level": 1,
"alterId": 233
}
]
Unlike ShadowSocks, users are distinguished by UUID rather than by port.
Restart after changes
v2ray restart
v2ray status