跳过正文
  1. 系列/
  2. VPS 实战系列/

任务 12:VPS内核优化、Tailscale组网与前端公网穿透

其雁过无痕
作者
其雁过无痕
目录

写在前面: 在服务器“毛坯房”装修进入深水区后,单纯的防火墙配置已经无法满足复杂网络环境下的安全与效率需求。本文记录了如何完成服务器环境的高阶配置,主要包括内核网络优化(BBR)与组建虚拟局域网 。核心目标是开启 Linux 内核自带的 BBR 拥塞控制算法以提升网络吞吐量,并使用 Tailscale 将本地电脑与云服务器组建成一个加密的局域网 。

阶段一:VPS 内核网络优化 (BBR 拥塞控制算法)
#

目的: 榨干服务器的网络吞吐量,降低高延迟环境下的丢包率。

操作过程:

  1. 检查默认状态:通过 sysctl net.ipv4.tcp_congestion_control 命令,发现系统默认使用的拥塞控制算法是相对保守的 cubic

  2. 修改系统内核变量:在终端执行以下命令,将队列调度算法改为 fq,并将拥塞控制算法改为 BBR

echo "net.core.default_qdisc=fq" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" | sudo tee -a /etc/sysctl.conf
  1. 应用并验证:使用 sudo sysctl -p 使配置生效,随后通过 lsmod | grep bbr 确认内核模块已成功加载。

小结:这是提升服务器网络物理性能的基础操作,完成后肉眼可见 SSH 连接的响应变得更加顺滑。

阶段二:组建零信任虚拟局域网 (Tailscale 双端部署)
#

背景痛点:

由于在本地开发时,常处于移动蜂窝网络(手机热点)或校园网的复杂 NAT 结构之后,没有固定的公网 IP。每次连接服务器或测试内网服务,都要添加新的防火墙白名单(当然,没有防火墙就没有这个困扰,但 Tailscale 的功能远不止这些)。引入基于 WireGuard 协议的 Tailscale 可以彻底解决动态 IP 带来的困扰。

操作过程:

  1. VPS 端安装与授权:

    • 在服务器终端通过一键脚本完成安装:curl -fsSL https://tailscale.com/install.sh | sh
    • 执行 sudo tailscale up 启动服务。终端返回了一串包含授权参数的 URL。
    • 将 URL 复制到本地浏览器,使用个人谷歌账号完成登录授权,将服务器拉入专属的 Tailnet(虚拟局域网)。
  2. 本地 Windows 端部署:

    • 在本地电脑下载 Windows 版 Tailscale 客户端。
    • 关键步骤:使用与 VPS 端完全一致的谷歌账号登录。
    • 登录成功后,系统托盘出现 Tailscale 图标,本地电脑获得了一个 100.x.x.x 开头的内网 IP。

测试连通性:在本地 cmd 中直接 ping 服务器分配的 100 开头的 IP,收到稳定延迟的回复。至此,本地电脑与远端 VPS 已无视物理网络限制,宛如插在同一台路由器上。

阶段三:端口防护
#

注意:Docker 默认会绕过系统防火墙。

当在 Linux 系统里配置好 UFW 防火墙,并设置了“拒绝所有公网访问 3306 端口”,然后用 Docker 跑起了一个 MySQL 容器。这时,Docker 为了实现容器通信,会直接去修改更底层的 iptables 规则。而它的优先级高于常规的 UFW,等于在防火墙上开了一扇面向全公网的窗。

不出几个小时,全网的嗅探脚本就能顺着你的公网 IP 摸进来,开始疯狂爆破你的数据库密码。(AI说的,听起来挺可怕的,但其实在做这个防护前我已经拥有这个VPS一段时间了,我也不知道会出现什么问题)

解法:利用 Tailscale 进行网卡级绑定

既然防不住 Docker 开窗,那就从源头上掐断它连接公网的可能。当组建好 VLAN 后,再也不需要把端口映射到 0.0.0.0(允许所有网络接口访问),而是绑定在 Tailscale 分配的内网 IP 上

实操演示(以 docker-compose.yml 为例):

