1. 高级篇
恭喜大家来到高级篇。 使用基础篇当中的配置案例科学上网足够了,但 V2Ray 提供了许多额外的功能,若不利用着实可惜。在本篇当中,将针对某个功能简要介绍,并给出关键配置,因此可能不是完整的,也不会像基础篇那样详细,只会在关键之处作一些必要的介绍。
V2Ray 的相比其它工具有一大优点是可以自行选择传输层的形式,也就是说 V2Ray 服务器和客户端之间的传输的流量格式我们是可以选择的。如我们可以选择伪装成 HTTP(TCP)流量,如果使用了 mKCP 也可以伪装成 BT 下载、视频通话、微信视频通话。也可以选择使用 WebSokcs 或者 TLS。以上这个都是传输层的配置决定的。
V2Ray 中传输层配置在 transport 里设定,也可以在各个 inbound/outbound 中的 streamSettings 设定。这两者的区别是 inbound/outbound 的 streamSettings 只对当前的 inbound/outbound 有效(分连接配置),不影响其它的 inbound/outbound 的传输层配置,而 transport 是全局的,对整个配置所有的 inbound 和 outbound 都有效(全局配置),如果一个 inbound/outbound 中设定了 streamSettings,transport 的设定不会影响这个 inbound/outbound。
在本篇当中,大部分内容都涉及到了传输层,关于这部分内容使用的是 inbound/outbound 的 streamSettings(分连接配置),同时也建议大家使用分连接配置。因为如果你在全局配置中开启了伪装功能,会导致浏览器或者其它软件无法与 V2Ray 通信!这不是 bug,只是因为你设置不当。
一、Mux
1. Mux
Mux 意为多路复用(multiplexing),在目前的科学上网工具中仅 V2Ray 有此功能(2018-03-15注:也有其他软件实现了类似的功能)。它能够将多条 TCP 连接合并成一条,节省资源,提高并发能力。
听众:呃?什么鬼?
好吧,翻译成人话就是:
从前,有一个人叫小白,他是骑行爱好者,还是网购狂人、DIY玩家,因此手中有点闲钱总会网购,也喜欢自己买配件组装自行车。有一次他组装自行车,在网上骑行之家买了头盗、手套、码表,在x诺专卖店买了指拨、变速器,在x特专卖买了车架,在xx车行买了刹车、踏板、坐垫,在xxx买了轮组、曲柄……
四天后…… 9 点小白手机响了,接通,小白:喂,你好。对方:你好,申x快递,来取一下包裹。小白兴兴冲地取快递了。 20 分钟后,小白:喂,你好。对方:你好,韵x,过来取快递。小白又去了。 又过 15 分钟,小白:喂,你好。对方:你好,天x,来取快递。小白又去了。 又过半个小时,小白:什么快递?对方:圆x,快点来。小白心里:我X。 10 分钟后……
如果是你是小白,你累不累? 电脑也差不多,但要干的活要小白多得多:
浏览器:我要看 V2Ray 配置指南。 电脑:好,我发起一条 TCP 连接。 Telegram:我要进 V2Ray 的 Telegram 群向大佬学习。 电脑:好,发起了连接。 浏览器:我要看 V2Ray 的手册。 电脑:好。 浏览器:我要 Google 搜索 V2Ray 的教程。 电脑:好。 浏览器:我要……
如果正常的上网连接可以使用上面小白的例子类比的话,那么,V2Ray 的 Mux 就是:
小黑也与小白一样自行组装自行车,也是网购配件,但他无论什么东西都从xx车行这店里买。
4 天后,小黑接起电话:你好。 对方:你好,顺x,来取一下快递。 小黑顺路买了瓶饮料:大哥,天气这么热,喝点水解解渴。嘿嘿,这箱子太沉,辛苦一下帮帮我搬到屋里吧。
Mux 实质上不能提高网速,但对并发连接比较有效,如浏览图片较多的网页,看直播等。从使用效果来说,V2Ray 的 Mux 应该类似于 Shadowsocks 的 TFO(TCP Fast Open),因为两者的目的都是减小握手时间,只是实现方式不一样。只是 TFO 要设置系统内核才能打开,而 Mux 是纯粹在软件层面上实现,从配置难易度上 V2Ray 较好一些。(2018-09-19 注:刚更新这段话没多久,V2Ray 就加入了对 TFO 的支持,感觉要学不动了~)
1.1. 配置
Mux 只需在客户端开启,服务器会自动识别,所以只给客户端的配置。也就是只要在 outbound 或 outboundDetour 加入 "mux": {"enabled": true}
即可:
{ "inbound": { "port": 1080, // 监听端口 "protocol": "socks", // 入口协议为 SOCKS 5 "domainOverride": ["tls","http"], "settings": { "auth": "noauth" // 不认证 } }, "outbound": { "protocol": "vmess", // 出口协议 "settings": { "vnext": [ { "address": "serveraddr.com", // 服务器地址,请修改为你自己的服务器 ip 或域名 "port": 16823, // 服务器端口 "users": [ { "id": "b831381d-6324-4d53-ad4f-8cda48b30811", // 用户 ID,必须与服务器端配置相同 "alterId": 64 // 此处的值也应当与服务器相同 } ] } ] }, "mux": {"enabled": true} } }
1.2. 更新历史
2018-08-30 修改排版、描述
二、mKCP
1. mKCP
V2Ray 引入了 KCP 传输协议,并且做了一些不同的优化,称为 mKCP,相对于常规的 TCP 来说,mKCP 在某些网络环境下具有更大的优势,但是 mKCP 有一个很明显的缺点就是会比 TCP 耗费更多的流量,所以请酌情使用。要了解的一点是,mKCP 与 KCPTUN 同样是 KCP 协议,但两者并不兼容。
1.1. 配置
mKCP 的配置比较简单,只需在服务器的 inbound 和 客户端的 outbound 添加一个 streamSettings 并设置成 mkcp 即可。
1.1.1. 服务器配置
{ "inbound": { "port": 16823, "protocol": "vmess", "settings": { "clients": [ { "id": "b831381d-6324-4d53-ad4f-8cda48b30811", "alterId": 64 } ] }, "streamSettings": { "network": "mkcp", //此处的 mkcp 也可写成 kcp,两种写法是起同样的效果 "kcpSettings": { "mtu": 1350, "tti": 20, "uplinkCapacity": 5, "downlinkCapacity": 100, "congestion": true, "readBufferSize": 1, "writeBufferSize": 1, "header": { "type": "none" } } } }, "outbound": { "protocol": "freedom", "settings": {} } }
1.1.2. 客户端配置
{ "inbound": { "port": 1080, "protocol": "socks", "domainOverride": ["tls","http"], "settings": { "auth": "noauth" } }, "outbound": { "protocol": "vmess", "settings": { "vnext": [ { "address": "serveraddr.com", "port": 16823, "users": [ { "id": "b831381d-6324-4d53-ad4f-8cda48b30811", "alterId": 64 } ] } ] }, "streamSettings": { "network": "mkcp", "kcpSettings": { "mtu": 1350, "tti": 20, "uplinkCapacity": 5, "downlinkCapacity": 100, "congestion": ture, "readBufferSize": 1, "writeBufferSize": 1, "header": { "type": "none" } } } } }
1.1.3. 说明
在上面的配置当中,与之前相比主要的变化在于多了一个 streamSettings,包含有不少参数:
network
: 网络的选择,要像上面的配置写成 kcp 或 mkcp 才会启用 mKCPkcpSettings
: 包含一些关于 mKCP 设置的参数,有type
:要伪装成的数据包类型uplinkCapacity
: 上行链路容量,将决定 V2Ray 向外发送数据包的速率。单位为 MBdownlinkCapacity
:下行链路容量,将决定 V2Ray 接收数据包的速率。单位同样是 MBheader
:对于数据包的伪装
客户端的上行对于服务器来说是下行,同样地客户端的下行是服务器的上行,mKCP 设置当中服务器和客户端都有 uplinkCapacity 和 downlinkCapacity,所以客户端的上传速率由服务器的 downlinkCapacity 和客户端的 uplinkCapacity 中的最小值决定,客户端的下载速率也是同样的道理。因此,建议将服务器和客户端的 downlinkCapacity 设成一个很大的值,然后分别修改两端的 uplinkCapacity 以调整上下行速率。
还有一个 header 参数可以对 mKCP 进行伪装,这是 mKCP 的一个优势。具体的伪装类型在 type 参数设置,type 可以设置成 utp、srtp、wechat-video、dtls、wireguard 或者 none,这几个分别将 mKCP 数据伪装成 BT 下载、视频通话、微信视频通话、dtls、wireguard(一种新型 VPN)以及不进行伪装。这里的 type 参数,客户端与服务器要一致。还有要时刻记住伪装仅仅是伪装。
至于上述配置里有但是我没有说明的参数,是 V2Ray 的默认值,我个人建议是保持默认。如果你需要了解或者修改,请参考手册。
1.2. 更新历史
2018-03-17 Update
2018-08-30 Update
1. 动态端口
V2Ray 提供了一个叫动态端口的功能。顾名思义,就是可以动态变化端口,对于对抗封锁或许有效,请大家自行验证。
1.1. 基本动态端口
服务器 inbound 的端口作为主端口,在 inboundDetour 开动态监听的端口,客户端不用额外设定。
1.1.1. 服务器配置
{ "inbound":{ "port": 37192, "protocol": "vmess", "settings": { "clients": [ { "id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f", "level": 1, "alterId": 64 } ], "detour": { "to": "dynamicPort" } } }, "inboundDetour":[ { "protocol": "vmess", "port": "10000-20000", // 端口范围 "tag": "dynamicPort", "settings": { "default": { "level": 1, "alterId": 32 } }, "allocate": { // 分配模式 "strategy": "random", // 随机开启 "concurrency": 2, // 同时开放两个端口 "refresh": 3 // 每三分钟刷新一次 } } ] }
1.1.2. 客户端配置
{ "outbound": { "protocol": "vmess", "settings": { "vnext": [ { "address": "1.2.3.4", "port": 37192, "users": [ { "id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f", "alterId": 64 } ] } ] } } }
1.2. 动态端口使用 mKCP
在 inbound 和 inboundDetour 加入 streamSettings 并将 network 设置为 kcp 即可。
1.2.1. 服务器配置
{ "inbound": { "port": 37192, "protocol": "vmess", "settings": { "clients": [ { "id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f", "level": 1, "alterId": 64 } ], "detour": { "to": "dynamicPort" } }, "streamSettings": { "network": "kcp" } }, "inboundDetour": [ { "protocol": "vmess", "port": "10000-20000", // 端口范围 "tag": "dynamicPort", "settings": { "default": { "level": 1, "alterId": 32 } }, "allocate": { // 分配模式 "strategy": "random", // 随机开启 "concurrency": 2, // 同时开放两个端口 "refresh": 3 // 每三分钟刷新一次 }, "streamSettings": { "network": "kcp" } } ] }
1.2.2. 客户端配置
{ "outbound": { "protocol": "vmess", "settings": { "vnext": [ { "address": "1.2.3.4", "port": 37192, "users": [ { "id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f", "alterId": 64 } ] } ] }, "streamSettings": { "network": "kcp" } } }
1.3. 更新历史
2018-01-06 删除错误且不必要的部分
四、代理转发
1. 代理转发
V2Ray 提供了代理转发功能,利用它可以实现中转(在没有中转服务器操作权限的情况下)。
1.1. 基本代理转发
使用代理转发可以实现由一个 Shadowsocks 服务器或者 V2Ray(VMess) 服务器来中转你的网络流量,并且中转服务器只能看到你加密的数据而不知道原始的数据是什么。
以下面的配置说明,它的工作原理是:
你在 Twitter 发了个帖子 f**k GFW,由 V2Ray 代理
V2Ray 客户端收到浏览器发出的 f**k GFW 的帖子后,首先由对其进行加密(VMess,id: b12614c5-5ca4-4eba-a215-c61d642116ce,目的服务器: 1.1.1.1:8888)
加密后数据包将被转到 transit 这个 outbound 中,在这里数据包又会加密一次(Shadowsocks, password: password, 服务器: 2.2.2.2:1024)
两次加密后的数据包被发送到了 Shadowsocks 服务器,该服务器收到后解包后得到仍是加密的数据包(步骤 2 中加密后的数据包),然后将数据包发到 VMess 服务器。即便这个 Shadowsocks 服务器的主人是个偷窥狂魔,他也没办法看到你的原始数据。
VMess 服务器收到 Shadowsocks 服务器发来的数据包,解密得到原始的数据包,然后把你这个帖子发到 Twitter 的网站中。
只要第 5 步中的服务器是自己掌控的就不用担心别人看到你的上网的内容。
客户端:
{ "outbound": { "protocol": "vmess", "settings": { // settings 的根据实际情况修改 "vnext": [ { "address": "1.1.1.1", "port": 8888, "users": [ { "alterId": 64, "id": "b12614c5-5ca4-4eba-a215-c61d642116ce" } ] } ] }, "proxySettings": { "tag": "transit" // 这里的 tag 必须跟作为代理 VPS 的 tag 一致,这里设定的是 "transit" } }, "outboundDetour": [ { "protocol": "shadowsocks", "settings": { "servers": [ { "address": "2.2.2.2", "method": "aes-256-cfb", "ota": false, "password": "password", "port": 1024 } ] }, "tag": "transit" } ] }
1.2. 链式代理转发
如果你有多个 Shadowsocks 或 VMess 账户,那么你可以这样:
{ "outbound": { "protocol": "vmess", "settings": { // settings 的根据实际情况修改 "vnext": [ { "address": "1.1.1.1", "port": 8888, "users": [ { "alterId": 64, "id": "b12614c5-5ca4-4eba-a215-c61d642116ce" } ] } ] }, "tag": "DOUS", "proxySettings": { "tag": "DOSG" } }, "outboundDetour": [ { "protocol": "shadowsocks", "settings": { "servers": [ { "address": "2.2.2.2", "method": "aes-256-cfb", "ota": false, "password": "password", "port": 1024 } ] }, "tag": "AliHK" }, { "protocol": "shadowsocks", "settings": { "servers": [ { "address": "3.3.3.3", "method": "aes-256-cfb", "ota": false, "password": "password", "port": 3442 } ] }, "tag": "AliSG", "proxySettings": { "tag": "AliHK" } }, { "protocol": "vmess", "settings": { "vnext": [ { "address": "4.4.4.4", "port": 8462, "users": [ { "alterId": 64, "id": "b27c24ab-2b5a-433e-902c-33f1168a7902" } ] } ] }, "tag": "DOSG", "proxySettings": { "tag": "AliSG" } }, ] }
那么数据包经过的节点依次为: PC -> AliHK -> AliSG -> DOSG -> DOUS -> 目标网站
这样的代理转发形成了一条链条,我称之为链式代理转发。
注意:如果你打算配置(动态)链式代理转发,应当明确几点:
性能
。链式代理使用了多个节点,可能会造成延时、带宽等网络性能问题,并且客户端对每一个加解密的次数取决于代理链的长度,理论上也会有一定的影响。安全
。前文提到,代理转发会一定程度上提高安全性,但安全取决于最弱一环,并不意味着代理链越长就会越安全。如果你需要匿名,请考虑成熟的匿名方案。 另外,使用了代理转发 streamSettings 会失效,即只能是非 TLS、无 HTTP 伪装的 TCP 传输协议。
1.3. 更新历史
2018-03-17 Update
2018-07-08 Update
五、HTTP 伪装
1. HTTP 伪装
(2018-03-16 注:个人建议不要使用 HTTP 伪装) V2Ray 自 v2.5 版本开始提供 HTTP 伪装功能,后经作者不断完善,到现在已经非常成熟稳定了。V2Ray 的 HTTP 伪装功能可以可以将 V2Ray 的流量伪装成正常的 HTTP 协议的。这里给出一个 HTTP 伪装的服务器端与客户端配置文件示例。
配置中关于 HTTP 头字段的内容及含义,Wikipedia 有简要的说明,可参阅。
1.1. 配置
从 V2Ray 的实现角度来说,使用 HTTP 伪装的同时完全可以使用动态端口。但我个人并不建议这么做,因为从实际情况来看,基本上不会有人在一个服务器上开使用多个端口的 Web 服务。如果你觉得 HTTP 伪装的配置过于复杂不懂得如何修改,那请直接使用下面的配置即可。
1.1.1. 服务器
{ "log" : { "access": "/var/log/v2ray/access.log", "error": "/var/log/v2ray/error.log", "loglevel": "warning" }, "inbound": { "port": 80, //推荐80端口,更好地迷惑防火墙(好吧实际上并没有什么卵用 "protocol": "vmess", "settings": { "clients": [ { "id": "b831381d-6324-4d53-ad4f-8cda48b30811", "level": 1, "alterId": 64 } ] }, "streamSettings": { "network": "tcp", "tcpSettings": { "header": { // header 这一项是关于数据包伪装的设置,可自定义合理的内容,但要确保服务器与客户端一致 "type": "http", "response": { "version": "1.1", "status": "200", "reason": "OK", "headers": { "Content-Type": ["application/octet-stream", "application/x-msdownload", "text/html", "application/x-shockwave-flash"], "Transfer-Encoding": ["chunked"], "Connection": ["keep-alive"], "Pragma": "no-cache" } } } } } }, "outbound": { "protocol": "freedom", "settings": {} }, "outboundDetour": [ { "protocol": "blackhole", "settings": {}, "tag": "blocked" } ], "routing": { "strategy": "rules", "settings": { "rules": [ { "type": "field", "ip": [ "0.0.0.0/8", "10.0.0.0/8", "100.64.0.0/10", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.2.0/24", "192.168.0.0/16", "198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "::1/128", "fc00::/7", "fe80::/10" ], "outboundTag": "blocked" } ] } } }
1.1.2. 客户端
{ "log": { "loglevel": "warning" }, "inbound": { "port": 1080, "protocol": "socks", "domainOverride": ["tls","http"], "settings": { "auth": "noauth" } }, "outbound": { "protocol": "vmess", "settings": { "vnext": [ { "address": "serveraddr.com", "port": 80, "users": [ { "id": "b831381d-6324-4d53-ad4f-8cda48b30811", "alterId": 64 } ] } ] }, "streamSettings": { "network": "tcp", "tcpSettings": { "header": { //这里的 header 要与服务器保持一致 "type": "http", "request": { "version": "1.1", "method": "GET", "path": ["/"], "headers": { "Host": ["www.cloudflare.com", "www.amazon.com"], "User-Agent": [ "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36", "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46" ], "Accept-Encoding": ["gzip, deflate"], "Connection": ["keep-alive"], "Pragma": "no-cache" } } } } } }, "outboundDetour": [ { "protocol": "freedom", "settings": {}, "tag": "direct" } ], "routing": { "strategy": "rules", "settings": { "domainStrategy": "IPIfNonMatch", "rules": [ { "type": "field", "ip": [ "0.0.0.0/8", "10.0.0.0/8", "100.64.0.0/10", "127.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.0.0.0/24", "192.0.2.0/24", "192.168.0.0/16", "198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", "::1/128", "fc00::/7", "fe80::/10" ], "outboundTag": "direct" }, { "type": "chinasites", "outboundTag": "direct" }, { "type": "chinaip", "outboundTag": "direct" } ] } } }
1.2. 更新历史
2017-08-05 删掉部分不必要的配置
2018-03-16 Update
1. TLS
从 v1.19 起引入了 TLS,TLS 中文译名是传输层安全,如果你没听说过,请 Google 了解一下。以下给出些我认为介绍较好的文章链接:
1.1. 注册一个域名
如果已经注册有域名了可以跳过。 TLS 需要一个域名,域名有免费的和有付费的,如果你不舍得为一个域名每年花点钱,用个免费域名也可以,但总体来说付费的会优于免费的。为了方便,在本文中我就忽略如何注册购买域名了。关于如何获取域名,具体搜索相关文章教程。
注册好域名之后务必记得添加一个 A 记录指向你的 VPS!
以下假设注册的域名为 mydomain.me,请将之替换成自己的域名。
1.2. 证书生成
TLS 是证书认证机制,所以使用 TLS 需要证书,证书也有免费付费的,同样的这里使用免费证书,证书认证机构为 Let's Encrypt。 证书的生成有许多方法,这里使用的是比较简单的方法:使用 acme.sh 脚本生成,本部分说明部分内容参考于acme.sh README。
证书有两种,一种是 ECC 证书(内置公钥是 ECDSA 公钥),一种是 RSA 证书(内置 RSA 公钥)。简单来说,同等长度 ECC 比 RSA 更安全,也就是说在具有同样安全性的情况下,ECC 的密钥长度比 RSA 短得多(加密解密会更快)。但问题是 ECC 的兼容性会差一些,Android 4.x 以下和 Windows XP 不支持。只要您的设备不是非常老的老古董,强烈建议使用 ECC 证书。
以下将给出这两类证书的生成方法,请大家根据自身的情况自行选择其中一种证书类型。
证书生成只需在服务器上操作。
1.2.1. 安装 acme.sh
执行以下命令,acme.sh 会安装到 ~/.acme.sh 目录下。
$ curl https://get.acme.sh | sh % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 671 100 671 0 0 680 0 --:--:-- --:--:-- --:--:-- 679 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 112k 100 112k 0 0 690k 0 --:--:-- --:--:-- --:--:-- 693k [Fri 30 Dec 01:03:32 GMT 2016] Installing from online archive. [Fri 30 Dec 01:03:32 GMT 2016] Downloading https://github.com/Neilpang/acme.sh/archive/master.tar.gz [Fri 30 Dec 01:03:33 GMT 2016] Extracting master.tar.gz [Fri 30 Dec 01:03:33 GMT 2016] Installing to /home/user/.acme.sh [Fri 30 Dec 01:03:33 GMT 2016] Installed to /home/user/.acme.sh/acme.sh [Fri 30 Dec 01:03:33 GMT 2016] Installing alias to '/home/user/.profile' [Fri 30 Dec 01:03:33 GMT 2016] OK, Close and reopen your terminal to start using acme.sh [Fri 30 Dec 01:03:33 GMT 2016] Installing cron job no crontab for user no crontab for user [Fri 30 Dec 01:03:33 GMT 2016] Good, bash is found, so change the shebang to use bash as preferred. [Fri 30 Dec 01:03:33 GMT 2016] OK [Fri 30 Dec 01:03:33 GMT 2016] Install success!
安装成功后执行 source ~/.bashrc
以确保脚本所设置的命令别名生效。
如果安装报错,那么可能是因为系统缺少 acme.sh 所需要的依赖项,acme.sh 的依赖项主要是 netcat(nc),我们通过以下命令来安装这些依赖项,然后重新安装一遍 acme.sh:
$ sudo apt-get -y install netcat
1.2.2. 使用 acme.sh 生成证书
证书生成
执行以下命令生成证书:
以下的命令会临时监听 80 端口,请确保执行该命令前 80 端口没有使用
$ sudo ~/.acme.sh/acme.sh --issue -d mydomain.me --standalone -k ec-256 [Fri Dec 30 08:59:12 HKT 2016] Standalone mode. [Fri Dec 30 08:59:12 HKT 2016] Single domain='mydomain.me' [Fri Dec 30 08:59:12 HKT 2016] Getting domain auth token for each domain [Fri Dec 30 08:59:12 HKT 2016] Getting webroot for domain='mydomain.me' [Fri Dec 30 08:59:12 HKT 2016] _w='no' [Fri Dec 30 08:59:12 HKT 2016] Getting new-authz for domain='mydomain.me' [Fri Dec 30 08:59:14 HKT 2016] The new-authz request is ok. [Fri Dec 30 08:59:14 HKT 2016] mydomain.me is already verified, skip. [Fri Dec 30 08:59:14 HKT 2016] mydomain.me is already verified, skip http-01. [Fri Dec 30 08:59:14 HKT 2016] mydomain.me is already verified, skip http-01. [Fri Dec 30 08:59:14 HKT 2016] Verify finished, start to sign. [Fri Dec 30 08:59:16 HKT 2016] Cert success. -----BEGIN CERTIFICATE----- MIIEMTCCAxmgAwIBAgISA1+gJF5zwUDjNX/6Xzz5fo3lMA0GCSqGSIb3DQEBCwUA MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNjEyMjkyMzU5MDBaFw0x NzAzMjkyMzU5MDBaMBcxFTATBgNVBAMTDHdlYWtzYW5kLmNvbTBZMBMGByqGSM49 **************************************************************** 4p40tm0aMB837XQ9jeAXvXulhVH/7/wWZ8/vkUUvuHSCYHagENiq/3DYj4a85Iw9 +6u1r7atYHJ2VwqSamiyTGDQuhc5wdXIQxY/YQQqkAmn5tLsTZnnOavc4plANT40 zweiG8vcIvMVnnkM0TSz8G1yzv1nOkruN3ozQkLMu6YS7lk/ENBN7DBtYVSmJeU2 VAXE+zgRaP7JFOqK6DrOwhyE2LSgae83Wq/XgXxjfIo1Zmn2UmlE0sbdNKBasnf9 gPUI45eltrjcv8FCSTOUcT7PWCa3 -----END CERTIFICATE----- [Fri Dec 30 08:59:16 HKT 2016] Your cert is in /root/.acme.sh/mydomain.me_ecc/mydomain.me.cer [Fri Dec 30 08:59:16 HKT 2016] Your cert key is in /root/.acme.sh/mydomain.me_ecc/mydomain.me.key [Fri Dec 30 08:59:16 HKT 2016] The intermediate CA cert is in /root/.acme.sh/mydomain.me_ecc/ca.cer [Fri Dec 30 08:59:16 HKT 2016] And the full chain certs is there: /root/.acme.sh/mydomain.me_ecc/fullchain.cer
-k
表示密钥长度,后面的值可以是 ec-256
、ec-384
、2048
、3072
、4096
、8192
,带有 ec
表示生成的是 ECC 证书,没有则是 RSA 证书。在安全性上 256 位的 ECC 证书等同于 3072 位的 RSA 证书。
证书更新
由于 Let's Encrypt 的证书有效期只有 3 个月,因此需要 90 天至少要更新一次证书,acme.sh 脚本会每 60 天自动更新证书。也可以手动更新。
手动更新 ECC 证书,执行:
$ sudo ~/.acme.sh/acme.sh --renew -d mydomain.com --force --ecc
如果是 RSA 证书则执行:
$ sudo ~/.acme.sh/acme.sh --renew -d mydomain.com --force
由于本例中将证书生成到 /etc/v2ray/
文件夹,更新证书之后还得把新证书生成到 /etc/v2ray。
1.2.3. 安装证书和密钥
ECC 证书
将证书和密钥安装到 /etc/v2ray 中:
$ sudo ~/.acme.sh/acme.sh --installcert -d mydomain.me --fullchainpath /etc/v2ray/v2ray.crt --keypath /etc/v2ray/v2ray.key --ecc
RSA 证书
$ sudo ~/.acme.sh/acme.sh --installcert -d mydomain.me --fullchainpath /etc/v2ray/v2ray.crt --keypath /etc/v2ray/v2ray.key
注意:无论什么情况,密钥(即上面的v2ray.key)都不能泄漏,如果你不幸泄漏了密钥,可以使用 acme.sh 将原证书吊销,再生成新的证书,吊销方法请自行参考 acme.sh 的手册
1.3. 配置 V2Ray
1.3.1. 服务器
{ "inbound": { "port": 443, // 建议使用 443 端口 "protocol": "vmess", "settings": { "clients": [ { "id": "23ad6b10-8d1a-40f7-8ad0-e3e35cd38297", "alterId": 64 } ] }, "streamSettings": { "network": "tcp", "security": "tls", // security 要设置为 tls 才会启用 TLS "tlsSettings": { "certificates": [ { "certificateFile": "/etc/v2ray/v2ray.crt", // 证书文件 "keyFile": "/etc/v2ray/v2ray.key" // 密钥文件 } ] } } }, "outbound": { "protocol": "freedom", "settings": {} } }
1.3.2. 客户端
{ "inbound": { "port": 1080, "protocol": "socks", "domainOverride": ["tls","http"], "settings": { "auth": "noauth" } }, "outbound": { "protocol": "vmess", "settings": { "vnext": [ { "address": "mydomain.me", // tls 需要域名,所以这里应该填自己的域名 "port": 443, "users": [ { "id": "23ad6b10-8d1a-40f7-8ad0-e3e35cd38297", "alterId": 64 } ] } ] }, "streamSettings": { "network": "tcp", "security": "tls" // 客户端的 security 也要设置为 tls } } }
1.4. 验证
一般来说,按照以上步骤操作完成,V2Ray 客户端能够正常联网说明 TLS 已经成功启用。但要是有个可靠的方法来验证是否正常开启 TLS 无疑更令人放心。 验证的方法有很多,我仅介绍一种小白化一点的,便是 Qualys SSL Labs's SSL Server Test。
注意:使用 Qualys SSL Labs's SSL Server Test 要求使用 443 端口,意味着你服务器配置的 inbound.port 应当是 443
打开 Qualys SSL Labs's SSL Server Test,在 Hostname 中输入你的域名,点提交,过一会结果就出来了。
这是对于你的 TLS/SSL 的一个总体评分,我这里评分为 A,看来还不错。有这样的界面算是成功了。
这是关于证书的信息。从图中可以看出,我的这个证书有效期是从 2016 年 12 月 27 号到 2017 年的 3 月 27 号,密钥是 256 位的 ECC,证书签发机构是 Let's Encrypt,重要的是最后一行,
Trusted
为 Yes
,表明我这个证书可信。
1.5. 温馨提醒
V2Ray 的 TLS 不是伪装或混淆,这是完整、真正的 TLS。因此才需要域名和证书。后文提到的 WS(WebSocket) 也不是伪装。
1.6. 更新历史
2017-08-06 加点提醒
2017-12-31 修正文字错误
2018-04-05 Update
1. WebSocket
WebSocket 的配置其实很简单,就跟 mKCP 一样把 network 一改就行了。话不多说,直接上配置。
1.1. 配置
1.1.1. 服务器配置
{ "inbound": { "port": 16823, "protocol": "vmess", "settings": { "clients": [ { "id": "b831381d-6324-4d53-ad4f-8cda48b30811", "alterId": 64 } ] }, "streamSettings": { "network":"ws" } }, "outbound": { "protocol": "freedom", "settings": {} } }
1.1.2. 客户端配置
{ "inbound": { "port": 1080, "protocol": "socks", "domainOverride": ["tls","http"], "settings": { "auth": "noauth" } }, "outbound": { "protocol": "vmess", "settings": { "vnext": [ { "address": "serveraddr.com", "port": 16823, "users": [ { "id": "b831381d-6324-4d53-ad4f-8cda48b30811", "alterId": 64 } ] } ] }, "streamSettings":{ "network":"ws" } } }
1. WebSocket+TLS+Web
前文分别提到过 TLS 和 WebSocket 的配置方法,而本文搭配 Web 服务并同时实现 TLS 和 WebSocket。关于 Web 的软件本文给出了 Nginx,Caddy 和 Apache 三个例子,三选一即可,也可以选用其它的软件。
很多新手一接触 V2Ray 就想搞 WebSocket+TLS+Web 或 WebSocket+TLS+Web+CDN,我就想问 ssh 和 vim/nano 用利索了没,步子这么大不怕扯到蛋吗?使用 Nginx / Caddy / Apache 是因为 VPS 已经有 Nginx / Caddy / Apache 可以将 V2Ray 稍作隐藏,使用 WebSocket 是因为搭配 Nginx / Caddy / Apache 只能用 WebSocket,使用 TLS 是因为可以流量加密,看起来更像 HTTPS。 也许 WebSocket+TLS+Web 的配置组合相对较好,但不意味着这样的配置适合任何人。因为本节涉及 Nginx / Caddy / Apache,只给出了配置示例而不讲具体使用方法,也就是说你在阅读本节内容前得会使用这三个软件的其中之一,如果你还不会,请自行 Google。
注意: V2Ray 的 Websocket+TLS 配置组合并不依赖 Nginx / Caddy / Apache,只是能与其搭配使用而已,没有它们也可以正常使用。
1.1. 配置
1.1.1. 服务器配置
这次 TLS 的配置将写入 Nginx / Caddy / Apache 配置中,由这些软件来监听 443 端口(443 比较常用,并非 443 不可),然后将流量转发到 V2Ray 的 WebSocket 所监听的内网端口(本例是 10000),V2Ray 服务器端不需要配置 TLS。
服务器 V2Ray 配置
{ "inbound": { "port": 10000, "listen":"127.0.0.1",//只监听 127.0.0.1,避免除本机外的机器探测到开放了 10000 端口 "protocol": "vmess", "settings": { "clients": [ { "id": "b831381d-6324-4d53-ad4f-8cda48b30811", "alterId": 64 } ] }, "streamSettings": { "network": "ws", "wsSettings": { "path": "/ray" } } }, "outbound": { "protocol": "freedom", "settings": {} } }
Nginx 配置
配置中使用的是域名和证书使用 TLS 小节的举例,请替换成自己的。
server { listen 443 ssl; ssl on; ssl_certificate /etc/v2ray/v2ray.crt; ssl_certificate_key /etc/v2ray/v2ray.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; server_name mydomain.me; location /ray { proxy_redirect off; proxy_pass http://127.0.0.1:10000;#假设WebSocket监听在环回地址的10000端口上 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $http_host; } }
Caddy 配置
因为 Caddy 会自动申请证书并自动更新,所以使用 Caddy 不用指定证书、密钥。
mydomain.me { log ./caddy.log proxy /ray localhost:10000 { websocket header_upstream -Origin } }
Apache 配置
同样地,配置中使用的是域名和证书使用 TLS 小节的举例,请替换成自己的。
<VirtualHost *:443> ServerName mydomain.me SSLCertificateFile /etc/v2ray/v2ray.crt SSLCertificateKeyFile /etc/v2ray/v2ray.key SSLProtocol -All +TLSv1 +TLSv1.1 +TLSv1.2 SSLCipherSuite HIGH:!aNULL <Location "/ray/"> ProxyPass ws://127.0.0.1:10000/ray/ upgrade=WebSocket ProxyAddHeaders Off ProxyPreserveHost On RequestHeader append X-Forwarded-For %{REMOTE_ADDR}s </Location> </VirtualHost>
1.1.2. 客户端配置
{ "inbound": { "port": 1080, "listen": "127.0.0.1", "protocol": "socks", "domainOverride": ["tls","http"], "settings": { "auth": "noauth", "udp": false } }, "outbound": { "protocol": "vmess", "settings": { "vnext": [ { "address": "mydomain.me", "port": 443, "users": [ { "id": "b831381d-6324-4d53-ad4f-8cda48b30811", "alterId": 64 } ] } ] }, "streamSettings": { "network": "ws", "security": "tls", "wsSettings": { "path": "/ray" } } } }
1.1.3. 注意事项
V2Ray 暂时不支持 TLS1.3,如果开启并强制 TLS1.3 会导致 V2Ray 无法连接
较低版本的nginx的location需要写为 /ray/ 才能正常工作
如果在设置完成之后不能成功使用,可能是由于 SElinux 机制(如果你是 CentOS 7 的用户请特别留意 SElinux 这一机制)阻止了 Nginx 转发向内网的数据。如果是这样的话,在 V2Ray 的日志里不会有访问信息,在 Nginx 的日志里会出现大量的 "Permission Denied" 字段,要解决这一问题需要在终端下键入以下命令:
setsebool -P httpd_can_network_connect 1
请保持服务器和客户端的 wsSettings 严格一致,对于 V2Ray,
/ray
和/ray/
是不一样的
1.1.4. 其他的话
开启了 TLS 之后 path 参数是被加密的,GFW 看不到;
主动探测一个 path 产生 Bad request 不能证明是 V2Ray;
不安全的因素在于人,自己的问题就不要甩锅,哪怕我把示例中的 path 改成一个 UUID,依然有不少人原封不动地 COPY;
使用 Header 分流并不比 path 安全, 不要迷信。
1.2. 更新历史
2017-12-05 加一些提示
2018-01-03 Update
2018-08-19 Update
2018-08-30 Add configuration for Apache2
1. HTTP/2
简单地说 HTTP/2 是 HTTP/1.1 的升级版(目前大多数网页还是 HTTP/1.1),点击这里可以直观地体会到 HTTP/2 相比于 HTTP/1.1 的提升(不代表 V2Ray 中 HTTP/2 相对于 TCP 的提升就是这样的)。
由于我不清楚 V2Ray 引入 HTTP/2 的意图是什么,V2Ray 的手册也没有对此进行说明,再加上我没怎么测试过 HTTP/2 ,所以呢关于 HTTP/2 有什么高级的姿势我也不甚了解。如果有网友发现了新姿势,欢迎告知。
1.1. 配置
与其它的传输层协议一样在 streamSettings 中配置,不过要注意的是使用 HTTP/2 要开启 TLS。
1.1.1. 服务器配置
{ "inbound": { "port": 443, "protocol": "vmess", "settings": { "clients": [ { "id": "b831381d-6324-4d53-ad4f-8cda48b30811", "alterId": 64 } ] }, "streamSettings": { "network": "h2", // h2 也可写成 http,效果一样 "httpSettings": { //此项是关于 HTTP/2 的设置 "path": "/ray" }, "security": "tls", // 配置tls "tlsSettings": { "certificates": [ { "certificateFile": "/etc/v2ray/v2ray.crt", // 证书文件,详见 tls 小节 "keyFile": "/etc/v2ray/v2ray.key" // 密钥文件 } ] } } }, "outbound": { "protocol": "freedom", "settings": {} } }
1.1.2. 客户端配置
{ "inbound": { "port": 1080, "listen": "127.0.0.1", "protocol": "socks", "domainOverride": ["tls","http"], "settings": { "auth": "noauth", "udp": false } }, "outbound": { "protocol": "vmess", "settings": { "vnext": [ { "address": "mydomain.me", "port": 443, "users": [ { "id": "b831381d-6324-4d53-ad4f-8cda48b30811", "alterId": 64 } ] } ] }, "streamSettings": { "network": "h2", "httpSettings": { //此项是关于 HTTP/2 的设置 "path": "/ray" }, "security": "tls" } } }
1.2. 更新历史
2018-03-18 初版
2018-08-30 Update
1. CDN
Cloudflare 还是太慢了,用国内的吧,绝对能体验飞一般的速度,正好 V2Ray 已经支持 HTTP/2 了,又拍云、七牛、阿里都不错,腾讯的 h2 还在内测,百度不清楚。不过说真的,CDN 的话国外的还是有些水土不服,强烈建议使用国内的,速度提升非常大,也非常稳定,高峰期毫无压力,在重点 IP 段也无所畏惧。
1.1. 配置
懒得写怎么配置了,会用 Cloudflare,其他的 CDN 也不会有问题。
1.2. 更新历史
2018-03-18 初版
1. 不推荐的配置
也许有一部分朋友发现了,高级篇的内容关于传输层的,各种配置的组合,可以搭配出非常多的配置。但是,有一些组合是我认为不值得或者是冗余的(仅代表个人意见),以下给出。
TLS+KCP
这是相当一部分人喜欢的组合。选用KCP的原因是为了在某些恶劣的网络环境下拥有比较好的上网体验。而使用 TLS 的原因大约有两种考虑:一是认为 TLS 拥有与 HTTPS 一样的特征不容易被墙;二是觉得TLS具有更好的加密效果不容易被墙。对于第一点,尽管 HTTPS 是基于 TLS,但并不等同与 TLS,因此 TLS 与 HTTPS 的特征一样的说法是错误的;对于第二点,使用更强的加密算法而被墙的几率更小这个观点并未得到论证。然而这并不是我不推荐的理由,真正的原因的是不使用 TLS 并没什么坏处,额外使用 TLS也没有足够的好处。
TLS+HTTP 伪装
我并没有测试过这个组合,不清楚最外层是 TLS 还是 HTTP 伪装。无论哪一种,处于内层的配置将会失去其意义。
单纯使用 Websocket
理论上,使用 Websocket 会比 TCP 性能差一些,单纯所以如果不是搭配 CDN、nginx 或者在 PaaS 上使用,那还是使用 TCP 吧。
还没有评论,来说两句吧...