背景
(2022年)8月17日下午,原本正常使用的V2Ray服务突然遭遇频繁的TCP阻断,网络访问断断续续,大有服务器要跪的样子。无奈这是基础服务,只能放下手头正在开展的工作,转来优先处理这个问题🤬。
我当前ISP是联通,远程服务器配置是Nginx+tls+websocket+V2Ray。上次服务器配置更新是在2年半前,期间也有配置需要调整,但服务运行正常,我懒得没动。
为处理这个问题,我做了以下前置动作:
最终确定下来,我要趁这个机会做如下调整:
- 放弃原本的CentOS,改系统为Debian。CentOS停止支持,换上Debian图个安稳。
- 更换原有域名。原有域名只有这一个作用,释放后停止续费节省票子。
- 给V2Ray的新域名套上cloudflare。之前一直不想更换nameserver,也不想处理CDN的https证书,所以没套CDN。这次套CDN也不一定能用,但至少应该会保住IP。 在保住IP的前提下,剩下的慢慢解决。
- 记录此次配置过程。就因为我一直没写文档,所以在这么长的时间里我没有调整过配置。为此我多花了域名1年的费用…心疼ing。
我暂时不打算更换V2Ray,我不确定别的软件有比V2Ray更优秀。翻墙图的是稳定,哪怕慢我也是可以接受的。别的软件我看都在优化性能上了,就没有尝试加强隐蔽性或者寻找其他过墙方案上吗?
说干就干。在TCP阻断的情况下,只能先连国内VPS,再ssh到国外。恰好我有台阿里ECS。
操作记录
重装系统
我的服务器是搬瓦工的,重装系统的过程就是关机
-登陆官网后台
-进入KiwiVM管理页面
-Install new OS
。没什么好说的,还不会的话看这篇登录KiwiVM控制面板并重装系统官方文档即可。
重装Debian系统后第一件事就是更新系统。本篇所有的服务器指令都是直接以root身份执行的。
apt update
apt list --upgradable
apt upgrade
sync
reboot
开启防火墙。搬瓦工修改了默认的ssh端口,所以在执行防火墙开启指令ufw enable
前,必须先将指定的ssh端口加入允许列表(ufw allow 12345/tcp
指令开放了12345端口的tcp连接),否则……即便使用默认ssh端口,在开启防火墙前也要先加允许。防火墙ufw的详细使用可参考在Debian中配置防火墙ufw。
apt update
apt install ufw
ufw status
ufw allow 12345/tcp
ufw enable
ufw status
安装nginx(nginx+tls)
nginx的安装没什么好说的,直接看我另一篇nginx安装文档就行。
接下来就是配置nginx,打开防火墙,完成dns解析。有人说在freenom上可以免费购买域名,但需要点技巧。我不想耽误时间,也不想再额外添加一个没有用的域名,即使它是免费的。我这边只提供下信息,谁有需要谁自己去研究。
配置nginx,添加一个新的空站点。
mkdir /usr/share/nginx/html/new_site
cp /usr/share/nginx/html/index.html /usr/share/nginx/html/new_site/
chown -R nginx:nginx /usr/share/nginx/html/new_site/
cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/new_site.conf
mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.deleted
vi /etc/nginx/conf.d/new_site.conf
,新内容如下:
server {
server_name newsite.com;
access_log /var/log/nginx/newsite.com.access.log main;
root /usr/share/nginx/html/new_site;
index index.html;
location / {
try_files $uri $uri/ =404;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# 转发websocket请求到v2ray配置,开始
# 转发websocket请求到v2ray配置,结束
}
使新站点配置生效:
nginx -t
nginx -s reload
防火墙允许80、443端口访问。
ufw status
ufw allow http
ufw allow https
ufw status
在完成newsite.com域名的dns解析后,网站已经可以正常访问了。接下来我们会为网站开启https。此处我是通过snapd安装certbot,并使用certbot获取https证书的。certbot --nginx
会自动修改nginx配置文件以开启站点https访问。
apt update
apt install snapd
sync
reboot
snap install core
snap refresh core
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot
certbot --nginx
至此,tls也有了。
安装v2ray(v2ray+websocket)
安装v2ray。v2ray的官网现在是v2fly了,这是需要注意的。它的文档中包含了Debian下v2ray的安装。具体指令如下:
apt update
apt install v2ray
v2ray -version
systemctl status v2ray
额外补充几点,省得我日后还要重读文档:
- 我丝毫不关心官方文档中说的
Unstable 仓库
到底是什么,官方配置步骤中的1、2、3被直接跳过; - 这样直接安装的v2ray版本是
4.34.0
,写在这里日后配置v2ray时方便确认该版本是否支持新功能; - 官方配置文档中使用
systemctl edit v2ray.service
特别指定日志目录不是必需的,你不一定需要开启v2ray日志;我开启了日志,所以也执行了官方此步骤的推荐配置; systemctl edit v2ray.service
命令相当于执行vi /usr/lib/systemd/system/v2ray.service
后再执行systemctl daemon-reload
,它们是等效的。- v2ray默认的配置文件是
/etc/v2ray/config.json
。
配置v2ray,vi /etc/v2ray/config.json
修改文件内容如下:
{
"log":
{
"access": "/var/log/v2ray/access.log",
"error": "/var/log/v2ray/error.log",
"loglevel": "warning"
},
"inbounds":
[
{
"sniffing":
{
"enabled": true,
"destOverride":
[
"http",
"tls"
]
},
"port": 22222,
"listen": "127.0.0.1",
"protocol": "vmess",
"settings":
{
"clients":
[
{
"id": "57d47ad2-9b73-4991-a8c5-394f89522c0e",
"level": 1,
"alterId": 0
}
]
},
"streamSettings":
{
"network": "ws",
"wsSettings":
{
"path": "/fxxKThEW0r1d"
}
}
}
],
"outbounds":
[
{
"protocol": "freedom",
"settings": {}
},
{
"protocol": "blackhole",
"settings": {},
"tag": "blocked"
}
],
"routing":
{
"domainStrategy": "AsIs",
"rules":
[
{
"type": "field",
"outboundTag": "block",
"protocol":
[
"bittorrent"
]
}
]
}
}
关于此配置文件的几点说明:
- 开启了日志;
- 开启了流量嗅探,不开启嗅探没办法知道客户端在跑bt;
- 封锁了所有bt流量,以免被vps提供商拒绝服务;
- 监听本地
127.0.0.1
地址的22222
端口。127.0.0.1
无法通过外网IP直接访问; - 创建了一个用户
57d47ad2-9b73-4991-a8c5-394f89522c0e
; - 允许在vps上通过访问
http://127.0.0.1:22222/fxxKThEW0r1d
进行websocket
通信。 - 新V2Ray白话文指南上提供了很多实用的v2ray配置技巧,你可以拿来学习参考。
- 我对v2ray配置的看法是,如果只是拿来翻墙用,完全没有必要了解太多,谁知道它哪天就被封了。
"alterId": 0
是当前版本v2ray的推荐配置;"path": "/fxxKThEW0r1d"
大家推荐使用乱码,虽然我认为这样做没有任何意义…- 此配置无需防火墙配置,因为监听的是本地IP。
使新配置生效。
v2ray -test
systemctl restart v2ray
有坑列一下,能帮助一个是一个:
- 如果你不用nginx做前端,而是直接让v2ray以tcp tls的方式来提供服务,需要以root身份来启动v2ray,否则会报错。因为你需要让v2ray去读取证书文件,而普通用户没有读取证书权限的。以root方式启动v2ray需要修改
v2ray.service
文件。不建议使用这种配置,被墙风险高,还给v2ray提权了。不想给v2ray提权就老老实实用nginx。既然nginx都用了就把websocket给加上。这主要是官方文档的锅,把v2ray的tcp tls教程放在前面。
关于v2ray客户端,windows下用v2rayN,安卓v2rayNG。iPhone用Shadowrocket。
整合nginx+v2ray(nginx+tls+websocket+v2ray)
整合nginx与v2ray的过程,就是让nginx将收到的来自公网的websocket请求转发到监听本地地址的v2ray上。
你只需要vi /etc/nginx/conf.d/new_site.conf
,在# 转发websocket请求到v2ray配置,开始
和# 转发websocket请求到v2ray配置,结束
中间的空白行上添加如下内容:
location /fxxKThEW0r1d {
if ($http_upgrade != "websocket") {
return 404;
}
proxy_redirect off;
proxy_pass http://127.0.0.1:22222;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
# Show real IP in v2ray access.log
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
使nginx新配置生效:
nginx -t
nginx -s reload
配置cloudflare(cdn)
终于来到了之前没来过的地方。
原本是直接访问自己站点的,但是在站点前加一个cdn,我们在访问自己网站的时候会访问cdn的节点,数据由cdn提供。cdn提供的数据是它访问我们网站返回的。这样做的好处就是我们隐藏了自己网站的ip——我们连接的是cdn节点的ip。gfw一般不ban cdn的ip。
为了使用cf的cdn,我们需要把nameserver换成cf提供的ns。在更换ns的过程中,需要对比原来的域名解析记录,将这些记录在cf里面补全——cf在没有成为域名指定的ns前无法获取全部的解析记录。
设置完ns后,设置cf连接的加密方式为“Full SSL”,注意,不是“Full SSL (strict)”。 为了省事儿,我们不强迫使用https,允许用户访问http。 这里说的省事儿,是我还想把证书的获取工作交给Let's Encrypt去做:cf的证书要么收费,要么还需要配置。而Let's Encrypt的证书每3个月需要更新一次,更新的时候它会访问网站自身的http,而不是网站自身的https。如果设置cf强制转换请求为https,Let's Encrypt可能无法正常更新证书。
配置完cf,我们可以验证下网站https证书延期的功能是否依然正常:
certbot renew --dry-run
关于cf配置过程中的坑记录一下:
- 有人说把cloudflare workers当reverse proxy使用也可以完成网站的IP隐藏。这种不需要设置ns的方法对我诱惑挺大,但实际测试结果是无法正常访问v2ray,是不可行的。它会报错
[Warning] app/proxyman/outbound: failed to process outbound traffic > proxy/vmess/outbound: failed to find an available destination > common/retry: [transport/internet/websocket: failed to dial WebSocket > transport/internet/websocket: failed to dial to (wss://hello-my-friend-365.v2ray.workers.dev/fxxKThEW0r1d): > remote error: tls: handshake failure] > common/retry: all retry attempts failed
。从报错上来看,是由于cloudflare workers使用的是cf颁发的证书,而不是我们站点自己的https证书导致的。直接使用cdn才能解决这个证书问题,因为cdn使用的是我们站点自己的证书。
在配置cf前我还查了一些资料,放出来以防有人需要:
- 在使用Cloudflare的网站上,签发Let’s Encrypt证书的问题
- 验证已在Cloudflare上激活的站点的Let’s Encrypt证书 - 这是cf官方的文章
- let's encrypt配合cloudflare CDN使用 - 此人思路新奇
至此,cdn+nginx+tls+websocket+v2ray的配置全部完成。
有人说可以通过工具优选Cloudflare CDN节点IP,进而加快v2ray的访问。我无意尝试。
系统优化
有人说配置bbr效果会比较好。可惜我一行sysctl net.ipv4.tcp_congestion_control
下去发现搬瓦工已经默认启用bbr了。有需要的朋友自己去看How to Enable BBR on Debian。
总结
结果:还是时断时续的,而且延时(ping)加大,下载速度变慢。不过总算是不担心vps IP彻底被ban了,可以开始担心域名被干了。
完成这些配置后,至少可以省下未来域名的钱,和更换IP的钱,不算亏。
为了心里更有底些,我还下载了tor,好在彻底断网的时候临时顶一顶,让我能有个窗口期去寻找新的解决办法。tor单独使用,没有与v2ray配合。v2ray被封的时候,配合使用无意义。
后记
2022.9.2
连通不稳定的情况再次发生,但没比我重新配置前严重。是时候尝试寻找其他方案了。
查看过的其他文档: