x1184的小站
x1184的小站
简单聊聊ProjectV设计思路
简单聊聊ProjectV设计思路

阅读说明

本文适合于有基本的计算机网络基础的开发者阅读,包括但不限于网络传输模型和网络协议的特性。

零、引言

基本设定

首先,我们来设定一个概念:一个代理(FQ)协议可能具备的三要素。
一、传输:能在 A、B 两个主机之间建立一条安全可靠的通信通道,用于传输数据;
二、协议:对于将要传输的数据,能将这些数据的目的地告知代理服务器;
三、内容:可以对传输的数据进行优化,比如压缩、合并等。
任何一个FQ协议都具备以上三要素中的几个或全部。

文字可能较难理解,我们来举一个简单的例子:Socks 协议。Socks 只具备协议要素,即告知代理服务器要把数据发送到哪里去,以达到代理的目的。但众所周知单纯的 Socks 不具备FQ能力,因为它不能建立可靠的通道(即会被Q)。于是就有了 Shadowsocks。Shadowsocks 在 Socks 的基础上增加了传输要素,对数据加了密,使墙无法分析其内容。而 Shadowsocks 不具备内容要素,因为对于客户端的发来的内容,Shadowsocks 不进行任何修改,直接发送给了代理服务器。

这篇两年前v2作者的文章放在目前新协议新思路不断出现的现在依旧适用,那时的v2发布已两年了,正准备升版本号到3.0。从branch log来看,当时可能是在适配支持ss的AEAD算法,而其实其主要核心协议和传输方式这时基本开发完成了。

作者谈改版

然后说一下版本号,这次升到 3.0,并不是有黑科技要加入,而是因为 2.x 的目标已经实现了。2.x 开发代号为“one for all”,它的含义是这样的:V2Ray 成为单一核心,其它项目围绕着 V2Ray 展开。目前 Project V 在所有主流图形化平台上都有图形界面的客户端:

跑一下star趋势分析可以发现其主要流行起来或是大规模使用的时间点是在2017/10/9,彼时对应的版本号为2017.10.27 v2.44,可能跟当时主流协议安全性受到质疑有一定关系。并且其瑞士军刀式的设计思路开阔了人们的视野,原来一个软件可以支持这么多种”传输通道”和更定制化的协议。现在我们就从文档和作者文章为据,简要聊聊其设计思路。

https://img.ocasis.cn/image/5e52208c32363
项目趋势分析图

一、模块化设计思路

功能自定

模块化,简单来说就是乐高积木,每一块积木都有统一的接口(有例外,这里忽略),积木和积木之间想拼就拼,想拆就拆,很方便。类似的。v2中的每一个功能都可以简单地添加或移除。

完整功能的版本

import (
    _ "v2ray.com/core/app/dispatcher/impl"
    _ "v2ray.com/core/app/dns"
    _ "v2ray.com/core/app/log"
    _ "v2ray.com/core/app/policy/manager"
    _ "v2ray.com/core/app/proxyman/inbound"
    _ "v2ray.com/core/app/proxyman/outbound"
    _ "v2ray.com/core/app/router"

    _ "v2ray.com/core/proxy/blackhole"
    _ "v2ray.com/core/proxy/dokodemo"
    _ "v2ray.com/core/proxy/freedom"
    _ "v2ray.com/core/proxy/http"
    _ "v2ray.com/core/proxy/shadowsocks"
    _ "v2ray.com/core/proxy/socks"
    _ "v2ray.com/core/proxy/vmess/inbound"
    _ "v2ray.com/core/proxy/vmess/outbound"

    _ "v2ray.com/core/transport/internet/kcp"
    _ "v2ray.com/core/transport/internet/tcp"
    _ "v2ray.com/core/transport/internet/tls"
    _ "v2ray.com/core/transport/internet/udp"
    _ "v2ray.com/core/transport/internet/websocket"

    _ "v2ray.com/core/transport/internet/headers/http"
    _ "v2ray.com/core/transport/internet/headers/noop"
    _ "v2ray.com/core/transport/internet/headers/srtp"
    _ "v2ray.com/core/transport/internet/headers/utp"
    _ "v2ray.com/core/transport/internet/headers/wechat"
)

更小占用的精简版本

import (
    _ "v2ray.com/core/app/dispatcher/impl"
    _ "v2ray.com/core/app/log"
    _ "v2ray.com/core/app/policy/manager"
    _ "v2ray.com/core/app/proxyman/inbound"
    _ "v2ray.com/core/app/proxyman/outbound"
    _ "v2ray.com/core/app/router"

    _ "v2ray.com/core/proxy/dokodemo"
    _ "v2ray.com/core/proxy/freedom"
    _ "v2ray.com/core/proxy/vmess/outbound"

    _ "v2ray.com/core/transport/internet/tcp"
    _ "v2ray.com/core/transport/internet/tls"
    _ "v2ray.com/core/transport/internet/udp"
)

自己可根据适当的组件需要编译出响应的版本,使用官方的编译工具运行就好 $GOPATH/bin/vbuild -os=linux -arch=arm 之后运行 v2ray -config=config.pb -format=pb

协议自由组合

先看下基本规则

https://img.ocasis.cn/image/5e52ae2689ef5
  • 需要配置至少一个入站协议(Inbound)和一个出站协议(Outbound)才可以正常工作。协议列表见第二章节。
    • 入站协议负责与客户端(如浏览器)通信:
      • 入站协议通常可以配置用户认证,如 ID 和密码等;
      • 入站协议收到数据之后,会交给分发器(Dispatcher)进行分发;
    • 出站协议负责将数据发给服务器,如另一台主机上的 V2Ray。
  • 当有多个出站协议时,可以配置路由(Routing)来指定某一类流量由某一个出站协议发出。
    • 路由会在必要时查询 DNS 以获取更多信息来进行判断。

正如引言中所述的基本概念一样,其实在v2之前的各种代理方案也都是三种不同定位的部分组合合成的最终结果,而ProjectV这边直接把其概念统一化,将不同的组合方案聚合起来,使其拥有更强的使用周期和更灵活的组合方式,其中也有专项改造的新协议。这里我们按照文章开头的分类方式选择几种说下。

Vmess

传输+识别,是V2Ray原创的加密通讯协议。基于 TCP,是一个无状态协议,即客户端和服务器之间不需要握手即可直接传输数据,每一次数据传输对之前和之后的其它数据传输没有影响。

mKCP

只负责传输, 流式传输协议 ,基于KCP协议做修改,而KCP本质是TCPoverUDP, 所以其本质也是一个基于 UDP 的协议

Mux.Cool

识别+内容,多路复用,单一TCP被分为请求若干次,即一个 Mux.Cool 连接中可传输若干个子连接,每个子连接有一个独立的 ID 和状态。 Mux 只为减少 TCP 的握手延迟而设计,而非提高连接的吞吐量。Mux 实质上不能提高网速,但对并发连接比较有效。

HTTP

仅作为识别,通过基本的用户名密码做识别,安全性较低,官方建议仅作为局域网段内监听使用。

Socks

仅仅识别, 没有对传输加密,不适宜经公网中传输,适用场景是若只能使用socks proxy访问时情况,可作为为其他协议连接代理服务器的前置代理使用。

Dokodemo-door

任意门入站协议,负责识别协议, 主要用作端口映射和透明代理。

TCP

本作为传输层协议,在项目里同样也是仅负责传输,同时可伪装header,同时伪装完整的http头,包含Request和Responces。但官方不推荐使用伪装及结合TLS使用

WebSocket

传输协议,WebSocket 连接可以被其它 HTTP 服务器(如 NGINX)分流。可自定header里的host。其主要特性是作为应用层协议支持套TLS安全协议,且天然支持长连接和使用代理场景类似增加识别难度,底层还是TCP传输性能会稍微有所损耗。

HTTP/2

识别协议+内容协议, 完整按照 HTTP/2 标准实现,可以通过其它的 HTTP 服务器(如 Nginx)进行中转。 客户端和服务端届强制TLS,安全性很有保证。

QUIC

传输协议,使用 UDP 进行多路并发传输 ,作为较新的协议,目前还在实验期间,也是强制TLS。优势主要是减少握手延迟,多路复用不阻塞,连接迁移,劣势主要是ISP会对其QOS。

