1.前言
前文有提到过,黑五的时候看到RackNerd促销,就买了个便宜的VPS小鸡,一年才$10多点,不幸的是,到手没多久发现IP就被封了,意思就是,国内不能直连VPS了,中间需要一个在国内能访问的海外节点当作代理或者跳板才能访问这个小鸡。
但是,如果说要想更换IP,需要额外支付$3,我觉得这个钱不值得,谁知道即使换了新的又能坚持多久,况且监测之后发现,它用的是较差的线路,慢慢就闲置了。
最近为了处理实际需求,经过精心筛选,在DMIT上买了台CN2GIA线路的VPS,2C3G的配置,要月付$19.9,同等配置比搬瓦工要便宜一点。不得不说,一分钱一分货,处理器的差别实际使用感受不大,但是线路的区别就很明显,尤其是晚高峰的时候,用代理访问不了的网站,用CN2GIA就可以,1.5TB的4Gbps高速流量和不限量的低速流量,如果也有需要可以点下面这个链接有没有合适的,支持支付宝:
DMIT-高性能计算设施
2.介绍
节点是什么?简单来说,可以把节点当作运行在一台机器上的一个进程。在国内无法直接访问Google,但是如果把这个访问请求发给节点进程,因为节点的机器在海外,没有限制,它可以访问Google,它把Google返回的响应,再发给国内的你,这样一来,原本无法访问Google的你,通过一个在海外的节点,也可以顺利访问Google了,当然,这只是一个笼统的介绍,中间有诸多流程和细节。
从上面说的过程可以看出,可以运行节点进程的机器首先需要的就是在国内可以直接访问,也就是VPS IP没有被封,如果被封了,本质和Google也就一样了。只有先访问到它,才有了后面所有的可能。
3.架构设计
1 | Client |
架构如上。
节点有很多种类型,比如Shadowsocks、VMess、VLess、Trojan等,因为我正在用的代理节点就是Trojan类型,所以我还是选了Trojan类型,至于sing-box,则是一个代理工具,可以运行节点进程,来提供代理/转发服务。
可以看到,在sing-box前还套了一层nginx,因为这个VPS主要是解决其他需求的,搭建个节点只是额外的小需求,如果只是跑节点,也可以不套nginx。
4.流程
因为买的VPS是裸机器,只有一个系统,我用的体积相对较小的Debian的Linux系统,流程大致如下:
- 安装sing-box
- 配置sing-box
- 增加域名A记录解析
- 安装证书
- 安装nginx
- 配置nginx
- 配置客户端
4.1 安装sing-box
安装命令如下,官方提供的:
1 | curl -fsSL https://sing-box.app/install.sh | sh |
交给systemd管理:
1 | sudo systemctl daemon-reload |
一般安装后,它会自动在/etc/systemd/system下自动创建service文件,如果执行命令时报错找不到sing-box服务,可以在/lib/systemd/system自己创建sing-box.service文件,内容如下:
1 | [Unit] |
4.2 配置sing-box
sing-box的配置文件在/etc/sing-box/config.json,如果没有则手动创建,配置模版如下:
1 | { |
这个配置表明,sing-box只在本机的8443端口提供服务。这里面有2部分需要修改,分别是密码和域名/证书:
- password:这是客户端配置节点时密码,可通过
openssl rand -base64 24随机生成一个,也可以通过sing-box generate rand --base64 24生成 - server_name/certificate_path/key_path:这个等后面再说,先这样
校验sing-box配置是否正确可通过这个官方提供的命令,现在第二部分的配置还没准备好,执行这个check会报错,是正常的:
1 | sudo sing-box check -c /etc/sing-box/config.json |
4.3 增加域名A记录解析
这一步来配置上一步缺少的域名/证书部分。前提是需要拥有一个域名,那样这步就很容易了,只需要打开管理域名的网站后台,在DNS解析里添加一条A记录即可,子域名可以随便起名字,但是最好不要起trojan之类的,过于明显了,可能会增加被封锁的概率,可以用个随机字符串,这里就用:abcd,作为举例。
A记录的子域名写abcd,指向的IP地址,就写VPS的IPv4地址,如果在用CloudFlare管理域名,记得要关闭橙色云,这里不需要代理,只需要DNS解析功能,然后保存即可。
大概几分钟之后,应该就可以正常解析了,可以通过下面命令验证,只要正确返回VPS的IP就表示可以了:
1 | dig abcd.domain.com |
4.4 安装证书
市面上大多的证书都需要付费,提供免费证书的不多,我选的是Let’s Encrypt,这也是多数人的选择,在Debian上通过certbot工具即可完成,同时还可以帮我们自动刷新,因为这个免费的证书有效期只有3个月。
1 | sudo apt update |
在这一步完成之后,上门所缺少的证书文件就会自动生成:
1 | /etc/letsencrypt/live/abcd.domain.com/fullchain.pem |
把域名和这两个补充到sing-box的配置文件中,至此,sing-box就算配置完成
4.5 安装nginx
这步很简单,直接命令安装:
1 | sudo apt install -y nginx |
4.6 配置nginx
nginx有两层常见能力,一个是HTTP层,常用来处理浏览器请求,另一个是TCP/UDP层,常用来做转发,所以这里要用steam层来监听443端口
新建/etc/nginx/streams-enabled/trojan.conf文件,如果没有streams-enabled目录,则手动创建,因为这个不是默认自带的:
1 | stream { |
在 /etc/nginx/nginx.conf 顶层确认有包含,注意是顶层,和其他include写在一起即可:
1 | include /etc/nginx/streams-enabled/*.conf; |
编辑完成之后,检查是否正确:
1 | sudo nginx -t |
这个时候可能会报错,找不到stream,我在操作时就报错,因为stream没有默认安装,需要手动安装:
1 | sudo apt install -y libnginx-mod-stream |
当模块文件和配置文件都存在时,再执行 nginx -t 就应该不会再报错了。
4.7 配置客户端
我在本地使用的代理客户端是ClashX Meta,早期用的ClashX Pro由于这样那样的原因已经不用了,早前写过一篇文章,说的是如何在ClashX Pro上优雅管理多个订阅,虽然客户端换了,但配置依然能用,地址如下:
所以,这一步对我来说,只是添加一个本地file类型的proxy-provider,我是直接复制其他代理的配置文件的,然后替换了其中的节点信息,然后再加到proxy里,最后就可以正常使用了:
1 | mixed-port: 7890 |
如上,如果需要的话,仅需替换节点信息中的server和sni为自己的域名,密码复制上面配置sing-box时生成的密码即可。
5.常见问题
5.1 当和tailscale并存时
我在VPS上装了tailscale,为的是有些服务我只希望通过虚拟内网来访问,而不是公开访问,而tailscale也在监听443端口,这个时候执行nginx -t就会报错,它会说443端口已经被占用。不过这种很好解决,监听不同的IP即可。
tailscale监听的443端口的请求,都是要访问它100开头的内网IP,而nginx监听443端口的请求,都是访问的是VPS的IP,tailscale那边不用管,它自己已经配好了,只需要收窄一下nginx监听的请求范围即可。
原本是这么写的:
1 | server { |
改成这样即可,其中的aa.bb.cc.dd就是VPS的公网IPv4地址:
1 | server { |
5.2 查询端口占用
1 |
|
输出的内容格式大概是这个样子:
1 | State Recv-Q Send-Q Local Address:Port Peer Address:Port Process |
- State:表示状态,因为加了-l参数,所以这列都是LISTEN监听中
- Rece-Q:接收队列,0表示没有积压的请求
- Send-Q:发送队列,后面的数字表示监听队列的上限
- Local Address/Port:监听的地址和接口,这里可以看到nginx只监听发给111.11.11.11:443的请求
- Peer Address/Port:对端的地址和端口,也就是发请求的一方,都是0表示接受任意来源的连接
- Process:占用端口的进程信息
6. 追加:vless-reality
一台VPS机器是可以多个不同类型节点的,不同类型节点本质就是处理数据的方式有所区别,宏观来看,都是在接收数据、发送数据。
6.1 增加节点配置
上面配置的是trojan类型节点,但据说reality类型伪装更好,这里也来配置一下。需要先准备以下参数:
1 | # 1. 生成一个用户 UUID |
记下输出的结果:
- UUID
- PrivateKey(填入服务端配置)
- PublicKey(客户端连接时使用)
- ShortId(两端都会用到)
sing-box配置文件中,inbounds是个数组,增加一个对象即可,上面trojan监听的是8443端口,这里监听9443端口:
1 | "inbounds": [ |
6.2 修改nginx配置
有了节点,下一步就需要修改nginx配置,把流量转发到服务所在的9443端口。上面提到,nginx是根据请求SNI进行分流的,但是呢,reality的特点是,SNI写的是其他大厂的,比如上面这份配置,用的就是Cloudflare,所以,nginx拿到的SNI就是发 www.cloudflare.com,nginx要做的就是将这类流量转发到9443端口:
1 | stream { |
这么配置后,真实来自 www.cloudflare.com 的流量也会被转发至9443端口造成误伤,但细想一下,一般情况下,Cloudflare不会给我发请求。
6.3 客户端配置
sing-box客户端的格式:
1 | "outbounds": [ |
客户端和服务器的tls.server_name必须相同,不一定是Cloudflare,也可以是其他大厂的,比如: www.misrosoft.com,等等,基本都支持TLS 1.3。
6.4 伪装流程
客户端访问时,数据包的目标IP是VPS的IP,但是SNI是Cloudflare,包体中带有其他配置信息:uuid、short_id、public_key等。数据包经过防火墙时,只能嗅探到目标IP和SNI,以为是发往Cloudflare的数据包。数据包到达VPS的9443端口后,客户端加密过的数据,服务器解密,验明正身后,按需发起请求,拿到响应后,加密返回给客户端。
防火墙如果怀疑,尝试发送探针包,目标IP为VPS IP,SNI是Cloudflare,VPS收到探针包之后,发现无法正常解密后,判定不是来自客户端,于是按照reality.handshake的配置,对 www.cloudflare.com 发请求,然后将响应返回,防火墙拿到响应后,会认为这个VPS是Cloudflare的CDN边缘节点或者是反向代理,达到伪装目的。