OpenVPN + V2Ray

This is a quick note on the process for setting up OpenVPN+V2Ray on an Ubuntu server and an Ubuntu client. Since this is aimed at intermediate-level users, no details are given.

1. Server

1.1. Install V2Ray (Nginx+ws+tls) on the server using the wulabing script from https://github.com/wulabing/V2Ray_ws-tls_bash_onekey.

Here is an example configuration generated by the wulabing script:

地址(address): v2.example.com
端口(port): 443
用户id(UUID): c7d7f868-1c17-452a-b2f6-64e61a4a6454
额外id(alterId): 0
加密方式(security): 自适应
传输协议(network): ws
伪装类型(type): none
路径(不要落下/): /1976f7/
底层传输安全: tls

1.2. Install OpenVPN on the server using the angristan script from https://github.com/angristan/openvpn-install.

2. Client

2.1. Download the generated OpenVPN client configuration file from the server to the client, for example v2.ovpn.

2.2. Download and unzip the latest V2Ray client for your platform, e.g. https://github.com/v2fly/v2ray-core/releases/download/v4.44.0/v2ray-linux-64.zip.

2.3. Configure the V2Ray client configuration file config.json to match the parameters on the server, and with UDP enabled set to true (since OpenVPN is using UDP). Much of the configuration below was copied from the default configuration file supplied with the zip file. Some of it will never apply in our scenario (e.g. the routing and dns) because the traffic passing over V2Ray will already be encrypted by OpenVPN.

 {
 "log": {
 "loglevel": "warning"
 },

 "inbounds": [{
 "port": 1080,
 "listen": "127.0.0.1",
 "tag": "socks-inbound",
 "protocol": "socks",
 "settings": {
 "auth": "noauth",
 "udp": true,
 "ip": "127.0.0.1"
 },
 "sniffing": {
 "enabled": true,
 "destOverride": ["http", "tls"]
 } }],

 "outbounds": [{
 "protocol": "vmess",
 "settings": {
 "vnext": [{
 "address": "123.123.123.123",
 "port": 443,
 "users": [
 { "id": "c7d7f868-1c17-452a-b2f6-64e61a4a6454",
 "alterId": 0 } ]
 }]
 },
 "streamSettings": {
 "network": "ws",
 "security": "tls",
 "tlsSettings": {
 "allowInsecure": false,
 "serverName": "v2.example.com"
 },
 "wsSettings": {
 "path": "/1976f7/",
 "headers": {
 "Host": "v2.example.com"
 } } } },{
 "protocol": "freedom",
 "settings": {},
 "tag": "direct"
 },{
 "protocol": "blackhole",
 "settings": {},
 "tag": "blocked"
 }],

 "routing": {
 "domainStrategy": "IPOnDemand",
 "rules":[
 {
 "type": "field",
 "ip": ["geoip:private"],
 "outboundTag": "blocked"
 },
 {
 "type": "field",
 "domain": ["geosite:category-ads"],
 "outboundTag": "blocked"
 } ]
 },

 "dns": {
 "servers": [
 "1.1.1.1",
 "8.8.8.8",
 "localhost"
 ]
 },

 "policy": {
 "levels": {
 "0": {
 "uplinkOnly": 0,
 "downlinkOnly": 0
 } },
 "system": {
 "statsInboundUplink": false,
 "statsInboundDownlink": false,
 "statsOutboundUplink": false,
 "statsOutboundDownlink": false
 } },

 "other": {} }

2.4. Start the V2Ray client running:

./v2ray -config config.json

2.5. Edit the generated OpenVPN client configuration file, e.g. v2.ovpn. Append a line:

socks-proxy 127.0.0.1

2.6. Now you can import the OpenVPN client configuration v2.ovpn into your client. On Ubuntu with GNOME desktop, you typically do the import in the Settings GUI.

2.7. Add a static route from the client to the server, so that it does not try to send OpenVPN traffic via V2Ray, then V2Ray via OpenVPN, in a continuous and never-ending loop. For example, if your gateway is 10.0.0.1 and your interface is wlp3s0:

sudo ip route add 123.123.123.123 via 10.0.0.1 dev wlp3s0

2.8. Start the OpenVPN connection on the client.

2.9. OpenVPN on the client now goes to the V2Ray client, which goes to the V2Ray server, which goes to the OpenVPN server. Your OpenVPN connection is hidden inside your V2Ray connection.

2.10. To end the process, stop OpenVPN on the client, delete the static route, and stop V2Ray on the client.

Updated 2022-02-03