WireGuard 组网实战:把管理面板藏进 VPN
摘要
一次安全审计发现:宝塔面板、phpMyAdmin、nps 管理后台、s-ui 面板,四个管理入口全部公网可达,只靠账号密码挡着。三个收紧方案摆在面前(WireGuard VPN、IP 白名单、SSH 隧道),最后选了 WireGuard:手机电脑各一个客户端,分流配置只让管理流量走 VPN,防火墙把四个管理端口收成仅 VPN 网段可达,公网实测直接超时。本文记录完整的方案选型、WireGuard 原理速览、部署步骤、VPN 内访问地址清单,以及一次把业务端口误收紧的真实踩坑。
目录
- 引言:审计发现管理面板在公网裸奔
- 方案选型:三个选项,为什么是 WireGuard
- WireGuard 的核心原理(一分钟版)
- 服务端部署:VPS 上的 wg0
- 客户端配置:分流,只让管理流量走 VPN
- AllowedIPs 到底在控制什么
- 手机端导入实操
- 防火墙收紧:管理口与业务口必须分清
- VPN 内访问地址清单
- 踩坑实录:两次"打不开"的真相
- 敏感配置归档:进 NAS 私密文件夹
- 总结
引言:审计发现管理面板在公网裸奔
事情的起因是一次只读安全审计。扫了一圈 VPS 的防火墙和监听端口,发现 UFW 的公网放行列表里躺着这么几个端口:17449(宝塔面板)、888(phpMyAdmin)、8080(nps 管理后台)、2095(s-ui 面板)。防火墙计数器还显示这些规则已经有入站命中,说明公网上的扫描器早就注意到它们了。
靠账号密码挡扫描器,等于把家门钥匙插在锁上,心里总归不踏实。审计结论很明确:管理面必须收敛。于是有了这次整改。
方案选型:三个选项,为什么是 WireGuard
当时摆了三个方案让用户选:
| 方案 | 做法 | 优点 | 缺点 |
|---|---|---|---|
| WireGuard VPN(推荐) | VPS 上建 VPN 服务端,管理端口只对 VPN 网段开放 | 出差、动态 IP 都能用;手机电脑都方便;一次配置长期有效 | 需要装客户端 |
| 防火墙 IP 白名单 | 只放行家里公网 IP | 零客户端,最简单 | 家里 IP 一变就失联;出差在外无法管理 |
| SSH 隧道 | 面板只监听本机,经 SSH 端口转发访问 | 不新增服务 | 每次都要手动建隧道;手机上操作麻烦 |
用户选了 WireGuard。理由很实际:他经常出门,手机就是主力管理终端,IP 白名单在动态 IP 面前不堪一用,SSH 隧道在手机上又太折腾。WireGuard 一次配好,手机上点一下连接,管理面板就像在内网一样打开,这个体验是另外两个方案给不了的。
WireGuard 的核心原理(一分钟版)
动手之前,先花一分钟理解 WireGuard 到底在干什么,免得配的时候像在背咒语。
WireGuard 是一个三层(IP 层)VPN,跑在 UDP 上。它的设计哲学是"极简":整个协议约几千行代码,没有传统 VPN(比如 OpenVPN/IPsec)那堆协商套件和插件。核心机制就三块:
- Noise 协议握手:双方用 Curve25519 做 1-RTT(一次往返)密钥交换,握手完就有一组对称密钥。没有证书体系,身份就是一对公私钥,公钥即身份。
- cryptokey routing(加密密钥路由):这是 WireGuard 最有特色的设计。它维护一张"IP 网段 → 对端公钥"的路由表。收到一个加密包,用哪个密钥解密,取决于解密后内层 IP 的源地址落在哪个对端的 AllowedIPs 里;要发包给 10.88.0.2,就用 10.88.0.2 对应公钥加密。路由和加密是同一张表,配错 AllowedIPs,包要么发不出去,要么对端直接丢弃。
- 无连接状态:WireGuard 本身不感知"连接",靠定时握手和数据包驱动保持会话。网络切换(比如手机从 WiFi 切到 5G)时,它能自动漫游重建,对端 IP 变了也能认出来。这就是为什么它特别适合手机。
理解了第 2 点,后面"服务端 peer 写 10.88.0.2/32、客户端 AllowedIPs 写 10.88.0.0/24"的配置就不再是玄学,而是在填写这张路由表。
服务端部署:VPS 上的 wg0
VPS(Debian 13)上安装 WireGuard 服务端,网卡命名为 wg0,网段规划为 10.88.0.0/24,VPS 自己是 10.88.0.1。UDP 51820 在 UFW 上放行公网,这是整个 VPN 唯一需要暴露的端口。
# 安装并启用(Debian 13)
apt install wireguard -y
systemctl enable --now wg-quick@wg0
# 确认接口起来了
wg show wg0
# 应看到 interface: wg0,listening port: 51820
服务端配置的核心就几行(密钥部分略去,见后文归档说明):
[Interface]
Address = 10.88.0.1/24
ListenPort = 51820
PrivateKey = (略,保存在 VPS /etc/wireguard/,权限 600)
[Peer]
# 手机
PublicKey = (略)
AllowedIPs = 10.88.0.2/32
[Peer]
# 电脑
PublicKey = (略)
AllowedIPs = 10.88.0.3/32
/etc/wireguard/ 目录权限设为 600,密钥明文只存在于 VPS 本地和 NAS 的私密配置归档里,不会出现在聊天记录、日志或任何公开位置。
客户端配置:分流,只让管理流量走 VPN
客户端有两个:手机(10.88.0.2/32)和电脑(10.88.0.3/32)。关键设计是分流:AllowedIPs 只写 10.88.0.0/24,不写 0.0.0.0/0。这意味着只有访问管理面板的流量走 VPN,日常上网、刷视频的流量该走哪走哪,VPN 不背这个锅。
[Interface]
PrivateKey = (略)
Address = 10.88.0.3/32
[Peer]
PublicKey = (略)
Endpoint = 82.139.204.8:51820
AllowedIPs = 10.88.0.0/24
分流还有一个附带好处:VPN 隧道的带宽和稳定性只影响管理操作,不影响正常上网。VPS 本来就只有约 1 GiB 内存,让全量流量走 VPN 纯属浪费资源。
AllowedIPs 到底在控制什么
AllowedIPs 是 WireGuard 里最容易配错、也最值得讲透的一个字段。它同时干两件事,对应 cryptokey routing 的两个方向:
| 方向 | 含义 | 本例 |
|---|---|---|
| 出站路由 | 发往这些网段的包,走这个 peer 的隧道出去 | 客户端写 10.88.0.0/24:访问管理网段才进隧道,其余走默认路由 |
| 入站校验 | 只接受源 IP 落在这些网段内的解密包,其他的丢弃 | 服务端给手机 peer 写 10.88.0.2/32:这个 peer 只能顶着 10.88.0.2 的源地址发包 |
所以服务端 peer 的 AllowedIPs 要写精确的 /32:它既是"这个客户端是谁"的身份声明,也是防止客户端冒充别人源 IP 的校验。而客户端的 AllowedIPs 写 10.88.0.0/24,是在说"我只把管理网段的流量交给你",这就是分流的全部秘密——没有复杂的策略路由,一行配置搞定。
验证隧道通没通,不用猜:服务端跑 wg show wg0 latest-handshakes,能看到某个 peer 的近期握手时间,就说明它在线。当时手机扫码导入后,握手记录正常出现;电脑 peer 还没导入,列表里没有它的握手,属于正常现象。
手机端导入实操
手机是这次的主力管理终端,导入步骤值得单独记一笔:
- 在手机上安装 WireGuard 官方 App;
- 服务端为手机 peer 生成好配置(含私钥),转成二维码;
- 手机 App 里点"+" → "从二维码创建",扫码;
- 给隧道起个名(比如"家里管理"),点一下开关连接;
- 到 VPS 上跑
wg show wg0 latest-handshakes,看到手机 peer 有近期握手,即连通。
二维码和电脑版配置文件都属于敏感资料,生成后第一时间归档进了 NAS"私密配置"(见后文),用完即从临时位置删除,不在聊天记录和日志里留明文。
防火墙收紧:管理口与业务口必须分清
VPN 通了之后,把四个管理端口的公网放行删掉,改为仅允许 10.88.0.0/24 访问:
# 以宝塔面板 17449 为例:删掉公网放行,改为仅 VPN 网段
ufw delete allow 17449/tcp
ufw allow from 10.88.0.0/24 to any port 17449
# 同理处理 888、8080、2095
收紧后从公网实测:curl 访问 17449 和 888 直接超时(连接建不上),说明管理入口已经不再公网直达。整改生效。
但这里有个极其重要的区分:管理口和业务口。VPS 上有些端口看起来像管理口,实际承担着业务流量,收紧它们会直接断业务:
| 端口 | 真实用途 | 定性 | 处理 |
|---|---|---|---|
| 17449 | 宝塔面板 | 纯管理口 | 仅 VPN |
| 888 | phpMyAdmin | 纯管理口 | 仅 VPN |
| 8080 | nps Web 管理 | 纯管理口 | 仅 VPN |
| 2095 | s-ui 面板 | 纯管理口 | 仅 VPN |
| 8808 | nps 的 Win RDP 隧道 | 业务口 | 保持公网放行,不能动 |
| 2096 | s-ui 订阅端口 | 业务口 | 保持公网放行,不能动 |
| 8024/8081/8082 | nps 客户端隧道 | 业务口 | 不动 |
| 8443 | s-ui 业务端口 | 业务口 | 不动 |
| 8999/80/443/22022 | nginx 业务 / 网站 / SSH | 业务口 | 不动 |
判断方法很实在:ss -tlnp 看监听进程,再结合已有架构记录逐个确认。nps 的管理端口读它的配置文件能确认是 8080,8808 只是它承载的一条 RDP 隧道。s-ui 的数据库里能查到面板端口是 2095、面板路径是 /app/,2096 是订阅端口。收紧前必须逐端口确认用途,这是用一次真实故障换来的教训,详见下节。
VPN 内访问地址清单
连上 VPN 之后(手机或电脑),管理面板的访问地址如下:
| 服务 | VPN 内地址 | 备注 |
|---|---|---|
| 宝塔面板 | https://10.88.0.1:17449/安全入口路径 | 必须 HTTPS 且带安全入口路径,HTTP 会被重置,根路径返回 404 |
| nps 管理后台 | http://10.88.0.1:8080 | 内网明文即可,流量已在 VPN 隧道内 |
| s-ui 面板 | http://10.88.0.1:2095/app/ | 注意带 /app/ 路径,返回 307 跳转属正常 |
| phpMyAdmin | 从宝塔面板里进入最方便 | 888 站点绑定了 server_name,直接拿 IP 访问会 404 |
| 黑群晖 DSM | https://10.88.0.1:28100 | 自签证书,浏览器需手动继续;28100 同样仅 VPN 可达 |
注意 DSM 那一行:28100 这个端口从一开始就没对公网开放过(防火墙默认 DROP),之前是通过 nps 隧道(VPS 28100 → 192.168.0.106:5001)在 VPS 本机提供服务。这次顺手给它加了仅 VPN 可达的防火墙规则,手机连上 WireGuard 就能直接打开 DSM,不用再绕隧道。
另外提一句留白:nps 的公网管理域名(nps.028000.xyz)目前仍然可以从公网访问,靠 nps 自身的账号密码保护。这是用户逐项定夺后决定保留的,理由是"有账号密码即可"。安全上这是一个已知的、被接受的例外,记在这里备查。
踩坑实录:两次"打不开"的真相
第一次:8808 和 2096 被误伤。 收紧操作时,一度把 8808 当成了 nps 的管理口、把 2096 当成了 s-ui 的闲置端口,一起改成了仅 VPN 可达。结果 8808 是家里 Win 机器的 RDP 隧道(nps 承载),2096 是 s-ui 的订阅端口,都是业务口。发现后立即用 ufw allow 把公网放行恢复,纯管理口(17449/888/8080/2095)保持仅 VPN。教训:收紧前必须区分业务口与管理口,默认不碰任何不确定的端口。事后这条被写进了防火墙操作规范。
第二次:"宝塔打不开"是虚惊一场。 手机连上 VPN 后,一度打不开宝塔面板,第一反应是隧道坏了。逐跳排查后发现真相有三层:宝塔开了 HTTPS,普通 HTTP 会被直接重置;宝塔带安全入口路径,直接访问根路径会因入口保护返回 404;服务端实测确认,用浏览器 UA 访问带安全入口路径的地址返回 200。用户真机确认可用。教训:面板"打不开"先别怪网络,先看清它的访问要求(协议、路径、UA),很多"故障"只是没按它的规矩敲门。
还有一个小坑:phpMyAdmin 的 nginx 站点绑了 server_name=phpmyadmin,直接用 http://10.88.0.1:888 访问会 404。最省事的办法是从宝塔面板里点进去,别跟 server_name 较劲。
敏感配置归档:进 NAS 私密文件夹
WireGuard 的客户端配置(含私钥)和手机二维码,属于"丢了就等于把家门钥匙送人"的敏感资料。按用户定的规矩,它们统一归档到 NAS 上独立的"私密配置"共享文件夹:
NAS/私密配置/
├── README.md # 归档规范:什么能进、怎么分类
├── 踩坑记录.md # 本轮的坑:宝塔入口、端口辨析、phpMyAdmin 等
└── WireGuard/
├── README.md # 用途、手机/电脑导入方法、VPN 内地址、分流与应急说明
├── wg-pc.conf # 电脑客户端配置
└── wg-phone.png # 手机二维码
这个共享有三个特点:第一,不挂载到 OpenList,对外文件站看不见;第二,上传后从 NAS 回读做 MD5 校验,确保归档件和源文件一致;第三,每类敏感配置一个子目录加一份 README,说明"这是什么、怎么用"。今后 VPN、证书、密钥、Token 都按这个格式归档。应急情况下(比如 VPN 连不上),SSH 隧道仍然可以作为进入管理面的备用通道。
总结
这次整改的完整链条是:审计发现问题 → 三个方案用户拍板 → WireGuard 服务端上线 → 客户端分流配置 → 防火墙按"管理口/业务口"逐个收紧 → 公网实测验证 → 敏感配置归档。中间踩了一个真实的坑(误伤业务口),换来一条硬规矩(收紧前逐端口确认用途)。管理面板现在藏在 10.88.0.0/24 后面,公网扫描器连握手都建不上,而手机点一下 VPN,该管的照样能管。安全和便利,这次都要了。
相关阅读:《家庭数据中心架构总览:VPS、PVE、NAS 三方分工》、《nps 内网穿透实战:一机一 Client 的隧道管理体系》、《fail2ban 实战:从 SSH 到 Web 登录接口的防护》