修改前:

services:
  mysql:
    image: mysql:8.0
    ports:
      - "3306:3306" # 默认等同于 0.0.0.0:3306,全网皆可扫描

修改后:

services:
  mysql:
    image: mysql:8.0
    ports:
      - "100.x.x.x:3306:3306" # 替换为自己 VPS 的 Tailscale IP

效果: 修改重启后(记得重启啊),这个 MySQL 容器在互联网上彻底“蒸发”了。公网的扫描器连这个端口的存在都探测不到。只有处于同一个 Tailscale 虚拟局域网(VLAN)中并获得授权的设备,才能通过 100.x.x.x:3306 畅通无阻地直连数据库。

这不仅解决了动态 IP 下无法设置固定防火墙白名单的痛点,更是现代微服务架构中零信任网络(Zero Trust)的实践。无论是跑数据库、Redis 还是内部调用的后端 API,统统用这个方法藏进内网,再也无需为弱密码爆破而焦虑。

阶段四:进阶探索 —— Funnel 公网穿透本地 Vue 项目
#

在搭建好虚拟局域网后,尝试利用 Tailscale 的 Funnel(漏斗)功能,将本地正在开发的 Vue 项目临时暴露到公网,以便在不走 CI/CD 部署流程的情况下直接向他人展示 UI 效果。

1. 穿透操作与表象成功

  • 启动本地前端服务:在 VS Code 终端运行 npm run dev,Vite 服务正常启动在 http://127.0.0.1:5173/
  • 开启公网穿透:在管理员模式的 cmd 中执行 tailscale funnel 5173
  • 终端提示 Success,并分配了一个带有 HTTPS 的专属公网域名(如:https://idyq.tailxxxx.ts.net/)。 (首次使用可能需要二次登录确认)

2. 遭遇报错(“Blocked request”)

满怀期待地用浏览器打开该公网链接,却遭遇了直接拦截,页面抛出错误:

Blocked request.

This host (“idyq.tailxxxx.ts.net”) is not allowed.

To allow this host, add “idyq.tailxxxx.ts.net” to server.allowedHosts in vite.config.js.

3. 排查与底层原理

网络隧道已打通却被拦截,问题在于 Vite 框架的 DNS 重新绑定防御机制

出于安全考虑,Vite 开发服务器默认只信任请求头(Host)中来源为 localhost127.0.0.1 的请求。当我们通过 Tailscale 分配的 ts.net 域名访问时,Host 字段不符,Vite 直接将其判定为潜在的安全风险并切断了响应。

4. 解决办法

根据报错提示,在 Vue 项目根目录下的 vite.config.js 文件中,手动配置 server 选项,将该专属公网域名加入白名单:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  server: {
    // 允许 Tailscale 分配的公网域名访问本地开发服务器
    allowedHosts: [
      'idyq.tailxxxx.ts.net'
    ]
    // 也可以简单粗暴地写成 allowedHosts: true 或 'all' 来允许所有域名访问
  }
})

保存配置文件后,Vite 自动热更新。再次刷新浏览器的公网链接,报错消失,本地 Vue 页面完美呈现在公网环境中。展示完毕后,只需在终端敲下 tailscale funnel off 即可安全闭合大门。

相关文章

任务 7:部署限制内存的数据库

在服务器部署的进阶之路上,部署限制内存的数据库是一个必经的关卡 。对于这种小内存的 VPS(比如 RackNerd),如果直接裸跑默认配置的 MySQL 8.0,它会一口气吞掉 400MB 甚至更多的内存,极易导致服务器 OOM(内存溢出)死机。

番外:1G 小内存 VPS 部署 Java JSP 项目实战:Docker 本地构建 + 远程运行完美方案

在拥有了一台属于自己的 VPS(如 1核 1G内存,配置了 2G Swap)后,很多新手在尝试部署 Java 项目时,往往会选择直接在服务器上安装 Maven 或运行 docker build。但现实很残酷:Java 编译极其消耗内存,1G 的内存在构建瞬间就会被挤爆,导致系统卡死或触发 OOM (Out Of Memory) 杀掉进程。