余生、漫漫长路,有些人终其一生都在追寻虚无缥缈的迷途微光。余生很长,何必慌张。
——《往后余生》
GFW作为又一道万里长城,为了保护中国公民远离社交媒体荼毒立下了汗马功劳(迫真!)。大概计算机的某种鄙视链,用Google的看不上用Baidu的,用Tor的看不上用Google的,用V2Ray的鄙视用SSR的,用Trojan的斜眼看自己配V2Ray的,如此种种就当听个笑话~
回归正题,为了应对疫情过后注意力回归的GFW升级,想着提前升级到WSS组合拳上。之前用的基本的VMess + Google Cloud HK or Taiwan,也不知道是不是Google大环线堪比IPLC,简单实用一直稳定,VM价格$5/月 + 流量$20/月;最近精简开支,就Vultr SPG + V2Ray WSS (其实Vultr SPG也是日本中转线路,不过日本的IP基本都挂了,就……)
默认大家伙已经具备了搭建基础V2Ray功能的水平,这次线路就是Basic V2Ray ——> V2Ray WSS的升级路线。**[V2Ray + WebSocket + TLS + Nginx + Cloudflare]**
基本点
客户端 Ubuntu 19.10,服务器端 Ubuntu18.04。Shell默认使用ZSH。
默认大家伙已经具备了搭建基础V2Ray功能的水平,这次线路就是Basic V2Ray ——> V2Ray WSS的升级路线。
Linux包管理器是aptitude后端的多线程apt-fast,命令中的apt-fast
都可以换成aptitude
无伤大雅。
涉及到域名的地方就用your.domain
代替了,不会有人真的照抄吧……(笑
几种V2Ray进阶传输协议的对比和选择
先说结论,看完可以直接跳过后面大段描述:
- WSS:有能力搞定域名和解析,推荐使用WebSocket+TLS (WSS) ,可以的话再增加CDN支持。
- WS:没有办法搞定域名,推荐直接使用WebSocket。
- mKCP:对于处在拥堵网络,如4G的用户,推荐使用mKCP伪装,并打开Mux多路复用。
WebSocket (WS)
WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
简单说,WebSocket解决了HTTP协议的部分问题,比如每次求都携带状态信息(如身份认证等)、请求每次都要携带完整的头部等等。再加上由于WebSocket全双工通信,因此能够很好的进行实时通信。用在V2Ray上时,请求与应答的效率要远高于HTTP,而V2Ray的请求要远高于普通的请求,所以WebSocket可以说是一种不错的选择。同时由于WebSocket本身已经成熟,因此有Cloudflare这类云服务商支持基于WebSocket流量的CDN服务,这进一步增进了原本的服务器的安全性。
TLS
传输层安全性协议(英语:Transport Layer Security,缩写作TLS),及其前身安全套接层(Secure Sockets Layer,缩写作SSL)是一种安全协议,目的是为互联网通信提供安全及数据完整性保障。
对于TLS,其实大家不应该觉得陌生,TLS作用于HTTP便诞生出了现今最为常用的协议HTTPS,那么作用于WebSocket,自然便成了WSS,也就是WebSocket+TLS。
TLS的作用就好比是一个保险箱,不管在传输HTTP还是WebSocket的时候,传输中的内容均是以明文的方式传输的。也就是说,只要有人对传输数据拦截,是完全可以知道你在传输什么东西。而TLS就是用来交换最开始的“锁”的方式,保证传输的保密。
对于V2Ray来说,虽然经过了协议的加密,但是这类流量本身就并不“正常”。试想,你手机连接了V2ray,大量数据通过协议向一个固定IP请求,而数据内容与普通的数据格格不入。这自然会引起部分人的警觉。如果嵌套一个保险箱(TLS),让数据显得和其他请求的数据没什么两样,这样一方面减少了审查者的怀疑,另一方面又加强了数据的安全性。当然由于TLS本身存在一个加密解密的过程,因此势必会对传输的效率带来影响。不过影响是微乎其微的,想要追求安全,自然也需要一定的牺牲。
h2 (HTTP/2)
h2便是HTTP/2 (原名HTTP/2.0)即超文本传输协议 2.0,是下一代HTTP协议。对于V2Ray,使用h2必须同时使用TLS。h2本质是HTTP协议,对于传统http1.1协议传输速度快了不少,无主界便是基于h2的网站。h2的下层协议是TCP,因此大家应该知道这类协议的共同缺点了。
较之类似的WebSocket协议,传输效率略逊于WebSocket。但是它却有比WebSocket更加好的伪装,由于大部分网站使用HTTP协议,因此h2+TLS这种协议能使V2Ray流量伪装在正常流量中,并且难以察觉。
QUIC
2018年11月,国际互联网工程任务组(The Internet Engineering Task Force,简称 IETF )将HTTP-over-QUIC 实验性协议将被重命名为 HTTP/3,并有望成为 HTTP 协议的第三个正式版本,代表了互联网的未来。不久之后,无主界也许也会支持这个协议。
QUIC(Quick UDP Internet Connection)是谷歌制定的一种基于UDP的低时延的互联网传输层协议。此协议基于UDP,但较之KCP更为可靠。由于现今V2Ray的QUIC并不是真正意义上的HTTP/3,因此存在一定的兼容问题。
WSS (WebSocket + TLS + Web Server) 的完整安装与配置
使用 Nginx/Caddy/Apache 是因为 VPS 已经有 Nginx/Caddy/Apache 可以将 V2Ray 稍作隐藏,使用 WebSocket 是因为搭配 Nginx/Caddy/Apache 只能用 WebSocket,使用 TLS 是因为可以流量加密,看起来更像 HTTPS。 也许 WebSocket + TLS + Web 的配置组合相对较好,但不意味着这样的配置适合任何人。
注意: V2Ray 的 Websocket + TLS 配置组合并不依赖 Nginx/Caddy/Apache,只是能与其搭配使用而已,没有它们也可以正常使用。
域名注册
就像论文写了一页半的Introduction,我们终于进入正题!TLS 需要一个域名,域名有免费的和有付费的,如果你不舍得为一个域名每年花点钱,用个免费域名也可以,但总体来说付费的会优于免费的。
免费的域名申请可以移步Freenom,不过谨记
免费的就是最贵的
。付费域名租用,国内使用阿里云域名(曾经的万网),国外多币信用卡使用GoDaddy可以帮助降低审计风险(既然如此在GoDaddy就不要选择AliPay)。
注册好域名之后务必记得添加一个 A 记录指向你的 VPS!再次说明,以下涉及到域名的地方就用your.domain
代替,域名的地方就用your.domain
代替,域名的地方就用your.domain
代替。
TLS证书生成和更新
TLS 是证书认证机制,所以使用 TLS 需要证书,证书也有免费付费的,同样的这里使用免费证书,证书认证机构为 Let’s Encrypt。 证书的生成有许多方法,这里使用的是比较简单的方法:使用 acme.sh 脚本生成,本部分说明部分内容参考于acme.sh README。
证书有两种,一种是 ECC 证书(内置公钥是 ECDSA 公钥),一种是 RSA 证书(内置 RSA 公钥),建议使用 ECC 证书。简单来说,同等长度 ECC 比 RSA 更安全,也就是说在具有同样安全性的情况下,ECC 的密钥长度比 RSA 短得多(加密解密会更快)。ECC 的兼容性会差一些,Android 4.x 以下和 Windows XP 不支持。
证书生成只需在服务器上操作。以下将给出这两类证书的生成方法,请大家根据自身的情况自行选择其中一种证书类型。
acme.sh 的依赖项主要是 socat,我们通过以下命令来安装这些依赖项,然后安装一遍 acme.sh。执行以下命令,acme.sh 会安装到 ~/.acme.sh 目录下。
1 | sudo apt-fast install -y openssl cron socat curl |
安装成功后执行 source ~/.bashrc
(对应zsh source ~/.zshrc
)以确保脚本所设置的命令别名生效,看见zshrc最后添加了. "/home/v2/.acme.sh/acme.sh.env"
的别名解析。
使用 acme.sh 生成证书:执行以下命令生成证书,命令会临时监听 80 端口,请确保执行该命令前 80 端口没有使用。
1 | sudo ~/.acme.sh/acme.sh --issue -d your.domain --standalone -k ec-256 --force |
其中 -k 表示密钥长度,后面的值可以是 ec-256 、ec-384、2048、3072、4096、8192,带有 ec 表示生成的是 ECC 证书,没有则是 RSA 证书。在安全性上 256 位的 ECC 证书等同于 3072 位的 RSA 证书。这里使用sudo
不加--force
会触发一个警告,打开 https://github.com/acmesh-official/acme.sh/wiki/sudo 可以看到使用sudo
可能导致续订失败,暂时还不知道效果,先酱紫。
手动更新 ECC 证书
由于 Let’s Encrypt 的证书有效期只有 3 个月,因此需要 90 天至少要更新一次证书,acme.sh 脚本会每 60 天自动更新证书。也可以手动更新。
1 | 如果是 RSA 证书 |
安装证书和密钥
由于本例中将证书生成到 /etc/v2ray/ 文件夹,更新证书之后还得将新证书和密钥安装到 /etc/v2ray 中:
1 | ECC 证书 |
注意:无论什么情况,密钥(即上面的v2ray.key)都不能泄漏,如果你不幸泄漏了密钥,可以使用 acme.sh 将原证书吊销,再生成新的证书,吊销方法请自行参考 acme.sh手册
TLS配置验证
一般来说,按照以上步骤操作完成,V2Ray 客户端能够正常联网说明 TLS 已经成功启用。但要是有个可靠的方法来验证是否正常开启 TLS 无疑更令人放心。
打开 Qualys SSL Labs’s SSL Server Test,在 Hostname 中输入你的域名,点提交,过一会结果就出来了。
从图中可以看出关于证书的信息,我的这个证书有效期是从 21 Mar 2020 到 19 Jun 2020 ,密钥是 256 位的 ECC,证书签发机构是 Let’s Encrypt,重要的是最后一行,Trusted 为 Yes,表明我这个证书可信。
Web服务器的选择/安装/配置
Apache和Nginx的对比和选择
首先给出结论:一般来说,需要性能的Web服务,用Nginx 。如果不需要性能只求稳定,那就Apache吧。
Nginx相对于Apache的优点:轻量级,同样起Web服务,比Apache占用更少的内存及资源抗并发,Nginx处理请求是异步非阻塞的,而Apache则是阻塞型的,在高并发下Nginx能保持低资源低消耗高性能高度模块化的设计,编写模块相对简单社区活跃,各种高性能模块出品迅速。
Apache 相对于Nginx 的优点:rewrite,比Nginx的rewrite强大模块超多,基本想到的都可以找到;Bug少,超稳定,存在就是理由。
Nginx安装
1 | sudo apt-fast update |
Nginx测试
安装成功后打开浏览器,打开你的域名(your.domain)或者输入服务器IP(x.x.x.x)地址,如果看到默认的Nginx登录页面,则安装成功。
Nginx Cheat Sheet
需求 | 命令 |
---|---|
启动Nginx服务 | sudo systemctl start nginx |
停止Nginx服务 | sudo systemctl stop nginx |
重新启动Nginx服务 | sudo systemctl restart nginx |
重新加载Nginx服务 | sudo systemctl reload nginx |
禁用Nginx服务以在启动时启动 | sudo systemctl disable nginx |
重新启用Nginx服务以在启动时启动 | sudo systemctl enable nginx |
Nginx配置文件的结构和最佳做法
- 所有Nginx配置文件都位于/etc/nginx目录中。
- 主要的Nginx配置文件为/etc/nginx/nginx.conf。
- 为使Nginx配置更易于维护,建议为每个域创建一个单独的配置文件。您可以根据需要拥有任意数量的服务器块文件。
- Nginx服务器块文件存储在/etc/nginx/sites-available目录中。除非它们链接到/etc/nginx/sites-enabled目录,否则Nginx不会使用此目录中找到的配置文件。
- 要激活服务器块,您需要从以下目录中的配置文件站点创建符号链接(指针)将sites-available目录移到sites-enabled目录。
- 建议遵循标准命名约定,例如,如果您的域名是your.domain,则您的配置文件应命名为/etc/nginx/sites-available/your.domain.conf ]
- /etc/nginx/snippets目录包含可包含在服务器块文件中的配置片段。如果使用可重复的配置段,则可以将这些段重构为片段,并将片段文件包括到服务器块中。
- Nginx日志文件(access.log和error.log)位于/var/log/nginx目录中。建议每个服务器块使用不同的access和error日志文件。
- 您可以将域文档根目录设置为所需的任何位置。 Webroot的最常见位置包括:
/home//
/var/www/
/var/www/html/
/opt/
Nginx服务器配置
这次 TLS 的配置将写入 Nginx 配置中,由ta来监听 443 端口(443 比较常用,并非 443 不可),然后将流量转发到 V2Ray 的 WebSocket 所监听的内网端口(本例是14400),V2Ray 服务器端则不需要配置 TLS。
服务器V2Ray和Nginx配置
服务器 V2Ray 配置
1 | { |
Nginx 配置
注意替换配置中的是域名和证书。将以下代码以v2ray_ws_tls.conf
保存在 /etc/nginx/conf.d
路径下作为Nginx的一个单独模块加载。如果出现任何Nginx启动失败的提示,请在/var/log/nginx
自行查看错误日志 error.log
。
1 | server { |
注意事项
V2Ray 自4.18.1后支持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/ 是不一样的
较低版本的系统/浏览器可能无法完成握手. 如 Chrome 49/XP SP3, Safari 8/iOS 8.4, Safari 8/OS X 10.10 及更低的版本. 如果你的设备比较旧, 则可以通过在配置中添加较旧的 TLS 协议以完成握手.
CDN的配置和使用
目前和 V2Ray 兼容的 CDN 国外有 Cloudflare,国内阿里云,这两家的 CDN 是支持 WebSocket 的。剩下的几家不支持 WebSocket,也不会 keep TCP connection。因此 HTTP/2 回源也不支持(访问支持 HTTP/2 和回源支持 HTTP/2 是两回事)。另外,使用国内 CDN 需要域名备案并服务商实名认证。使用有风险,入坑需谨慎。
确保 Cloudflare 的 Crypto 选项卡的 SSL 为 Full,并且请确保 SSL 选项卡有显示 Universal SSL Status Active Certificate 这样的字眼,如果你的 SSL 选项卡没有显示这个,不要急,只是在申请证书,24 小时内可以搞定。
有关 Cloudflare 的 Firewall(防火墙)问题
最近突然有遇见经过 CDN 的代理完全无法通讯的情况哦。 有趣的是,在 VPS 里没有任何相关日志,并且不走 CDN 的话就可以正常通讯并出现相关日志了呢;而走 CDN 的 Web 可以正常访问,但 Path 界面却出现了 Challenge(Captcha)。也就是说,问题就在于 Cloudflare 啦。在 Firewall 界面有看见大量 IP 被拦截的记录,问题 GET👍。
稍稍总结一下不同的解决方案:
- Firewall => Settings => Security Level,设置为 Essentially Off (默认是 Medium,个人实测改为 Low 仍被拦截)。
- 无需修改 Security Level,而是 Firewall => Tools,将 China(或被 Block 的 IP/ASN)作为 Whitelist。
- Issues 里有提到,可以 Firewall => Firewall Rules,添加 Country => China 或 IP Address =>(被 Block 的 IP)或 URL Path => (wsSettings 里 的那个 path),为 Allow 即可,但个人实测,Activity log 里会显示,先是被 Firewall Rules 所 Allow,随后又被 Security Level 所 Block。
- 针对解决方案 3,建议各位在出现被拦截的问题之前就进行此操作,本文所提的个人实测是在已经出现被拦截的情况下所进行的哦。
总结和回顾
整体方法就是:客户端V2Ray使用TLS协议访问domain443端口,服务器端Nginx监听443端口来信并转发至14400端口,服务器端V2Ray监听14400的Nginx转发信息并进一步向外传递,形成完整信息交互链。因为使用域名访问,自然而然可以附加CDN隐藏服务器IP。
祝诸位事毕功成!!!
注意以下几点:
- 开启了 TLS 之后 path 参数是被加密的,GFW 看不到;
- 主动探测一个 path 产生 Bad request 不能证明是 V2Ray;
- 使用 Header 分流并不比 path 安全, 不要迷信。
TODO
- 我的第一次……长篇,后续慢慢改进。当前主题似乎是不适合图文太多,而且缺少目录 (懒得用hexo-toc,会全部生成),更换主题提上calendar。[Done]
Reference
- https://baike.baidu.com/item/IPLC
- https://cloud.google.com/
- https://www.idleleo.com/05/2071.html
- http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html
- https://zh.wikipedia.org/wiki/%E5%82%B3%E8%BC%B8%E5%B1%A4%E5%AE%89%E5%85%A8%E5%8D%94%E8%AD%B0
- https://github.com/acmesh-official/acme.sh
- https://github.com/Neilpang/acme.sh/wiki/Options-and-Params
- https://juejin.im/post/5dd5fac6f265da47dd1af995
- http://www.zhangjiee.com/blog/2019/apache-vs-nginx.html
- https://www.v2ray.com/
- https://nginx.org/cn/