布莱恩喵
项目档案已复盘

为了在外面打开家里电脑,我做了一个 NAS 远程开机网页

我用 NAS、Tailscale、WoL 和 SSH 拼了一个手机远程开关 Windows 电脑的小网页。它能跑,也让我重新认识了家庭网络自动化的边界。

NASTailscaleWoLDockerWindows

我真正想解决的不是“远程开机”这个技术问题,而是一个很具体的生活问题:人在外面,突然想用家里的显卡电脑,但它关着。

结论先放前面:这个小工具能解决我的核心需求。我人在外面时,可以先用手机连进自己的 Tailscale 网络,打开 NAS 上的一个网页,再点按钮唤醒家里的 Windows 电脑;用完以后,也能从同一个网页触发关机。

但它不是那种“所有人都应该照抄”的方案。它更像一个家庭网络里的小胶水:能跑,够用,也会把一些绕不过去的边界暴露出来。

为什么折腾

我有一台家里的 Windows 电脑,主要用来跑一些本地任务,比如 AI 模型、图像生成和需要显卡的东西。

问题是,人不在家时,这台电脑不应该一直开着。一直开着浪费电,也没必要;但要用的时候又希望它能远程醒过来,等服务启动好以后直接干活。

最理想的体验其实很简单:

  • 手机打开一个网页。
  • 点一下开机。
  • 等一会儿,家里的电脑开始工作。
  • 用完以后再点一下关机。

听起来像智能家居,实际做起来更像网络、系统权限和几个小坑叠在一起。

电脑远程控制网页界面,显示电脑在线、开机和关机按钮

我的公开版环境

公开版结构大概是这样:

手机
  -> Tailscale 私有网络
  -> NAS 上的网页工具
  -> 局域网里的 Windows 电脑

开机和关机走的是两条完全不同的路:

  • 开机:NAS 在局域网里发 WoL 的 Magic Packet,唤醒 Windows 有线网卡。
  • 关机:NAS 通过 SSH 登录 Windows,执行系统关机命令。

NAS 上跑的是一个很轻的小服务,放在 Docker 容器里。它不需要复杂后台,也不需要数据库,本质上就是一个只有几个按钮的网页。

实际怎么做

第一步是把网页放在 NAS 上。这个网页不负责花哨交互,只负责把两个高频动作放到手机上:开机和关机。

我最开始想找现成的 WoL Web 工具,结果选到的镜像并不能直接拉下来,干脆放弃,改成自己写一个很小的 Python HTTP 服务。这个选择不优雅,但很符合这个项目的气质:少一层依赖,少一层不确定。

第二步是让开机按钮发 Magic Packet。

WoL 这件事对环境要求不算高,但有几个前提必须满足:Windows 电脑最好走有线网卡,主板和网卡要允许关机后被唤醒,NAS 和电脑要在同一个局域网里。只要这些前提成立,NAS 发包,电脑就能醒。

第三步是让关机按钮走 SSH。

Windows 现在可以安装 OpenSSH Server。配置好以后,NAS 通过密钥登录 Windows,再执行关机命令。这里我没有把密码写进脚本,避免小工具变成安全隐患。

第四步是让 Windows 开机后自己把常用服务拉起来。

这一步我没有依赖远程桌面登录,而是用 Windows 服务和任务计划程序处理。电脑被唤醒后,后台服务延迟启动,尽量做到不用手动登录也能开始工作。

哪里卡住

第一个坑是现成镜像不可用。

这类小工具看起来 GitHub 上很多,但真正放到自己的 NAS 和网络环境里,经常会遇到镜像权限、构建年代、端口习惯和运行方式不合适的问题。最后自己写一个小服务,反而更省事。

第二个坑是 NAS 上的端口冲突。

NAS 本身会跑很多管理服务,有些端口已经被系统占用。这个问题不复杂,但会让“照着教程复制”立刻失效。最后我换成了一个不公开的本地端口,只在自己的私有网络里访问。

第三个坑是 SSH 密钥权限。

容器里挂载密钥文件时,文件权限可能不符合 SSH 客户端要求。SSH 会直接拒绝使用这个 key。解决办法不是放宽安全限制,而是在容器启动时复制一份临时 key,再把权限收紧到 SSH 接受的状态。

第四个坑是网页路径判断。

浏览器请求按钮链接时,路径后面可能会带查询参数。如果服务端只按完整路径做字符串匹配,就会出现按钮看起来点了、实际没有触发的情况。最后把路径和查询参数拆开处理,问题才消失。

第五个坑最麻烦:Windows 上 Tailscale 的无登录自动连接。

我尝试过让 Windows 冷启动后自动连回 Tailscale,但稳定性不够好。核心问题是 Tailscale 的桌面版状态和用户身份绑定比较深,冷启动、系统账户、任务计划、网络就绪时间凑在一起,很容易出现权限或状态不一致。

最后我没有把这个问题硬做下去。开机、关机、后台服务自启这三件事已经能稳定工作;Tailscale 的 Windows 无登录上线先作为遗留问题,不拿它当第一版成功标准。

这一步反而是整件事里最重要的取舍:不是所有问题都要在第一版解决。能稳定进入真实工作流,比做一个看起来很完整、实际很容易坏的方案更重要。

最后怎么解决

最终版本很克制:

  • NAS 上跑一个极简网页。
  • 开机按钮只负责发 Magic Packet。
  • 关机按钮只负责走 SSH。
  • 页面显示电脑在线状态,方便操作后确认。
  • Windows 侧用服务和任务计划处理后台启动。
  • Tailscale 只保证手机能访问 NAS 上的控制页,不强行解决 Windows 冷启动后的所有远程访问问题。

这个边界划清以后,整个工具反而稳定了。

很多家庭自动化失败,不是因为技术不够,而是第一版想一次解决太多问题:远程访问、自动登录、服务自启、安全认证、内网穿透、低功耗、图形桌面,全都塞在一起。这个项目给我的教训是,先把最关键的一段链路做稳,再决定要不要继续往上堆。

值不值得

如果只是偶尔远程开机,其实不一定值得折腾。买一个成熟的远程电源方案,或者直接用主板、路由器、远程桌面生态自带的功能,可能更省心。

但对我来说,这个小网页值得。原因不是它多高级,而是它把家里的 NAS、Windows 电脑、Tailscale 和本地 AI 工作流串了起来。它让我不用把高功耗电脑一直开着,也不用每次需要本地算力时都卡在“人不在家”这件事上。

我会把它归类为:适合愿意维护 NAS、懂一点 Docker 和局域网的人;不适合作为普通用户的第一套远程控制方案。

下一步

后面如果继续完善,我会优先看三件事:

  • 给操作加更清晰的结果反馈,而不是只靠刷新页面看状态。
  • 把配置从脚本里拆出去,减少以后改机器时的手工编辑。
  • 重新评估 Windows 冷启动后的远程访问方式,可能不再强求 Tailscale 桌面版自动上线,而是换一条更稳定的路。

这套东西不完美,但它已经进入了我的真实工作流。对我来说,这比写一个看起来很完整、实际不会再打开的教程更重要。