使用 FRP 和 WakeOnLan 远程电脑的方法
使用 FRP 和 WakeOnLan 远程电脑的方法
在某些场景下,我们需要在外远程访问家中的电脑。例如,最近过年回家时,有些服务需要远程查看,因此我折腾了使用 FRP 远程访问家中 Mac 的方法,还有远程唤醒电脑的 WakeOnLan 方案。
如何使用 frp 远程
FRP 的远程访问逻辑非常简单。由于家庭宽带通常不提供公网 IP(目前申请公网 IP 通常需要额外付费,具体方式需咨询运营商),因此需要通过服务器进行网络中转。
配置的过程中使用的是安全地暴露内网服务方式,这里简称为 stcp,使用的版本是v0.61.0。
Mac 自带的远程访问方式为 VNC,需要打开「设置」,「共享」,「屏幕共享」,并且打开「允许使用密码控制屏幕」。
服务端 frps 的配置为
frps.toml
,启动命令为
./frps -c frps.toml
bindPort = 7100 # 服务器监听端口
auth.token = "xxx" # 服务器验证密码
在深圳的机器上,运行 FRP 客户端配置文件
frpc.toml
如下,启动命令为
./frpc -c frpc.toml
。
serverAddr = "xxx" # 服务器域名
serverPort = 7100 # 服务器监听端口
auth.token = "xxx" # 服务器验证密码
[[proxies]]
name = "secret_ssh" # 名称要和访问者的配置保持一致
type = "stcp"
# 只有与此处设置的 secretKey 一致的用户才能访问此服务
secretKey = "xxx"
localIP = "127.0.0.1"
localPort = 5900 # macOS 系统屏幕共享服务监听的端口号
在外电脑运行 frpc 配置为
frpc.toml
,启动命令为
./frpc -c frpc.toml
serverAddr = "xxx" # 服务器域名
serverPort = 7100 # 服务器监听端口
auth.token = "xxx" # 服务器验证密码
[[visitors]]
name = "secret_ssh_visitor"
type = "stcp"
# 要访问的 stcp 代理的名字
serverName = "secret_ssh"
# 只有与此处设置的 secretKey 一致的用户才能访问此服务
secretKey = "xxx"
# 绑定本地端口以访问服务
bindAddr = "127.0.0.1"
bindPort = 6000
启动之后,打开 macos 自带的「屏幕共享」软件,按照配置连接
127.0.0.1:6000
,输入账号密码即可远程使用。
FRP 远程的体验
macOS 的远程使用的协议是 VNC 协议,相比于 Windows 的 RDP 协议体验会差一些。由于 macOS 的复杂动效和高分辨率,会很卡,把 macOS 的分辨率调整为 1080P,开启系统设置中的「减弱动态效果」,但是微信打开图片依然有渐变的动画,其他更深层次的优化设置没去研究了。
找了一下相关的帖子,例如Mac 上最流畅不卡的远程控制另外一台 Mac 的方法是什么?和求远程 mac 的最佳方式。在原生的 VNC 协议上,想要获得较好的体验就得加带宽,4Mbps 的带宽都很难获得较好的体验,最近云厂商出了峰值 200Mbps 的服务器体验会稍微好一点。其他类似 teamviewer 和向日葵之类的软件就没有去尝试了。
在「屏幕共享」连接成功后,点击顶部状态栏的「编辑」菜单,选择「使用共享的剪切板」,这样可以方便地在两台机器之间复制粘贴内容。文件传输方面,把文件拖动到目标电脑的「访达」目录即可。
FRP 的安全性和 TLS 抓包
另外对于 FRP 的安全性进行了简单的探究。
- 部署在公网服务器上的 FRP 服务如何不被别人盗用?
在服务器的配置文件中设置了
auth.token = "xxx" # 服务器验证密码
来保证不知道 auth.token 的用户无法使用。
- FRP 协议传输数据的过程中是否有加密处理?
在以前讨论里有流量被嗅探 #3193相关的讨论。在 2023 年 6 月,FRP v0.50.0默认使用了 tls 协议来进行加密,但是在 frps 随机生成的证书没有校验,做到这个程度已经差不多了。如果要进一步提升安全性,就自己配置证书。
我通过抓包也看到在三次握手完成之后,就开始走 TLS 协议。
WakeOnLan 的需求
原本到这里应该就结束了,让电脑永不休眠就可以了。然而我给电脑用上了「小米智能插座 3」,发现电脑在正常空跑的情况,在留存 Chrome、微信和 QQ 的情况下,功耗一般在 55-70w 之间。
如果是休眠状态,电脑功耗仅需要 3W。值得一提的是,我买了 Macmini M4,即使空跑也只有 3W 的功耗,苹果是真的省电。
按照 60w 的功率计算,一天大概需要 1.44 度电,按照 7 毛一度电,一天的电费需要 1 元,一年就是 365 元。
12 6024/1000=1.44度
1.440.7=1元
啥都不干需要消耗这么多电力,这显然不太合理。虽说可以设置电脑连接电源时自动启动,通过智能插座来远程控制开关电源,但是这样做不满足我的需求。于是我使用WakeOnLan(网络唤醒)技术来唤醒休眠中的电脑。
WakeOnLan 的配置
WakeOnLan 的原理很简单,就是网卡监听收到的包,如果是特殊内容的魔术包就唤醒操作系统。目前绝大多数电脑都支持通过 WakeOnLan 来唤醒。以我的 PC 为例,在 BIOS 中设置 PICE-E 和 Intel CNVi 为 Enable 状态即可。
设置好之后就需要从另外一个设备来唤醒,我尝试了使用群晖和路由器都可以办到,由于路由器一直跑并且不休眠的,所以最终选择使用路由器。我问了 AI 来生成一个唤醒的程序,给代码稍作改动就达到目的,我将代码和编译出来的执行程序都放到了 github 上的wakeonlan_go。
我的路由器是红米 AX6000,在路由器中执行命令可以看到基础系统是 openwrt,询问 AI 得知应该使用 linux 的 arm64 进行编译。
cat /etc/os-release
NAME="OpenWrt"
VERSION="18.06-SNAPSHOT"
ID="openwrt"
ID_LIKE="lede openwrt"
PRETTY_NAME="OpenWrt 18.06-SNAPSHOT"
VERSION_ID="18.06-snapshot"
HOME_URL="http://openwrt.org/"
BUG_URL="http://bugs.openwrt.org/"
SUPPORT_URL="http://forum.lede-project.org/"
BUILD_ID="unknown"
LEDE_BOARD="mediatek/mt7986"
LEDE_ARCH="aarch64_cortex-a53"
LEDE_TAINTS="no-all busybox"
LEDE_DEVICE_MANUFACTURER="OpenWrt"
LEDE_DEVICE_MANUFACTURER_URL="http://openwrt.org/"
LEDE_DEVICE_PRODUCT="Generic"
LEDE_DEVICE_REVISION="v0"
LEDE_RELEASE="OpenWrt 18.06-SNAPSHOT unknown"
首先将文件拷贝到路由器的
/tmp
目录,然后将其移动到
/data
目录下。在命令行中执行以下命令即可唤醒电脑。
# 这里的 ip 我填的是,192.168.31.255,需要填写电脑所在的局域网的广播地址,家用路由器的 ip 一般是 192.168.1.x 这里广播地址应该填写 192.168.1.255
# 如果子网掩码不是 255.255.255.0,就涉及计算机网络知识,需要替换成对应的广播地址。
/data/wake_on_lan -mac="xxx" -ip="xxx"
到这里局域网的唤醒就已经成功了。还需要在外网也能访问路由器的命令行来执行命令,将路由器的 ssh 也是用 frp 的 stcp 模式进行内网穿透。这里要注意的是如何让路由器用守护进程的方式运行 frp,我找 AI 也问了脚本,创建文件 frp-service,给执行权限。
#!/bin/sh /etc/rc.common
# 给红米 AX6000 路由器使用的,所以命名为 frp-service
# 用于启动和停止 FRP Client
START=99 # 启动顺序,较高的数字表示较晚启动
STOP=10 # 停止顺序
# 描述信息
DESCRIPTION="FRP Client"
# 启动命令
start() {
echo "Starting FRP Client..."
/data/frp_0.61.0_linux_arm64/frpc -c /data/frp_0.61.0_linux_arm64/frpc.toml &
}
# 停止命令
stop() {
echo "Stopping FRP Client..."
killall frpc
}
# 重启命令
restart() {
echo "Stopping FRP Client..."
killall frpc
echo "Starting FRP Client..."
/data/frp_0.61.0_linux_arm64/frpc -c /data/frp_0.61.0_linux_arm64/frpc.toml &
}
就可以通过
/data/frp-service start
命令来启动服务在后台运行了。需要注意的是除了 /data 目录下的文件,其他文件都会在路由器重启时被重置。这里还有个稍微不爽的点是在唤醒后需要等 30 秒左右远程桌面才能重新连上。
最后
本文的需求只是暴露 TCP 服务,直接暴露 TCP 到公网容易被各种暴力破解扫描,所以使用了 FRP 提供的 STCP 方式。如果只需要暴露 http 服务,那么再走 nginx 类的方向代理程序使用 https 对外提供服务比较安全,具体可以看很多年前写过的使用 Frp 内网穿透进行开发。
由于我只用了 macOS 的远程访问,FRP 在 windows 上设置开机启动和守护进程的方式不太一样,有朋友尝试后也完成了设置,可以看看Windows 设置 frpc 开机自动启动(不管用户是否登陆都要运行)
由于现在已经满足了我的需求,比较流行的异地组网,如headscale或者tailscale的方案没有继续深入研究了。