V2Ray服务端搭建记录

背景

(2022年)8月17日下午,原本正常使用的V2Ray服务突然遭遇频繁的TCP阻断,网络访问断断续续,大有服务器要跪的样子。无奈这是基础服务,只能放下手头正在开展的工作,转来优先处理这个问题🤬。

我当前ISP是联通,远程服务器配置是Nginx+tls+websocket+V2Ray。上次服务器配置更新是在2年半前,期间也有配置需要调整,但服务运行正常,我懒得没动。

为处理这个问题,我做了以下前置动作:

最终确定下来,我要趁这个机会做如下调整:

  1. 放弃原本的CentOS,改系统为Debian。CentOS停止支持,换上Debian图个安稳。
  2. 更换原有域名。原有域名只有这一个作用,释放后停止续费节省票子。
  3. 给V2Ray的新域名套上cloudflare。之前一直不想更换nameserver,也不想处理CDN的https证书,所以没套CDN。这次套CDN也不一定能用,但至少应该会保住IP。 在保住IP的前提下,剩下的慢慢解决。
  4. 记录此次配置过程。就因为我一直没写文档,所以在这么长的时间里我没有调整过配置。为此我多花了域名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

额外补充几点,省得我日后还要重读文档:

  1. 我丝毫不关心官方文档中说的Unstable 仓库到底是什么,官方配置步骤中的1、2、3被直接跳过;
  2. 这样直接安装的v2ray版本是4.34.0,写在这里日后配置v2ray时方便确认该版本是否支持新功能;
  3. 官方配置文档中使用systemctl edit v2ray.service特别指定日志目录不是必需的,你不一定需要开启v2ray日志;我开启了日志,所以也执行了官方此步骤的推荐配置;
  4. systemctl edit v2ray.service命令相当于执行vi /usr/lib/systemd/system/v2ray.service后再执行systemctl daemon-reload,它们是等效的。
  5. 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前我还查了一些资料,放出来以防有人需要:

至此,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

连通不稳定的情况再次发生,但没比我重新配置前严重。是时候尝试寻找其他方案了。

查看过的其他文档:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注