让家里电脑随叫随到:飞牛NAS+Lucky实现远程睡眠与唤醒
家里电脑你是不是也遇到过这两种情况:
想用的时候它睡了。人在外面,突然要查个文件、跑点东西,结果电脑正睡着,人不在跟前,叫不醒。
用完的时候忘关了。忙完出门,电脑还空开着,一天天白白耗电。
要是能手机点一下让它睡、再点一下把它叫醒,人在外面也能操作,这两个问题就都解决了。
这篇文章记录我自己搭的一个方案:用一台常开的飞牛NAS当中转站,配合一个几十行的Python脚本,实现家里电脑的远程睡眠和远程唤醒。
一、先认识一下参与的三台设备
1.电脑A:飞牛NAS,常年开机,充当入口和中继
2.电脑B:你要远程控制的家里电脑
3.电脑C:你在外的手机或电脑,用来发起指令

简单说就是:电脑C通过域名访问NAS上的Lucky,Lucky再把指令转发给电脑B,或者由Lucky直接发唤醒包。
说明: D:cxswork260930G83sleepassetsimage-20261001154920494.png如果你没有域名,也可以用飞牛官方的Fnconnect,效果差不多。下面默认你有独立域名。
二、为什么选"睡眠+唤醒",而不是关机或远程桌面
为什么不直接关机?
关机再开机意味着所有软件、网页、工作现场全没了,得重来。睡眠会把状态保留在内存里,唤醒后秒回原样,省电又不打断工作。
它跟远程桌面是两回事:
Radmin、ToDesk、向日葵这些解决的是"人在外面怎么操作电脑",而这套方案解决的是"电脑本身的睡眠和唤醒"。
两者不是替代关系,恰恰相反,电脑一睡着远程桌面也连不进去,所以远程唤醒其实是远程桌面的前置条件,它们互补。
唤醒和睡眠是两条完全不同的技术路径,下面分开说。
三、睡眠和唤醒分别怎么走
睡眠链路:电脑C访问域名 → 飞牛NAS上的Lucky → curl发请求 → 电脑B上的/sleep接口 → PowerShell执行睡眠
电脑B上跑着一个轻量的HTTP服务,收到/sleep请求后调用PowerShell让系统睡眠。
唤醒链路:电脑C访问域名 → 飞牛NAS上的Lucky → 发WoL魔术包 → 电脑B网卡 → 开机
电脑B睡着后自己没法响应任何请求,所以唤醒靠的是网络唤醒(Wake-on-LAN),由Lucky向电脑B的网卡发一个魔术包,主板收到就开机。
为什么唤醒必须由NAS发起?
这是很多人第一次做会踩的坑。电脑B一睡,它上面的服务也跟着下线了,你不可能再向它发请求。所以唤醒这个动作只能由一台始终在线的设备来完成,飞牛NAS常年开机,正合适。
四、电脑B:装一个几十行的睡眠服务
电脑B需要装Python(用Node.js也行,那就是另一个脚本了)。建一个文件,我命名为sleep_server.pyw。用.pyw后缀的好处是双击运行不弹黑框,适合后台静默运行。
完整代码如下:
import http.server
import socketserver
import urllib.parse
import subprocess
import json
# ========= 配置区(改成你自己的)=========
PORT = 8899 # 服务监听端口
TOKEN = "改成你的随机长字符串" # 访问口令,务必改!
ALLOWED_IP_PREFIX = "192.168.1." # 只允许来自局域网的请求
# ========================================
class SleepHandler(http.server.BaseHTTPRequestHandler):
def log_message(self, format, *args):
print(f"[{self.client_address[0]}] {args[0]}")
def send_json(self, code, data):
self.send_response(code)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(json.dumps(data).encode("utf-8"))
def do_GET(self):
client_ip = self.client_address[0]
if not client_ip.startswith(ALLOWED_IP_PREFIX):
self.send_json(403, {"error": "IP not allowed"})
return
parsed = urllib.parse.urlparse(self.path)
params = urllib.parse.parse_qs(parsed.query)
if parsed.path == "/sleep":
self.handle_sleep(params)
elif parsed.path == "/status":
self.send_json(200, {"status": "ok", "message": "Webhook is running"})
else:
self.send_json(404, {"error": "Not found"})
def handle_sleep(self, params):
token = params.get("token", [""])[0]
if token != TOKEN:
self.send_json(401, {"error": "Invalid token"})
return
try:
ps_cmd = (
"Add-Type -AssemblyName System.Windows.Forms; "
"[System.Windows.Forms.Application]::SetSuspendState("
"[System.Windows.Forms.PowerState]::Suspend, $true, $false)"
)
result = subprocess.run(
["powershell", "-NoProfile", "-Command", ps_cmd],
capture_output=True, text=True, timeout=10,
creationflags=subprocess.CREATE_NO_WINDOW
)
if result.returncode == 0:
self.send_json(200, {"success": True, "message": "Sleep command sent"})
else:
self.send_json(500, {"success": False,
"error": result.stderr or result.stdout or "Unknown error"})
except subprocess.TimeoutExpired:
# 超时是正常的,系统正在睡眠,进程被挂起
self.send_json(200, {"success": True, "message": "Sleep command sent (timeout expected)"})
except Exception as e:
self.send_json(500, {"success": False, "error": str(e)})
def main():
with socketserver.TCPServer(("0.0.0.0", PORT), SleepHandler) as httpd:
print(f"Webhook server running on port {PORT}")
httpd.serve_forever()
if name == "__main__":
main()
代码只依赖Python标准库,不用装任何第三方包。
上面的代码做了三层防护:
1. 口令校验:/sleep必须带正确的token,否则返回401
2. IP白名单:只有指定网段(比如192.168.1.开头)的请求才处理
3. 固定路径:只有/sleep和/status两个接口,其他一律404
脚本写好之后,手工双击测试没问题,就把它设成开机自启(推荐用Windows的任务计划程序,勾选"不管用户是否登录都要运行"加"使用最高权限")。这样电脑B每次开机就自动在后台待命了。
五、飞牛NAS:Lucky的两块配置
Lucky是一款开源网络工具箱,DDNS、反代、端口转发、内网穿透、网络唤醒、计划任务都有,功能很全。在飞牛OS上通过Docker部署就行,安装过程不展开了。
装好之后我们只需要用它的两个功能。
5.1 网络唤醒(负责"醒")
进Lucky的"网络唤醒"模块,添加设备,填电脑B的MAC地址和局域网IP。保存后,以后在页面点一下就能向电脑B发魔术包完成唤醒。
说明: D:cxswork260930G83sleepassetsimage-20261001155855707.png唤醒没反应的话,先排查这几点:
1.BIOS/UEFI里开启Wake on LAN或PCI-E设备唤醒
2.Windows网卡的电源管理里勾选"允许此设备唤醒计算机",高级选项里开启"魔术包唤醒"
3.如果电脑B是完全关机(S5)而非睡眠(S3),个别主板要关掉"快速启动",否则WOL可能不生效
5.2 快捷指令(负责"睡")
Lucky的Web终端里有个"快捷指令"功能,可以预置一条命令一键执行。我们加一条睡眠指令,内容就是调用电脑B的服务:
curl "http://192.168.1.5:8899/sleep?token=你的口令"
说明: D:cxswork260930G83sleepassetsimage-20261001160118292.png点Web终端,在弹出的会话窗口里点快捷指令图标,找到刚才设置的指令,点一下就实现一键睡眠。
说明: D:cxswork260930G83sleepassetsimage-20261001162333437.png这里有个细节:这条curl是从NAS这边发出的,走局域网到达电脑B。所以电脑B的IP白名单设成局域网网段就能精准放行,不用对公网开放。
六、外网访问和安全
前面的配置都在局域网里跑,人在外面(电脑C)怎么触发?靠NAS的域名加外网访问能力:
1.飞牛NAS通过DDNS或内网穿透(Lucky本身支持)拿到可公网访问的域名
2.外部访问Lucky管理界面建议走HTTPS反代,别用明文HTTP暴露公网
3.Lucky管理账号设强密码,开登录校验
这样人在外面打开Lucky就能唤醒或睡眠家里电脑了。
安全方面再强调几点:
1. 不要把电脑B的/sleep端口直接映射到公网,让它只待在局域网里,Lucky作为唯一入口
2. token一定要改成长随机串,别用示例里的值
3. 电脑B的防火墙加规则,把8899端口的远程IP限制为192.168.1.0/24,从系统层面拦掉外网直连
4. 普通家用"睡眠+唤醒"够了,如果还想做截图、执行命令之类的高危操作,风险等级完全不同,需要更严格的鉴权,本文不覆盖
七、日常怎么用
整套链路跑通之后,日常流程很简单:
1. 出门在外,手机打开Lucky
2. 到"网络唤醒"点一下,家里电脑开机或唤醒
3. 不用的时候,到"快捷指令"点一下"睡眠",家里电脑入睡
八、总结
这套方案解决的其实就两个小问题:让睡着的电脑醒过来,让醒着的电脑睡过去。
但这两个小问题恰好是远程桌面够不着的。电脑一睡着,任何远程连接都无从谈起。
整套东西也很克制:
电脑B上一个几十行、零依赖的Python脚本,只认口令、只放行局域网来源;飞牛NAS上现成的Lucky,一边发魔术包完成唤醒,一边把睡眠指令转发给电脑B。睡让电脑自己干,醒让常开的NAS代劳。
没有引入重型组件,也没把电脑B的端口暴露到公网。边界清晰,只做睡与醒,不做更多。小带来的好处就是简单、稳定、好维护。
如果你家里也常开着一台NAS,又总为电脑忘关或者想用却发现它睡着了而头疼,不妨照着搭一个。很多时候把一件小事做到够用就好,比堆一整套功能来得更省心。
如果这篇对你有用,欢迎转发给同样折腾的朋友。
作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~
