最近开始白嫖公司的香港云服务器了,与之前自购的美国 VPS 对比测试下来无论是在网络延时、稳定性还是性能都有了比较大的改善。秉承资源利用最大化的原则,这台服务器的流量不能仅用于访问 Google,所以干脆把之前托管在 Github Pages 上的博客(其实是 Student Pack 到期之后,免费用户的私有项目用不了 GitHub Pages),以及自己搞的一些奇奇怪怪的网站也都迁移了过来(原来跑在腾讯云 1Mbps 的境内服务器上,SSL 握手时间都能让人抓狂)。
明确需求
- 访问 Google 要保证安全且快,这里选择 VLESS 方案
- 需要同时兼容多域名站点,这里有几个方案可选:单证书多域名 + VLESS 回落,前置 Nginx 分流,前置 HAProxy 分流
方案选则
VLESS 回落方案
由于 VLESS 本身不支持根据 SNI 来分流,需要支持多域名就需要签在同一张证书上。Let’s Encrypt 已经对泛域名证书有了比较完美的支持,配合 acme.sh 很容易实现单证书多域名(我所有的域名都在 Cloudflare 下解析)
然后这仍然有些一些问题,VLESS fallback 方案对 Typecho 的支持并不好(翻了一下其他博文,对 WordPress 之类的 php 程序支持也不行),所以无奈放弃这种方案(其实我也不太想将 VLESS 作为前置的 TCP 分流器)。于是开始尝试 Nginx 前置分流方案
Nginx 前置分流
借助 Nginx 的 ssl_preread
模块来实现 SNI,配置起来也很简单,只需要增加 stream
块
1 | stream { |
然后在站点配置里增加对上述 web 端口的监听即可
1 | server { |
其实这种方案本来也没什么问题,我开始也觉得可以就这样了。之后无意间发现博客后台记录的一些 client_ip 是 127.0.0.1,于是乎又不得不折腾 HAProxy 方案来分流
HAProxy 前置分流
HAProxy 相较于 ngx_stream_ssl_preread_module 的优点就是可以为每一个不同的 backend 设置不一样的数据传递方式,正是因为 nginx 做不到这一点所以上一个方案才会被 pass 掉
正巧 Proxy Protocol 就是用来做这个事情的,正巧 HAProxy 和 Nginx 对这个的支持都不错。相比而言 HAProxy 的配置文件 haproxy.cfg
显得就比较简单一点:
1 | global |
同样的对应 Nginx 站点配置也需要加上对 Proxy Protocol 的支持:
1 | server { |
一些提示
- 部分软件的安装方式和文档基本都可以在 https://github.com/v2fly 找到
- 需要做 http 跳 https 的话直接 Nginx 监听 80 跳
https://$server_name$request_uri
即可 - 因为 Nginx 的跳转是默认使用的是绝对地址,上述配置存在
https://web1.example.com/path
跳https://web1.example.com:8443/path/
的情况,需要使用absolute_redirect off
设置为相对地址的跳转
更新
2021.04.10 更新
翻阅 VLESS 文档无意间发现其入站支持 Proxy Protocol,果断卸载 HAProxy,用回上文中所说的 Nginx 分流方案,只需要在 stream.server
的配置块里新加一行 proxy_protocol on
,同时 VLESS 的配置项 streamSettings.tcpSettings
中加入 "acceptProxyProtocol": true
即可
2022.06.04 更新
翻阅 xray 文档 发现已经支持了 SNI 分流功能,所以如果没有什么很复杂的负载均衡需求,完全靠 xray 也足够了