文章

代理 - v2ray

之前在代理 - shadowsocks介绍了使用ss做代理的方式,部署简单,使用方便。但用了一个月之后,奇奇怪怪的事情发生了 ┓( ´∀` )┏

  1. 奇奇怪怪的问题
  2. v2ray
    1. 配置
    2. 客户端
  3. websocket + tls + web(eg: nginx)
    1. websocket
    2. 配置nginx
    3. v2ray服务器配置
      1. vmess over websocket over tls over tcp?
    4. v2ray客户端配置
      1. SwitchyOmega
      2. 不使用本地客户端
      3. 怎么确定走代理了
    5. 速度测试
  4. 和网站在一起
  5. 其他
  6. 感谢

奇奇怪怪的问题

部署shadowsocks的时候,开了好几个端口。8005端口用了一个月之后,突然发现没法在该端口建立起连接了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
> netstat -anp | grep :8005
tcp        0      0 104.225.232.103:8005    0.0.0.0:*               LISTEN      2683182/python3
tcp        0      0 104.225.232.103:8005    114.249.24.222:54649    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54566    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54544    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54984    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54524    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54779    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54868    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54988    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54805    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54525    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54818    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:46250    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54978    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54832    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54567    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54913    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54878    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54499    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54930    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54850    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54974    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54939    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54926    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54534    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54609    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54769    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54886    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54639    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54943    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54970    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54597    SYN_RECV    -
tcp        0      0 104.225.232.103:8005    114.249.24.222:54488    SYN_RECV    -
udp        0      0 104.225.232.103:8005    0.0.0.0:*                           2683182/python3

只收到SYN,不能收到二次确认的SYN。看起来像极了SYN洪泛攻击。但是连接请求都来自我的路由出口ip,而且连接确实是我自己发起的,所以肯定不是SYN洪泛攻击。但为什么会这样,实在是不清楚。

按照pip shadowsocks的指示查看日志:

1
sudo less /var/log/shadowsocks.log

也没看出什么异样。

换了个ss的端口,结果就好了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
> netstat -anp | grep :8002
tcp        0      0 104.225.232.103:8002    0.0.0.0:*               LISTEN      2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:63739    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:61558    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:61659    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:61736    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:49699    TIME_WAIT   -
tcp        0      0 104.225.232.103:8002    114.249.24.222:63026    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:49361    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:65437    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:65420    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:49247    TIME_WAIT   -
tcp        0      0 104.225.232.103:8002    114.249.24.222:61537    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:63063    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:49700    TIME_WAIT   -
tcp        0      0 104.225.232.103:8002    114.249.24.222:63419    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:65416    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:63094    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:65415    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:65402    ESTABLISHED 2683182/python3
tcp        0      0 104.225.232.103:8002    114.249.24.222:65428    ESTABLISHED 2683182/python3
udp        0      0 104.225.232.103:8002    0.0.0.0:*                           2683182/python3

为什么会这样?

据说是被GFW检测到了:

  • https://github.com/shadowsocks/shadowsocks-libev/issues/1932

按照这篇概述,找到了websocket + tls + nginx的方案,把翻墙流量伪装成访问网站的流量,再使用tls加密一波,相当难被发现。

v2ray

v2ray是一个比shadowsocks功能更强大的代理工具。可以按照v2fly的安装指南安装v2ray。

v2ray并没有明确的client和server之分,它就是一个盒子:数据包以inbound格式进来,以outbound格式出去。而v2ray做的主要就是协议转换的工作。对于每一个v2ray节点,下一个节点的inbound格式就是上一个节点的outbound格式。所以它的上一个节点就是下一个节点的client,下一个节点相当于上一个节点的server。这些节点可以连接成一串,每经过一个节点,格式进行一次转换。

所以v2ray主要配置的就是inbound和outbound所用的协议。

配置文件格式

配置

server和client都按照自己的平台装上对应的v2ray,server的配置比较简单,参考新手指南

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
  "inbounds":[
    {
      //"listen":"127.0.0.1", //只监听 127.0.0.1,避免除本机外的机器探测到开放了 10087 端口
      "port":10087, // 服务器监听端口
      "protocol":"vmess",
      "settings":{
        "clients":[
          {
            "id":"b831381d-xxx30811",
            "alterId": 64
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "wsSettings": {
          "path": "/v2ray"
        }
      }
    }
  ],
  "outbounds":[
    {
      "protocol":"freedom"
    }
  ]
}
  • 配置server监听的ip和端口;
  • 入口流量是由client发来的vmess格式;
  • client id相当于用户校验,是一个uuid,建议直接用uuid generator生成。client的id要和server的一致,来自client的流量才能通过;
  • 出口流量是freedom协议,相当于直连最终要访问的服务器。毕竟server是部署在海外VPS上的,直连YouTube就能访问了;

client的配置稍显麻烦:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
{
  "inbounds":[
    {
      "port":1080, // SOCKS 代理端口,在浏览器中需配置代理并指向这个端口
      "listen":"0.0.0.0",
      "protocol":"socks",
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls"]
      },
      "settings": {
        "auth": "noauth",
        "udp": false
      }
    }
  ],
  "outbounds":[
    {
      "protocol":"vmess",
      "settings":{
        "vnext":[
          {
            "address":"puppylpg.top", // 服务器地址,请修改为你自己的服务器 ip 或域名
            "port":443, // 服务器端口
            "users":[
              {
                "id":"b831381d-xxx30811",
                "alterId": 64
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "wsSettings": {
          "path": "/v2ray"
        }
      }
    },
    {
      "protocol":"freedom",
      "tag":"direct"
    }
  ],
  "routing":{
    "domainStrategy":"IPOnDemand",
    "rules":[
      {
        "type":"field",
        "ip":[
          "geoip:private"
        ],
        "outboundTag":"direct"
      }
    ]
  }
}
  • 入口流量是来自浏览器或者系统的socks协议的流量;
  • 出口流量要配置成server接收的vmess协议;
  • server的ip和port要配置好;
  • uuid要配置成和server一样的才能验证通过;
  • 强大的路由功能:上述出口流量配置为了两种类型,需要翻墙的vmess流量和直连流量,其中路由里配置私有ip的用直连流量,不需要走代理。其他没配置的流量默认使用outbounds的第一个,也就是代理

可以参考v2ray 路由,把国外网站配置为翻墙,国内网站配置为直连,广告域名配置为blackhole,直接丢弃广告流量,从而实现广告屏蔽的目的。

client和server之间也可以使用shadowsocks协议,这样v2ray作为client,它的server可以直接是shadowsocks服务器。

client和server之间甚至还可以配置为奇奇怪怪的http协议

经过上述配置,流量现在的路径是这样的:

1
2
3
4
5
6
7
{浏览器} 
    <--(socks)--> 
{V2Ray 客户端 inbound <-> V2Ray 客户端 outbound} 
    <--(VMess)-->  
{V2Ray 服务器 inbound <-> V2Ray 服务器 outbound} 
    <--(Freedom)--> 
{目标网站}

VPS Debian安装好v2ray之后,默认配置目录是/etc/v2ray,作为server存在,所以把server的配置放入config.json,然后使用命令检测配置的正确性:

1
v2ray -test -config /etc/v2ray/config.json

以上更详细的介绍可以参考:

  • v2fly大白话教程:https://guide.v2fly.org/
  • v2fly新手教程:https://www.v2fly.org/guide/start.html
  • v2fly配置文档:https://www.v2fly.org/config/overview.html
  • 有兴趣还可以看看v2ray的开发文档:https://www.v2fly.org/developer/intro/compile.html

客户端

如果直接使用从v2ray-core下载的v2ray作为client,用起来不是很方便。

之前买别人的代理的时候,用了基于v2ray的client软件:

  • windows用的是v2rayN:https://github.com/2dust/v2rayN;
  • Android用的是v2rayNG:https://github.com/2dust/v2rayNG;

都是有图形界面的,配置起来相对容易很多。

实际使用的时候,建议先下载一个v2ray-core的client,配置好config.json,作为client启动。此时的代理只是浏览器的代理,不是系统代理,所以chrome使用switchOmega配置好浏览器代理为v2ray-core的client服务地址(默认localhost:1080)之后,就可以成功访问YouTube了。至此,证明client配置是成功的。

之后以v2rayN为例,选择“添加vmess服务器”,然后直接选择“导入配置文件”,把刚刚配置的config.json导入进来,就成功添加了v2ray客户端可以连接的server。通过v2rayN的图形界面,可以很方便配置代理为系统代理,而不只是浏览器代理。

配过v2rayN,v2rayNG也大差不差了。不过v2rayN有分享功能,选中服务器,选中右边的“显示分享内容”,就会生成二维码。之后手机用v2rayNG直接扫码就行了。

各个平台的客户端可以参考:

  • 神一样的工具们:https://v2ray.com/awesome/tools.html

websocket + tls + web(eg: nginx)

  • https://guide.v2fly.org/advanced/wss_and_web.html

websocket

websocket是和http同等级的应用层协议,主要是为了解决http只能由client主动发起而不能反过来的问题。这就导致了client从server知道一个状态的实时动态变化过程,只能通过不断轮询的方式。而websocket则可以让server主动push消息给client:

  • websocket的形象解释:https://www.zhihu.com/question/20215561
  • https://www.ruanyifeng.com/blog/2017/05/websocket.html

但是上述文章似乎并没有解释websocket之所以能这么做的原理。这个以后再探讨,目前只需要知道:

  1. websocket类似http;
  2. websocket + tls类似http + tls,即https;
  3. websocket利用http完成握手阶段,兼容http,比http多一些header;

所以websocket + tls + nginx,本质上就是 通过v2ray客户端让流量伪装成websocket格式的流量,并使用tls加密,打到nginx上,而真正的v2ray服务器则隐藏在nginx后面。当然也不一定是nginx,apache也行。

整体配置主要就两步:

  1. 配置v2ray客户端和nginx之间通过websocket + tls方式通信。nginx配置http可以参考折腾小服务器 - netdata与nginx,数字证书配置方式可以参考折腾小服务器 - nginx与https
  2. 配置nginx反向代理到v2ray服务器;

配置nginx

nginx之前已经配置443端口为https了,所以websocket + tls可以配置在一起:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
upstream netdata {
    server 127.0.0.1:19999;
    keepalive 64;
}

upstream v2ray-ws {
    server 127.0.0.1:10086;
    keepalive 64;
}

server {
    listen 80;
    listen 443 ssl;
    # uncomment the line if you want nginx to listen on IPv6 address
    listen [::]:80;
    listen [::]:443 ssl;

    # the virtual host name of this subfolder should be exposed
    #server_name netdata.example.com;
    server_name puppylpg.xyz;

    # use password to access
    # auth_basic "Protected";
    # auth_basic_user_file passwords;

    # CA: LET'S ENCRYPT
    ssl_certificate /etc/letsencrypt/live/puppylpg.xyz/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/puppylpg.xyz/privkey.pem;

    location = /netdata {
        return 301 /netdata/;
    }

    location ~ /netdata/(?<ndpath>.*) {
        proxy_redirect off;
        proxy_set_header Host $host;

        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_pass_request_headers on;
        proxy_set_header Connection "keep-alive";
        proxy_store off;
        proxy_pass http://netdata/$ndpath$is_args$args;

        gzip on;
        gzip_proxied any;
        gzip_types *;
    }

    location ~ /v2ray {

        if ($http_upgrade != "websocket") { # WebSocket协商失败时返回404
            return 404;
        }

        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        # Show real IP in v2ray access.log
        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass_request_headers on;
        proxy_set_header Connection "keep-alive";
        proxy_store off;
        proxy_pass http://v2ray-ws;

        gzip on;
        gzip_proxied any;
        gzip_types *;
    }
}

主要配置:

  1. v2ray的服务地址:v2ray-ws;
  2. 域名 + /v2ray路径作为对v2ray-ws访问的请求;
  3. 设置Upgrade header,这是websocket比http协议多的header;
  4. 如果没有Upgrade: websocket header,说明它不是websocket协议,而是http协议。我们配置的是websocket,所以对于http协议,直接返回404;

之前给nginx的http访问配置了basic认证,这里关掉了。不然websocket协议的访问也需要basic认证,而v2ray客户端好像不支持这个,导致nginx报错401 unauthorized:114.249.24.222 - - [02/Jan/2022:05:45:15 -0500] "GET /v2ray HTTP/1.1" 401 179 "-" "Go-http-client/1.1"

v2ray服务器配置

照着这个配就行了:

  • https://guide.v2fly.org/advanced/wss_and_web.html#%E6%9C%8D%E5%8A%A1%E5%99%A8%E9%85%8D%E7%BD%AE

注意网络inbounds配置为ws,路径配置为/v2ray,和nginx保持一致:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
  "inbounds":[
    {
      "listen":"127.0.0.1", //只监听 127.0.0.1,避免除本机外的机器探测到开放了 10000 端口
      "port":10086, // 服务器监听端口
      "protocol":"vmess",
      "settings":{
        "clients":[
          {
            "id":"需要一个uuid",
            "alterId": 64
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "wsSettings": {
          "path": "/v2ray"
        }
      }
    }
  ],
  "outbounds":[
    {
      "protocol":"freedom"
    }
  ]
}

配置文件的格式参考:

  • https://www.v2ray.com/chapter_02/01_overview.html

主要配置的就是inbounds和outbounds这两个数组。对于每一个inbound或者outbound,根据使用协议的不同,配置项也不同。没特殊情况的话,v2ray的服务器和客户端之间用的就是vmess,所以这里server的inbound配了vmess。

查看vmess协议的配置属性,每个inbound可配置多个用户,还可以配置vmess协议基于什么底层协议传输,详见下文介绍。

v2ray支持tls,但是这里只配置了websocket没有配置tls,因为客户端和nginx之间已经是tls了,nginx和v2ray服务都在同一台机器上,没必要还使用tls

另外v2ray服务配置为只绑定127.0.0.1的10086端口,这样服务根本不对外暴露,也就不可能被检测到

outbound是Freedom协议,基本是直连,所以没有太多要配的。

之后重启v2ray和nginx就可以了。

可看到v2ray和nginx之间建立起了连接,且V2ray只绑定到了loop地址:

1
2
3
4
5
6
root@pokemon /e/n/sites-enabled# netstat -anp | grep :10086
tcp        0      0 127.0.0.1:10086         0.0.0.0:*               LISTEN      3225973/v2ray
tcp        0      0 127.0.0.1:10086         127.0.0.1:45362         ESTABLISHED 3225973/v2ray
tcp        0      0 127.0.0.1:45362         127.0.0.1:10086         ESTABLISHED 3243463/nginx: work
tcp        0      0 127.0.0.1:44320         127.0.0.1:10086         ESTABLISHED 3243463/nginx: work
tcp        0      0 127.0.0.1:10086         127.0.0.1:44320         ESTABLISHED 3225973/v2ray

vmess over websocket over tls over tcp?

出口协议配置的是vmess,transport配置成了websocket + tls,所以是 vmess over websocket over tls over tcp?

看起来是的。按照官方文档对stream setting的解释,默认是使用tcp的,但是可以修改为http、websocket、unix domain socket等。也正因为如此,上一个节点的outbound和下一个节点的inbound才必须配置一致,不然下一个节点不知道发来的数据经过了多少层包装,也就没法正确拆包。

tcp + tls + web里其实也印证了这个观点:使用直接使用vmess over tls over tcp,可以比vmess over websocket over tls over tcp少一层vmess封装。

v2ray客户端配置

v2ray没有什么server或client的差别,只有上一个节点和下一个节点。所以直接在自己的pc上起一个v2ray做客户端即可,配置使用socks/http作为inbound,服务器上的v2ray的inbound(vmess on websocket)作为outbound。

与Shadowsocks和ShadowsocksR不同,V2Ray官方未提供各平台的GUI客户端(实际上V2Ray核心不区分客户端和服务端)。许多第三方开发人员基于V2Ray核心开发了适用于各平台的GUI客户端,因此每个平台均有多个客户端可供选择

虽然可以使用v2rayN等各种包装了v2ray core的客户端,不过在linux上更建议直接使用v2ray,如果用docker起v2ray则更舒适

v2ray docker参考Docker - 容器化

作为client的配置照着这个配就行了。注意网络outbounds配置为ws + tls,路径配置为/v2ray,和nginx保持一致:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
{
  "inbounds": [
    {
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true,
        "userLevel": 8
      },
      "sniffing": {
        "destOverride": [
          "http",
          "tls"
        ],
        "enabled": true
      },
      "tag": "socks"
    },
    {
      "port": 10809,
      "protocol": "http",
      "settings": {
        "userLevel": 8
      },
      "tag": "http"
    }
  ],
  "outbounds":[
    {
      "protocol":"vmess",
      "settings":{
        "vnext":[
          {
            "address":"puppylpg.xyz", // 服务器地址,请修改为你自己的服务器 ip 或域名
            "port":443, // 服务器端口
            "users":[
              {
                "id":"需要一个uuid",
                "alterId": 64
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "wsSettings": {
          "path": "/v2ray"
        }
      }
    },
    {
      "protocol":"freedom",
      "tag":"direct"
    }
  ],
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "domain": [
          "domain:googleapis.cn"
        ],
        "outboundTag": "proxy",
        "type": "field"
      },
      {
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct",
        "type": "field"
      },
      {
        "ip": [
          "geoip:cn"
        ],
        "outboundTag": "direct",
        "type": "field"
      },
      {
        "domain": [
          "geosite:cn"
        ],
        "outboundTag": "direct",
        "type": "field"
      }
    ]
  }
}

客户端配置和上面介绍的类似,outbound使用vmess,也是基于websocket,需要使用tls,因为和nginx之间的通信是经过公网的远程通信。

outbound还配了一个freedom直连,给私有ip使用。

SwitchyOmega

不管是用v2rayN这种客户端,还是直接使用v2ray作为客户端,此时,本机监听了两个端口:

  • 10808:socks代理
  • 10809:http代理

此时,可以给浏览器配置socks/http代理来走这两个端口,连接服务器上的v2ray。也可以使用SwitchyOmega。

还可以在os上配置socks代理,让整个系统的流量都走10808。v2rayN等专门的client本身就有该功能。

不使用本地客户端

如果拿上述v2ray的client配置取代server配置(socks、http),直接运行在server端,是不是就可以不用在本地起client了?是的,因为不使用vmess,所以本地pc支持直接通过socks/http代理。但是,因为没走vmess,容易被封。

如果不使用vmess,且用cloudflare做代理呢?不合算,ping会变高

如果找一台国内的vps,部署上v2ray上述client配置,暴露socks/http,那么本地的pc可以直接通过socks连上国内的vps,最终连上国外的vps,也是可以的。但是国内的vps流量一般都很少,这么代理的话流量费就不合算了。

毕竟国外的vps明知道大家是做代理用的,所以流量给的都很慷慨。

怎么确定走代理了

除了翻墙成功之外,还可以通过访问国外的一些ip网站(国内的不行,国内的配置了不走代理)查看自己的ip,比如whoer。如果ip是代理服务器的ip,那肯定就成功了。

速度测试

vmessping/vmessspeed是官方提供的延迟/速度测试工具。

使用本地的windows电脑作为v2ray客户端,测一下vmess over websocket over tls over tcp方案的ping(vmess链接由v2rayN的分享功能生成):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
PS C:\Users\puppylpg\Desktop\all_v2ray> .\vmessping_amd64_windows.exe vmess://ew0KI................iDQp9
Vmessping ver[v0.3.4], A prober for v2ray (v2ray-core: 4.23.2)

Net: ws
Addr: puppylpg.xyz
Port: 443
UUID: xxxxxxxxxxxxxxxxxxxxxx
Type: none
TLS: tls
PS: ws-vmess

Ping http://www.google.com/gen_204: seq=1 time=816 ms
Ping http://www.google.com/gen_204: seq=2 time=667 ms
Ping http://www.google.com/gen_204: seq=3 time=830 ms
Ping http://www.google.com/gen_204: seq=4 time=1171 ms
Ping http://www.google.com/gen_204: seq=5 time=880 ms
Ping http://www.google.com/gen_204: seq=6 time=855 ms
Ping http://www.google.com/gen_204: seq=7 time=845 ms
Ping http://www.google.com/gen_204: seq=8 time=756 ms
Ping http://www.google.com/gen_204: seq=9 time=840 ms
Ping http://www.google.com/gen_204: seq=10 time=822 ms
Ping http://www.google.com/gen_204: seq=11 time=797 ms
Ping http://www.google.com/gen_204: seq=12 time=874 ms

--- vmess ping statistics ---
12 requests made, 12 success, total time 21.5943311s
rtt min/avg/max = 667/846/1171 ms
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PS C:\Users\puppylpg\Desktop\all_v2ray> .\vmessspeed_amd64_windows.exe vmess://ew0KI................iDQp9

Net: ws
Addr: puppylpg.xyz
Port: 443
UUID: xxxxxxxxxxxxxxxxxxxxxx
Type: none
TLS: tls
PS: ws-vmess

Testing From IP: 104.225.232.103 (IT7 Networks Inc) [34.0485, -118.2529]

Target Server: [3864]     0.32km Los Angeles, CA (United States) by GeoLinks
Latency: 100.994ms
Download Test: ................104.79 Mbit/s
Upload Test: ................25.69 Mbit/s

Download: 104.79 Mbit/s
Upload: 25.69 Mbit/s

和网站在一起

有一篇相当详细的上述配置类似的文章:

  • https://pincong.rocks/article/15493

里面提到了主动探测:虽然我们发出去的包是websocket + tls,和普通网站访问的流量别无二致,但是一旦GFW主动访问流量的目的地址,会发现目的地其实并没有网站存在,那就露馅了。

不过我之前就已经在pupyplpg.xyz部署网站了,虽然就一个单独的页面,指引跳转到我的github pages,但聊胜于无吧。

另一个建议就是不要使用/v2ray这种过于明显的路径,太扎眼。我不确定实际上GWF会不会特意针对这些特殊名字的路径进行侦测,但是我仔细一想,既然websocket流量已经经过tls加密了,那数据包访问路径究竟是不是/v2ray,GFW是看不到的。就算GFW主动使用/v2ray路径,nginx已经配置了http访问/v2ray路径返回404,所以就算主动探测,返回404什么也证明不了。

然后回看ws+tls+web配置教程,果然有关于这一点的说明。

“不要迷信”哈哈哈,确实,知识够丰富,会思考,就不会迷信,无论技术还是生活。

最后就是既然用了v2ray,就把ss下了吧,毕竟最终的安全性取决于最低的那一环。

其他

客户端还可以和服务器之间用以下协议通信:

  • 伪装成http:https://guide.v2fly.org/advanced/httpfake.html
    • 这个很好玩的样子,和直接使用http还不一样,不是vmess over http,而是vmess伪装成http:https://www.v2fly.org/config/transport.html#streamsettingsobject
  • tcp + tls:https://guide.v2fly.org/advanced/tls.html
  • tcp + tls + web:https://guide.v2fly.org/advanced/tcp_tls_web.html
    • 和上面的websocket + tls + web类似,只不过用了传输层的tcp而不是应用层的websocket;
  • 直接使用websocket:https://guide.v2fly.org/advanced/websocket.html
  • 直接使用http2:https://guide.v2fly.org/advanced/h2.html
    • 据说http2贼快:https://http2.akamai.com/demo
  • http2 + tls + web:https://guide.v2fly.org/advanced/h2_tls_web.html
    • 既然http2贼快,那就可以试试用它取代websocket + tls + web的效果
    • nginx和v2ray之间使用的http2可以用h2c,他们之间因为是本地机器,不需要强制使用tls了:
      • 基于http2传输配置:https://www.v2ray.com/chapter_02/transport/h2.html
      • v2ray新增h2c支持:https://v2ray.com/chapter_00/01_versions.html#20190712-v4200
    • nginx早就支持http2了;

主要是vmess over websocket已经很够用了,而vmess over tcp在网络提升方面并没有数量级上的优势,所以暂时不想折腾其他的协议方案了。

其他还可以探索一些v2ray的功能,比如:

  • 统计:https://www.v2fly.org/config/stats.html

感谢

还有一些v2ray写的关于网络的好文章

v2ray果然很强大!比shadowsocks要复杂不少。

GFW真是一个学习、巩固、拓展计算机网络知识的好素材,经历这些磨难之后,发现计算机网络的知识更加强悍了。

本来按照惯例,想用的标题是“感想”,结果错打成了“感谢”。将错就错吧,感谢好像别有韵味。

本文由作者按照 CC BY 4.0 进行授权