第一台 VPS 折腾小记

5288 字
26 分钟
第一台 VPS 折腾小记

人生的意义在于折腾。

宇宙级安全声明#

在使用本项目/教程/脚本之前,请务必仔细阅读以下声明。一旦您开始使用、复制或修改相关内容,即视为您已完全接受并同意本免责声明的所有条款。

  1. 用途说明
    • 本项目涉及的所有脚本、代码、配置文件及教程仅供 资源共享、技术研究和学术交流 使用。
    • 本文作者对其中包含的信息的合法性、准确性、完整性和有效性 不作任何保证。用户应根据自身情况自行判断并承担相应风险。
  2. 免责条款
    • 任何用户(包括但不限于个人、组织或自动化程序)间接使用本项目代码(包括但不限于建立 VPS、服务器配置或网络代理服务),或在违反其所在国家/地区法律法规的情况下进行传播和使用,本文作者对于由此引起的任何隐私泄漏、数据丢失、设备损坏或其他任何形式的后果概不负责。
    • 作者不对任何脚本在使用过程中可能出现的问题负责,包括但不限于由脚本错误、逻辑漏洞或兼容性问题导致的任何直接或间接损失。
  3. 禁止行为
    • 严禁 将本项目内的任何内容用于 商业用途 或 非法目的。
    • 不得利用本项目进行任何形式的网络攻击、非法入侵、绕过监管或其他违反当地法律法规的行为。
    • 若用户利用本项目从事任何违法行为,一切法律后果由用户 自行承担,与本文作者无关。
  4. 知识产权与侵权处理
    • 本项目均来自网络收集或个人学习总结。如果任何单位或个人认为该项目的脚本或内容可能涉嫌侵犯其合法权益,请及时通知并提供有效的身份证明、所有权证明及侵权情况说明。
    • 作者在收到上述法律文件并核实后,将会在第一时间删除相关内容。
  5. 条款变更
    • 本文作者保留在不预先通知的情况下,随时更改、补充或解释本免责声明的权利。
    • 请用户定期查看本声明,以确保了解最新的条款内容。

请谨记:使用技术时请务必遵守您所在国家和地区的法律法规。

0. 参考#

使用 IPv6-only VPS 低成本独享家宽,解锁 ChatGPT 不风控

年轻人的第一台 VPS 代理服务器

1. VPS 选择#

这里不做推荐,我用的是 ipv6-only,一年 15 刀乐,折算一下的话一个月 9 块(加上域名也没多贵),在家宽里算很便宜了,而且可以通过 warp 获得 ipv4 地址,所以问题不是很大。这里先贴一张节点质量:

可以看到,非常纯净,一些服务有屏蔽是因为网站不支持纯 v6 访问,问题不大。

2. VPS 搭建#

2.1 连接并安装基础工具#

Terminal window
ssh user@hostname

连接成功后,安装:

Terminal window
sudo apt update && sudo apt-get install -y curl vim ufw

安装 Docker:

Terminal window
sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release -y
# 创建 keyrings 目录
sudo mkdir -p /etc/apt/keyrings
# 下载并添加 GPG 密钥
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 添加 Docker 仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

2.2 安全性防护#

虽然 vps 厂商本身就提供了一定的安全保障措施,不过防人(爆破)之心的不可无。

2.2.1 创建用户组和用户#

将以下命令中的 username 和 passwd 自行替换即可:

Terminal window
getent group 1001 || groupadd -g 1001 vps \
&& getent passwd username || useradd -ms /bin/bash -u 1001 -g 1001 -G sudo username \
&& echo "username:passwd" | chpasswd

创建用户组,创建用户并拉入附加组 sudo,并设置密码。

2.2.2 修改 ssh 端口#

Terminal window
sudo nano /etc/ssh/sshd_config

找到被注释掉的 Port 22 并修改为:

Terminal window
Port 11451

记住这里你修改的端口号,如果你启动了防火墙需要进行对应的放行:

Terminal window
sudo ufw allow
ssh sudo ufw enable
sudo ufw allow 11451

请务必在确认端口放行后再重启 ssh 服务:

Terminal window
sudo systemctl restart ssh
sudo ufw deny 22

2.2.3 禁用 root 用户远程登录#

sudo nano /etc/ssh/sshd_config

找到 PermitRootLogin 并修改为 no。

2.2.4 RSA 密钥登录验证#

略。