二、可自定义的路由和DNS

V2内建了一个简单的路由功能,可以将入站数据按需求由不同的出站连接发出,以达到按需代理的目的,此路由可以细化不同的代理场景搭配不同规则,还可用Balancer对象完成负载均衡。

配合 Blackhole(黑洞)协议一起使用,可以达到禁止访问某些网站的效果,也可配合IP收集项目也可开启应用分流或白名单模式等细分场景。

作者谈路由

举一个例子:对于国内用户来说,国内站点需要直连;而对于国外用户来说,国内站点需要代理(因为源 IP 地区的问题)。目前大多数规则列表的做法是创建两个几乎一样的列表,区别只是每个域名后面跟着的“代理/直连”指令。这样看上去十分啰嗦,而且容易出错。在 V2Ray 中,你只需要使用一份列表,修改一下它们的 outboundTag即可。

V2还内置了一个 DNS 服务器,其有两大主要用途:根据域名的解析IP匹配路由规则,以及像传统的DNS功能,解析目标地址进行连接。由此 DNS 服务器所发出的 DNS 查询请求,会自动根据路由配置进行转发,无需额外配置。

内置路由和DNS结合起来,可以加强抗干扰性,可以细化场景(DNS分流)和完成一些附加功能(去广告,禁止协议,防止DNS劫持污染等等)

https://img.ocasis.cn/image/5e52af82ac3bf
DNS模块的处理过程

三、安全

模式识别

支持块加密

AEAD 就是 Authenticated Encryption with Associated Data,使用关联数据进行身份验证加密,是一种同时具备保密性、完整性和可认证性的加密方法。兼容块加密可以让识别过程更复杂。

重放攻击与CCA / CPA

VMess 从 2.19 开始可以抵御重放攻击。防止截获到的正常数据可用于攻击。

支持引入TLS

TLS链式证书校验

根据CA给出的解密公钥算签名结果是否符合,如符合则验证上级CA,同时通过CRL和OCSP协议防止过期,有效防止MITM攻击

https://img.ocasis.cn/image/5e53c1ca76087
校验证书和加密都会进行
Forward Secrey

使用DH 加密方式(非对称加密 具体使用ECDH或RSA)则最后生成的 sessionKey 和 private key 并没有直接关系,通过非对称加密,生成对称加密的 session key。

https://img.ocasis.cn/image/5e53c1ca76087
DH算法简单图示

四、总结

https://img.ocasis.cn/image/5e53c1b2b5125
官方文档给出的设计思路说明

目标

  • V2Ray 内核提供了一个平台,支持必要的网络代理功能,在其之上可以进二次开发,以提供更好的用户体验;
  • 以跨平台为首要原则,以减少二次开发的成本
应用层

重要模块列表:

  • Dispatcher: 用于把入站代理所接收到的数据,传送给出站代理;
  • Router: 内置路由,详见路由配置
  • DNS: 内置的 DNS 缓存;
  • Proxy Manager: 入站代理的管理器;
代理层

代理层分为两部分:入站代理(Inbound Proxy)和出站代理(Outbound Proxy)。两部分相互独立,入站代理不依赖于某个特定的出站代理

传输层

传输层提供一些网络数据传输相关的工具模块

归总

看到这里基本上和文章最开头作者说的FQ协议的三个部分契合了,就是从抽象到实现的具体过程了,和OSI模型对应的话就是网络层>传输层>应用层。然后v2的应用层就负责处理流量和路由DNS保证性能,代理层则是具体的自研协议或兼容性强的通用协议,主要负责识别(还可加密和混淆)或是内容(优化数据),至于传输层,则专门负责作为数据通道,主要是把传统传输层和应用层协议拿来用。三者分开,并可依据需求分别选择,无论从开发者开发角度还是使用者自定义功能使用角度,ProjectV的设计思维目前来看确实是达到了。

引用

代理协议三要素
核心设计思想

赞赏
欢迎留言交流讨论,留言必回。

admin

文章作者

一个平凡的追梦人

发表评论

textsms
account_circle
email

x1184的小站

简单聊聊ProjectV设计思路
看文档加动手实操,反推一些值得学习的概念和实现方式。整理一下
扫描二维码继续阅读
2020-02-08