现在还没有买 NAS,文件都放在电脑里,在外面要用就得先远程开机然后连接家里电脑拿文件。这时候就要通过树莓派来唤醒电脑了。
主要功能就是接收外部请求,然后发送魔术封包唤醒内网设备。通过 nginx
反代 Node.js,接收到外部发送的内网设备的 mac 然后发送魔术封包。当然需要你的宽带有公网 IP 才可以,而且你需要有自己的域名,或者路由器自己有提供 DDNS 域名的,例如华硕的路由就提供域名给用户设置 DDNS 的。
首先是你要在电脑的网卡设置允许外部唤醒,同时 Bios 里也要开启允许网络唤醒。
命令工具用 wakeonlan
,需要安装 sudo apt-get install wakeonlan
,某些系统是 wakelan
。
还可以直接使用 Node.js 的 Wol
包,这样就可以不需要另外安装 waleonlan
,不过都一样需要使用 root
运行 Node.js 才有权限访问网卡的!
安装和配置环境
我们先安装需要用的工具。或者直接用 node.js 的 wol
包就不需要安装这个。
sudo apt-get install nginx wokeonlan wget -y
如果你用非 root 用户运行的时候会有网卡访问权限问题,发不出魔术封包。就要给 wokeonlan 权限。
主要 Node.js 则需要下载解压再安装的。
# 先看一下系统内核
uname -a
# 因为树莓派 Zero W 是 armv6l 所以下载时候要注意你的 CPU。
wget https://nodejs.org/dist/v10.15.1/node-v10.15.1-linux-armv6l.tar.xz
# 解压
xz -d node-v10.15.1-linux-armv6l.tar.xz
tar -xavf node-v10.15.1-linux-armv6l.tar
# 把 Node.js 而进驻包移动到系统目录
sudo mv ./node-v10.15.1-linux-armv6l /usr/local/node
# 创建 Node.js 和 npm 的连接
sudo ln -s /usr/local/node/bin/node /usr/bin/node
sudo ln -s /usr/local/node/bin/npm /usr/bin/npm
这样就安装完成了。但是还要注意一样就是把目录加入环境变量!要不然用 npm 安装包只会就用不了的。
# 先看一下 npm 模块目录 例如:/usr/local/node/bin/npm
which npm
# 把返回的目录添加到环境变量
sudo nano /etc/profile
然后在后面加上 PATH=$PATH:/usr/local/node/bin/npm
,保存退出,然后执行 sudo source profile
或者重启树莓派。
确定代码放在哪个文件夹,我是放在用户目录下的,也就是 /home/pi/node/www/
。
新建文件夹
mkdir node
cd node
mkdir www
cd www
然后在这个文件夹安装 express
和 body-parser
两个需要依赖的包。
npm install express body-parser wol silly-datetime --sava
还有我们要用 pm2
代替直接 node
来后台运行服务,所以还要安装 pm2
。
sudo npm install pm2 -g
Nginx 设置
Nginx 主要用来处理请求,开启 SSl 等,然后反代本机的 Node.js。
我直接使用 nginxconfig.io 来生成服务器配置。
SSL 证书网上也有很多可以免费的泛域名证书,但是 SSL 就要你自己的域名和证书了,或者你可以用 acme.sh 在树莓派配置 Let’s Encrypt 证书,这样就不怕证书过期了。
Nginx 的详细用途直接网上一搜就一大堆了,不需要我这里介绍了。
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name myhome.boxks.com;
# SSL 证书路径
ssl_certificate /etc/nginx/ssl/myhome.boxks.com.crt;
ssl_certificate_key /etc/nginx/ssl/myhome.boxks.com.key;
# reverse proxy
location / {
# 反代本地 Node.js
proxy_pass http://127.0.0.1:5050;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
# security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# . files
location ~ /\.(?!well-known) {
deny all;
}
# gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
}
# HTTP redirect
server {
listen 80;
listen [::]:80;
server_name myhome.boxks.com;
return 301 https://myhome.boxks.com$request_uri;
}
Node.js 代码
主文件用 index.js
,因为后续要做其他,所以最好就是将 wol 制作成模块。
//1. 导入express
var express = require('express');
var wol = require('./wol.js');
// 创建服务器
var app = new express();
app.use('/wol', wol);
//. 绑定端口
app.listen(5050);
wol.js
文件
/**
* Post请求执行 shell 命令
* 只要向这个地址提交 {"mac":"设备 MAC 地址"}
* kaiyuan Hsie
* https://boxks.com
* */
//1. 导入express
var express = require('express');
// 解析器 需要安装 npm install -g body-parser
var bodyParser = require('body-parser');
// 创建 application/x-www-form-urlencoded 编码解析
var urlencodedParser = bodyParser.urlencoded({ extended: false });
// 创建服务器
var router = express.Router();
router.post("*", urlencodedParser, function (request, response) {
var process = require('child_process');
// Node.js 提供的子进程运行 shell 命令
if (!request.body) {
response.send("请提交设备 MAC 地址");
} else {
/**
* 使用工具 wakeonlan (需要安装), 某些系统是 wakelan
* Linux 也可使用命令 ether-wake -i br0 (设备 MAC 地址)
**/
process.exec('wakeonlan '+request.body.mac, function (error, stdout, stderr) {
if (error !== null) {
console.log('-wol- exec error: ' + error);//日志加上“-wol-”前缀方便以后搜索
response.send('exec error: ' +error);
} else {
console.log("-wol- "+request.body.mac);
response.send('成功执行命令');
}
});
}
})
module.exports = router;
使用 Nodejs 的 wol 包就用下面的代码
/**
* Post请求执行 shell 命令
* 只要向这个地址提交 {"mac":"设备 MAC 地址"}
* kaiyuan Hsie
* https://boxks.com
* */
//1. 导入express
var express = require('express');
// 解析器 需要安装 npm install -g body-parser
var bodyParser = require('body-parser');
// WOL 模块
var wolfun = require('wol');
// 时间模块
var sd = require('silly-datetime');
var nowTime=sd.format(new Date(), 'YYYY-MM-DD HH:mm:ss');
// 创建 application/x-www-form-urlencoded 编码解析
var urlencodedParser = bodyParser.urlencoded({ extended: false });
// 创建服务器
var router = express.Router();
router.post("*", urlencodedParser, function (request, response) {
//
if (!request.body) {
response.send("请提交设备 MAC 地址");
} else {
var thisMAC = request.body.mac;
wolfun.wake(thisMAC, function(error, postText){
if (error !== null) {
console.log('-wol- exec error: ' + error+' '+nowTime);
response.send('exec error: ' +error);
} else {
console.log("-wol- "+thisMAC+' '+postText+' '+nowTime);
response.send('已经叫咗电脑开机!');
}
});
}
});
module.exports = router;
运行程序
pm2
的 --watch
是自动检测文件修改然后重启服务
pm2 start /home/pi/node/www/index.js --watch
pm2
的详细用法可以看 Github 上的说明。
最好还是新建一个 pm2 的配置文件 pm2_config.json
,可以设置很多参数。例如下面的文件,可以设置程序目录、应用名称、日志目录等。
{
"apps" : [{
"name" : "nodewol",
"script" : "/home/pi/node/www/index.js",
"cwd" : "/home/pi/node/",
"instances" : "1",
"log_date_format" : "YYYY-MM-DD HH:mm Z",
"log_file" : "/home/pi/node/log/wol.log",
"error_file" : "/home/pi/node/log/wol-err.log",
"out_file" : "/home/pi/node/log/wol-out.log",
"watch" : true
}]
}
然后运行等命令就运行这个 json
文件。
pm2 start /home/pi/node/www/pm2_config.json
设置外网访问
设置DDNS
我自己使用的是 华硕 AC87U 路由器,路由就自带有 DDNS 功能,所以域名方面可以不用担心的。
我则是用自己的域名和 SSL 证书。
进路由后台,在「外部网络(WAN)」里面选择 DDNS,然后服务器选择华硕的,再填上你的二级域名,「HTTPS/SSL Certificate」选择「Import Your Own Certificate」然后上传你的证书。这里的证书不会影响你树莓派上的,单纯是访问你路由器管理页面用的!

如果你的服务商没有禁止了 80 端口的话其实可以选择「Free Certificate form Let’s Encrypt」就可以自动获取免费的证书了。
设置端口转发
同样是「外部网络(WAN)」顶部选择「端口转发」,然后自己设置一个端口映射到树莓派 443 端口就可以了。

域名 CNAME
我使用的是 CloudFlare,在 DNS 设置中加入 CNAME,然后不要使用 CloudFlare 的 CDN,因为我们需要的是直接连接家里的网络,不需要用 CDN 中转。

手机唤醒电脑
iOS 12 已经有「捷径」这样的工具,可以做很多事情,我就使用这个发送请求到树莓派的。
新建捷径,第一步先「URL」把树莓派的实际网址加进去,然后用「取得 URL 内容」选择 POST
表单,key
设置为 mac
,key
设置你设备的 MAC
,然后最后面用「显示结果」调用「URL内容」就可以了。
你还可以把这个捷径加入 Siri,然后直接就可以语音开电脑了。

您必须登录才能发表评论。