2.2.5 Fail2ban 工具#

Fail2ban 工具用于对于密码连续输错三次封 IP:

Terminal window
sudo apt install -y fail2ban
sudo nano /etc/fail2ban/jail.local

输入以下内容:

[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 3
[sshd]
enabled = true
port = 11451
filter = sshd
logpath = /var/log/auth.log
backend = systemd

保存并重启 fail2ban:

Terminal window
sudo systemctl restart fail2ban
sudo systemctl enable fail2ban

2.3 通过 Warp 获取 ipv4 地址#

如果你和我一样是 v6-only 的 vps,那么可以通过套一层的 warp 来获得 ipv4 地址,这样后续在使用代理服务时,也能正常访问 github.com 等不支持 v6 的网站(虽然速度比较慢)。

Terminal window
wget -N https://gitlab.com/fscarmen/warp/-/raw/main/menu.sh && bash menu.sh

如果分配不到 ipv4 地址,可以修改 DNS 为:

Terminal window
sudo nano /etc/resolv.conf
nameserver 2606:4700:4700::1111
nameserver 2001:4860:4860::8888
nameserver 2001:4860:4860::8844
nameserver 1.1.1.1
nameserver 8.8.8.8
nameserver 8.8.4.4

你可以通过 Cloudflare 的测试端点再次查看给你分配的地址:

Terminal window
curl -4 https://www.cloudflare.com/cdn-cgi/trace

3. 域名配置#

3.1 域名购买#

略。

3.2 域名托管#

将域名从你的购买处托管到 Cloudflare,具体步骤略,在 Cloudflare 控制面板添加你的域名时已经提供了相当详细的步骤。

3.3 申请 TLS 证书#

这里使用 acme.sh 开源工具,用来自动获取和管理 SSL/TLS 证书,自动续签,非常方便。

3.3.1 创建令牌#

该工具使用 Cloudflare DNS 验证的模式申请泛域名证书,因此需要:

  1. Zone ID
  2. Account ID
  3. API Token

前两个分别在“域->Overview”右下角即可找到,令牌进入 API令牌 获取,选择 编辑区域 DNS 模版:

选择对应域名,以及选择自己 VPS 的 IP 地址作为白名单(有 v4 和 v6 的话都写上):

继续,注意保存生成的 Token。

3.3.2 安装脚本#

Terminal window
su
# 脚本需要的定时服务
sudo apt update
sudo apt install -y cron
sudo systemctl enable cron
sudo systemctl start cron
sudo apt install socat -y
# 安装脚本并设置邮箱
curl https://get.acme.sh | sh -s email=your@email.com
# 将 CA 服务器改成 Let’s Encrypt
~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
source ~/.bashrc
# 开启自动更新
acme.sh --upgrade --auto-upgrad

其中,email=xxxx 用来设置向证书颁发机构注册时使用的邮箱,请填写为你实际使用的邮箱,用来接受 Let’s Encrypt 的邮件通知。

3.3.3 配置环境变量#

Terminal window
vim ~/.bashrc
export CF_Token="<Your API Token>"
export CF_Account_ID="<Your Account ID>"
export CF_Zone_ID="<Your Zone ID>"
source ~/.bashrc

3.3.4 签发证书#

Terminal window
acme.sh --issue --dns dns_cf -d yourdomain.com -d *.yourdomain.com

-d 之后接上你需要签发的域名。如果成功,会在最后输出证书的位置。具体包括:

  • yourdomain.com.cer:只有域名的叶子证书。
  • ca.cer:中间证书,用来构建完整的信任链。
  • fullchain.cer:由域名证书与中间证书组合而成的完整证书链文件,配置服务器时常用此文件以确保客户端能正确验证证书链。

通过以下命令,可以验证自动签发是否正确工作:

Terminal window
$ crontab -l
2 13 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

例如,2 13 * * * 表示每天的 13<02> 执行一次。或者通过以下命令手动签发:

Terminal window
acme.sh --cron --home /root/.acme.sh

3.3.5 使用证书#

通常,采用 fullchain.cer 作为网站证书的配置。密钥只有一个,例如 yourdomain.com.key,对应域名证书的私钥,直接输入就行。

如需让 root 外用户能访问证书,还需要:

mkdir -p /home/username/cert
cp /root/.acme.sh/yourdomain.com_ecc/yourdomain.com.key /home/username/cert/yourdomain.com.key
cp /root/.acme.sh/yourdomain.com_ecc/fullchain.cer /home/username/cert/fullchain.cer
sudo chmod 644 /home/username/cert/yourdomain.com.key
sudo chmod 644 /home/username/cert/fullchain.cer
Warning

注意:如果你在后面搭建节点或其他服务时,采用了 Docker 部署,容器是看不到宿主机的文件系统的,还需要移动到正确的映射路径。

4. 节点搭建#

4.1 Hysteria#

参考:https://v2.hysteria.network/zh/docs/getting-started/Installation

Hysteria2 基于 UDP,在网络环境较差时表现优异。

4.1.1 安装并运行官方脚本#

Terminal window
su
bash <(curl -fsSL https://get.hy2.sh/)

观察到输出 Congratulation! Hysteria 2 has been successfully installed on your server. 则证明安装成功。

如果提示 useradd: command not found,说明环境变量缺失。请先执行 export PATH=$PATH:/usr/sbin 后再次运行安装命令。

4.1.2 创建配置文件#

我们需要手动创建配置文件。这里,我已经将证书文件移动到 /home/username/cert/fullchain.cer 和 /home/username/cert/private.key。

Terminal window
vi /etc/hysteria/config.yaml

粘贴并修改以下内容:

listen: :8443 # 监听端口,需防火墙放行
# 使用之前申请的 CA 证书
tls:
cert: /home/username/cert/fullchain.cer
key: /home/username/cert/yourdomain.com.key
auth:
type: userpass
userpass:
# 修改这里:自定义用户名和密码
myuser1: password123
myuser2: password456
masquerade:
type: proxy
proxy:
url: https://bing.com # 伪装网址
rewriteHost: true
listenHTTP: :80
listenHTTPS: :8443
trafficStats: # 流量统计接口
listen: :22222
secret: trafficStats_passwd
bandwidth:
# 修改这里:根据你VPS的实际带宽调整,不要填满,留有余地
up: 100 mbps
down: 200 mbps

保存并退出,同时在 Cloudflare 控制面板添加对应的 A/AAAA 记录,指向你的服务器 IP,不要开启代理(云朵)。

Terminal window
systemctl enable hysteria-server.service --now
systemctl status hysteria-server.service

启动并验证状态,如果观察到 active (running) 则证明配置并运行成功,否则请自行参照 Hysteria 官网检查。

注意如果有 ufw 还需要放行对应端口:

Terminal window
sudo ufw allow 8443

如有问题,可通过以下命令观察调试信息:

Terminal window
# 启动 Hysteria2
systemctl start hysteria-server.service
# 重启 Hysteria2
systemctl restart hysteria-server.service
# 查看 Hysteria2状态
systemctl status hysteria-server.service
# 停止 Hysteria2
systemctl stop hysteria-server.service
# 设置开机自启
systemctl enable hysteria-server.service
# 查看日志
journalctl -u hysteria-server.service

4.1.3 配置端口跳跃#

Hysteria 是基于 UDP 的,为了防止运营商针对单一 UDP 端口的阻断,我们需要利用 iptables 做端口转发。这意味着客户端连接 50000-50100 端口时,VPS 会自动转给 8443 处理。

  1. 确认网卡名称:输入 ip addr 查看,通常是 eth0,但也可能是 ens3 等。将下令中的 eth0 替换为你的真实网卡名。
  2. 执行转发规则:
Terminal window
# 放行对应端口
sudo ufw allow 50220:50959/udp
sudo ufw allow 60133:60968/udp
# 允许 UDP 端口段
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 50220:50959 -j REDIRECT --to-ports 8443
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 60133:60968 -j REDIRECT --to-ports 8443
# 对应的 IPv6 规则 (如果不需要 IPv6 可跳过)
ip6tables -t nat -A PREROUTING -i eth0 -p udp --dport 50220:50959 -j REDIRECT --to-ports 8443

4.1.4 代理软件使用配置#

这里以 V2RayN 为例,其他软件类似,只要核心支持 Hysteria2 协议即可。点击”Configuration”->“Add[Hysteria2]“,配置如下,请修改为你自己的实际值:

如果能连通,说明上述配置成功。

4.1.5 配置流量统计服务#

这里我偷懒了,建议在配置完 Nginx 之后在进行这一步骤。

安装一些所需依赖:

Terminal window
sudo apt update apt install jq bc -y

创建查询脚本:

Terminal window
vim /root/check_traffic.sh

写入并修改以下内容,域名和 API 地址也可以根据需要自行修改:

#!/bin/bash
green='\033[0;32m'
cyan='\033[0;36m'
NC='\033[0m' # No Color
# 请修改这里:你的域名
DOMAIN="sub.yourdomain.com"
# 请修改这里:你的 config.yaml 里设置的 secret
SECRET="passwd"
# API 地址 (走 HTTPS)
TRAFFIC_URL="https://${DOMAIN}/hy-stats/traffic"
ONLINE_URL="https://${DOMAIN}/hy-stats/online"
AUTH_HEADER="Authorization: ${SECRET}"
# 函数:将字节转换为可读格式
bytes_to_readable() {
local bytes=$1
if (( bytes < 1024 )); then
printf "%d B" "$bytes"
elif (( bytes < 1024**2 )); then
printf "%.2f KB" "$(echo "scale=2; $bytes / 1024" | bc)"
elif (( bytes < 1024**3 )); then
printf "%.2f MB" "$(echo "scale=2; $bytes / (1024^2)" | bc)"
else
printf "%.2f GB" "$(echo "scale=2; $bytes / (1024^3)" | bc)"
fi
}
echo -e "${green}=== Hysteria2 流量与在线用户统计 ===${NC}"
echo
# 1. 获取在线用户数
echo -n "正在获取在线用户..."
online_resp=$(curl -s -H "$AUTH_HEADER" "$ONLINE_URL")
# 简单的整数判断,如果返回不是数字可能是认证失败
if [[ "$online_resp" =~ ^[0-9]+$ ]]; then
echo -e "\r当前在线用户数: ${cyan}${online_resp}${NC}"
else
echo -e "\r${cyan}获取在线用户失败 (可能是密钥错误或 Nginx 配置问题)${NC}"
# echo "Debug: $online_resp" # 调试用
fi
echo "-----------------------------------"
# 2. 获取流量统计
response=$(curl -s -w "HTTPSTATUS:%{http_code}" -H "$AUTH_HEADER" "$TRAFFIC_URL")
body=$(echo "$response" | sed -e 's/HTTPSTATUS\:.*//g')
status_code=$(echo "$response" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
if [ "$status_code" -eq 200 ]; then
# 使用 jq 解析 JSON
# 格式: 用户名 上传 下载
echo "$body" | jq -r 'to_entries[] | "\(.key) \(.value.tx) \(.value.rx)"' | while read -r key tx rx; do
readable_tx=$(bytes_to_readable "$tx")
readable_rx=$(bytes_to_readable "$rx")
echo -e "用户 ${green}$key${NC}: 上传 ${cyan}${readable_tx}${NC} | 下载 ${cyan}${readable_rx}${NC}"
done
else
echo "流量请求失败,状态码:$status_code"
echo "请检查密钥或 HTTPS 连接。"
fi
echo

4.2 Xray#

4.2.1 安装面板#

可以选择 x-ui 或者一个大佬魔改的 x-panel,没区别,x-panel 加了一些付费的一键配置等功能,对新手可能更友好吧。

如果安装 x-panel:

Terminal window
vim docker-compose.yml

将以下内容添加进去:

services:
x-panel:
image: xeefei/x-panel:latest
container_name: x-panel
restart: unless-stopped
network_mode: host
volumes:
- ./db/:/etc/x-ui/
- ./cert:/root/cert/
environment:
XRAY_VMESS_AEAD_FORCED: "false"
XUI_ENABLE_FAIL2BAN: "true"

启动容器:

Terminal window
sudo docker compose up -d

本地建立连接:

Terminal window
ssh -L 13688:127.0.0.1:13688 user@host

然后在本机访问 127.0.0.1<13688> 进行配置即可,默认用户名和密码均为 admin,登录后记得修改并重启面板。

如果你不想用 x-panel 或者不想用 docker 部署,可以参考大佬的这篇文章中的步骤 年轻人的第一台 VPS 代理服务器,思路都是大差不差的。

4.2.2 面板设置#

点击面板设置中,找到 面板证书公钥文件路径 和 面板证书密钥文件路径,分别填入 /root/cert/fullchain.cer 和 /root/cert/yourdomain.com.key,注意这里跟前面的容器设置有关,如果按照我的设置,宿主机目录 ./cert,即 home/username/cert 被映射到容器目录 root/cert,可通过以下命令验证:

Terminal window
sudo docker exec -it x-panel ls /root/cert

设置完成后,你就可以通过 ip:port (如果是 ipv6 地址请用 [] 括起来)的方式访问面板了,不过浏览器会提示不安全,如下图:

这是因为证书中认证的域名并不符合 ip,请在 Cloudflare 控制面板再次添加对应的 A/AAAA 记录,指向你的服务器 IP,不要开启代理(云朵),若名为 xui,则在之后 Nginx 也配置完成后,你可以通过 xui.yourdomain.com 访问面板。

4.2.3 搭建节点#

这里提供目前 Xray-core 中比较顶尖和主流的抗干扰配置,VLESS + Vision + TLS 和 VLESS + Reality + xhttp,简单来说:

对于前者,Vision 专门用于解决“TLS in TLS”特征和流量指纹问题。它能极其逼真地模拟正常的 HTTPS 网页浏览流量,让防火墙认为你正在访问一个正常的加密网站,不过由于基于 TLS,因此必须拥有一个真实的域名和 SSL 证书。

对于后者,Reality 协议会通过中间人攻击的方式,偷取别的网站(如 Apple, Microsoft, Amazon 等)的 TLS 握手特征。因此不需要域名和证书。同时,xhttp 在 packet 层面做了更精细的 Padding 和头部处理,使得流量特征更像现代浏览器访问网站的行为,配合 Reality 使用效果极佳。

这里给出 Gemini 总结的两者的区别(我也不是特别懂):

特性VLESS + Vision + TLSVLESS + Reality + xhttp
域名 (Domain)必须拥有 (每年需付费或申请免费)不需要 (直接使用 IP)
证书 (Cert)需要管理 (需申请并续期,如 acme.sh)不需要 (模拟目标网站 SNI)
CDN 支持支持 (但在 Vision 下不建议开启 CDN)不支持 (绝对无法套 CDN)
抗封锁能力极高 (只要域名干净,IP 正常)极高 (专门针对主动探测优化)
配置难度中等 (需解析域名、配置 Nginx/回落)简单 (填入 IP 和目标 SNI 即可)
端口要求通常占用 443 端口任意端口 (但推荐 443 以模拟真实)
适用场景长期稳定使用,不怕麻烦,有建站需求快速部署,不想买域名,IP 经常变动

这里因为我有域名,所以选择更稳定的“VLESS + Vision + TLS”,入站规则的创建我就省略了,基本都按照默认,记得在 SNI (域名) 处填写你的自己的三级域名,同时在证书设置部分填写之前准备好的证书路径,flow 记得选择 xtls-rprx-vision。

然后放行对应的端口。同理,在 Cloudflare 控制面板添加对应的 A/AAAA 记录,指向你的服务器 IP,不要开启代理(云朵),名字和你入站规则中的域名一致。

搞完之后可以在 V2rayN 中先测一下,没问题的话再继续。

5. 订阅服务搭建#

这里暂时先不折腾了。

Warning

由于 VPS 大部分是小内存机器(例如 512MB 或 1GB),且此时已经运行了 Hysteria、Nginx 等服务,在进行 Sub-Store 的安装和配置时极有可能导致内存溢出,进程被强行杀死,如果遇到这种情况,可以尝试从硬盘上划分一部分空间当作“虚拟内存”来使用,防止内存不足导致程序崩溃:

Terminal window
# 创建一个 1GB 的文件用于 swap
dd if=/dev/zero of=/swapfile bs=1M count=1024
# 设置权限,确保安全
chmod 600 /swapfile
# 将其标记为 swap 空间
mkswap /swapfile
# 启用 swap
swapon /swapfile
# (可选) 写入系统配置,确保重启后依然有效
echo '/swapfile none swap sw 0 0' | tee -a /etc/fstab
# 查看是否生效
free -h

如果配置正确,应该能看到 Swap: 这一行有了 1.0Gi 左右的空间。

5.1 安装基础组件与 FNM#

Terminal window
# 更新并安装 unzip 等工具
sudo apt update -y && sudo apt install unzip curl wget git -y
# 安装 FNM
curl -fsSL https://fnm.vercel.app/install | bash
# 让 FNM 生效
source /root/.bashrc

5.2 安装 Node.js v20.18.0#

Terminal window
fnm install v20.18.0

5.3 安装 PNPM#

Terminal window
curl -fsSL https://get.pnpm.io/install.sh | sh -
# 同样让它生效
source /root/.bashrc

5.4 安装 Sub-Store#

Terminal window
mkdir -p /root/sub-store
cd /root/sub-store
# 下载后端
curl -fsSL https://github.com/sub-store-org/Sub-Store/releases/latest/download/sub-store.bundle.js -o sub-store.bundle.js
# 下载前端并解压
curl -fsSL https://github.com/sub-store-org/Sub-Store-Front-End/releases/latest/download/dist.zip -o dist.zip
unzip dist.zip && mv dist frontend && rm dist.zip

5.5 配置 Sub-Store 系统服务#

5.5.1 配置密钥#

随便生成一个密钥并记下:

Terminal window
openssl rand -hex 16

5.5.2 创建服务文件#

Terminal window
vim /etc/systemd/system/sub-store.service

写入并修改以下内容:

[Unit]
Description=Sub-Store
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
[Service]
LimitNOFILE=32767
Type=simple
# 修改这里:这一串随机字符就是你以后访问 Sub-Store 的路径
Environment="SUB_STORE_FRONTEND_BACKEND_PATH=/你的随机密钥"
Environment="SUB_STORE_BACKEND_SYNC_CRON=0 0 * * *"
Environment="SUB_STORE_FRONTEND_PATH=/root/sub-store/frontend"
Environment="SUB_STORE_FRONTEND_HOST=0.0.0.0"
# 前端运行在 3001 端口
Environment="SUB_STORE_FRONTEND_PORT=3001"
Environment="SUB_STORE_DATA_BASE_PATH=/root/sub-store"
Environment="SUB_STORE_BACKEND_API_HOST=127.0.0.1"
Environment="SUB_STORE_BACKEND_API_PORT=3000"
# 启动命令 (确保路径正确)
ExecStart=/root/.local/share/fnm/fnm exec --using v20.18.0 node /root/sub-store/sub-store.bundle.js
User=root
Group=root
Restart=on-failure
RestartSec=5s
ExecStartPre=/bin/sh -c ulimit -n 51200
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target

5.5.3 启动服务#

Terminal window
systemctl daemon-reload
systemctl enable sub-store.service --now

如出现错误请使用以下命令打印调试信息自行调试:

Terminal window
systemctl start sub-store.service # 启动服务
systemctl enable sub-store.service # 设置为开机自启
systemctl status sub-store.service # 查看服务状态
systemctl stop sub-store.service # 停止服务
systemctl restart sub-store.service # 重启服务

6. Nginx 配置#

由于上述服务暴露在公网,因此暴露端口有一定的安全隐患,采用 Nginx 进行反代,将 443 加密流量在 Nginx 内部分流到不同的本地端口,本地端口不需要暴露。

6.1 安装#

Terminal window
sudo apt update
sudo apt install nginx libnginx-mod-stream -y

6.2 配置 Stream 分流#

Terminal window
vim /etc/nginx/nginx.conf

在 http 块外部添加我们即将要引入的分流规则:

include /etc/nginx/vps.conf;

配置 Stream 分流 (vps.conf):

Terminal window
vim /etc/nginx/vps.conf

填入以下内容(注意修改域名和端口为你实际需要使用的):

stream {
# 1. 域名识别区 (SNI Map)
map $ssl_preread_server_name $backend {
hostnames;
# 修改这里:你的 Sub-Store 域名 -> 转发给 sub 后端
sub.yourdomain.com sub;
# 修改这里:你的 X-UI 面板域名 -> 转发给 xui 后端
xui.yourdomain.com xui;
# 默认情况(比如直接访问 IP 或 hy2 域名) -> 转发给 hysteria
default hysteria;
}
# 2. 后端定义区 (Upstreams)
# Sub-Store 后端:转发给 Nginx 自己的 8444 端口 (处理 SSL 后再给 Sub-Store)
upstream sub {
server 127.0.0.1:8444;
}
# X-UI 面板后端:直接转发给 X-UI 面板端口
upstream xui {
server 127.0.0.1:13688;
}
# Hysteria 后端:转发给 Hysteria 的 HTTP 伪装端口
upstream hysteria {
server 127.0.0.1:8443;
}
# 3. 监听服务区
server {
listen 443 reuseport;
listen [::]:443 reuseport;
proxy_pass $backend;
ssl_preread on; # 开启 SNI 预读,否则无法识别域名
}
}

6.3 配置 Sub-Store 反代#

Stream 模块只是把流量扔过来了,对于 Sub-Store,我们还需要 Nginx 帮忙处理 HTTPS 加密(卸载证书),然后以 HTTP 协议传给 Sub-Store 程序(默认运行在 3001 端口)。

Terminal window
vim /etc/nginx/sites-enabled/vps.conf

写入并修改以下内容:

Terminal window
server {
# 监听 8444,接收来自 Stream 模块分流过来的 sub 流量
listen 8444 ssl http2;
listen [::]:8444 ssl http2;
# 修改这里:你的 Sub-Store 域名
server_name sub.yourdomain.com;
# 修改这里:你的证书绝对路径
ssl_certificate /home/username/fullchain.cer;
ssl_certificate_key /home/username/private.key;
location / {
# 转发给 Sub-Store 默认端口 3001
proxy_pass http://127.0.0.1:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# Hysteria 流量统计反代,访问 https://sub.yokumi.cn/hy-stats/traffic 就会被转到 http://127.0.0.1:22222/traffic
location /hy-stats/ {
proxy_pass http://127.0.0.1:22222/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

6.4 启动服务#

先删除默认配置(防止占用端口或冲突):

Terminal window
rm /etc/nginx/sites-enabled/default

在启动前测试一下配置是否有误:

Terminal window
$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

启动服务:

Terminal window
sudo systemctl restart nginx
sudo nginx -s reload
sudo systemctl status nginx

TODO#

目前的所有配置之后基本已经能正常使用了,至于问题等后续慢慢发现吧,前前后后加起来花了差不多一天,还是比较折腾的。

  • PT/BT 配置;
  • 整台🇭🇰双栈中转机搞链式代理(等有米了);
  • 后续迁移考虑整成一键脚本;

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

第一台 VPS 折腾小记
https://blog.yokumi.cn/posts/my-first-vps-setup-journey/
作者
Yokumi
发布于
2025-11-30
许可协议
CC BY-NC-SA 4.0
相关文章智能推荐
1
2026.5 Live Repo
生活杂谈翻了翻相册才发现上一次已经是去年 9 月的羊文学了,哎gszm坏事做尽。 这回的出行方式是经典京沪高铁二等座,去年锅贴得意之作绿皮 D9 真给我坐麻了,这次果断 G 系列。不过被课表背刺,本来还可以买早一班(),结果就是快 0 点才到虹桥。好像是第一次这么晚到沪国。
2
在 Linux 下编译安装 Dynamips 和 Dynagen 搭建 Cisco 实验环境
开发心得最终还是花了一点时间把计网实践的实验平台搞到 Linux 下实现了,相比于 Windows,同样配置的路由器,Linux 下 CPU 占用可降低 50% 以上,应该也会更加稳定吧。 本文将详细介绍如何在 Linux (Ubuntu/Debian) 系统下(macOS 等也是类似的,一些依赖的安装略有不同罢了)从源码编…
3
Python 套件管理器 uv 使用介绍
开发心得Python 生态得益于大数据时代和大模型时代蓬勃发展,相应的包管理工具也不断涌现,这篇文章简单记录一下个人上手 Astral 团队开发的 uv 的一些基操和使用一段时间后的体验。当然其实官方文档[^1]已经很详细了。 下表转载自 Shoukai Huang 大佬的博客[^2] 整理的横向对比:
4
浅谈大型项目的模块化开发(Based on Python)
开发心得最近在进行大型项目开发时,自行实现的一些公共模块,包括工具库、API 客户端等,都被扔在一个文件夹下,需要时由该项目的控制代码进行调用,不过因为水平之菜,经过测试没什么问题的代码 PR 上去之后经常会出现需要反复修改的情况。而且另一方面,这些公共模块具有一定的可移植性,但只被一个项目使用,没什么性价比,肯定是需要进一…
5
使用 Cloudflare R2 + WebP Cloud + PicGo 搭建你的图床
开发心得一开始使用了 jsDelivr 加速 Github 图床,但是实际使用中发现有时国内到 jsDelivr 的网络质量仍不稳定,或是存在 DNS 污染,并且使用 Github 作为图床容易污染 commit 记录。于是打算放弃这种依赖纯 CDN 的方式,转向 OSS ,加上刚好有优化博客访问的需求,以及赛博活菩萨 Cl…

评论区

文章目录