如何在Ubuntu16.04上使用Node-RED连接您的物联网
介绍
Node-RED 是一个物联网交换机,一个可视化工具,可帮助您将您喜爱的应用程序、网站和硬件连接在一起,以做新的有用的事情。 通常与 IFTTT 或已故的 Yahoo Pipes 相比,Node-RED 具有更强大和更灵活的界面,以及创建 节点 的大型开源社区以与各种应用程序和服务。
在本教程中,我们将安装 Node.js 和 Node-RED,从 Let's Encrypt 获取 SSL 证书,并使用 Nginx 处理 Node-RED 的安全连接。
先决条件
要遵循本教程,您将需要:
- 一台具有非 root sudo 用户和基本防火墙的 Ubuntu 16.04 服务器,按照 this Ubuntu 16.04 服务器设置教程 设置。 对于本教程,我们将使用一个名为 sammy 的用户,但当然您可以选择您喜欢的任何内容并根据需要进行替换。
- 已安装 Web 服务器 Nginx,并更新了防火墙以允许端口 80 和 443(Nginx Full)上的流量,如 如何在 Ubuntu 16.04 上安装 Nginx 中所述
- 指向您的服务器的域名,如 如何使用 DigitalOcean 设置主机名中所述。 本教程将自始至终使用
node-red.example.com
。 - 让我们安装加密,并为您在上面配置的域生成证书。 如何在 Ubuntu 16.04 上使用 Let's Encrypt 保护 Nginx 将引导您完成必要的步骤。 您可以忽略有关 Nginx 配置的步骤(步骤 3-5),我们将在此处介绍。 只需确保您获得成功颁发的证书,并设置
cron
作业来处理自动续订。
第 1 步 — 安装 Node.js 和 npm
Ubuntu 16.04 可以轻松安装最新的 Node.js 长期支持 (LTS) 版本,因为它包含在默认存储库中。
sudo apt-get install nodejs-legacy
该命令会安装 Node.js v4.2.x LTS(长期支持),这意味着 Node.js 基金会将从 2015 年 10 月 12 日发布之日起 30 个月内继续支持此版本。
注意:安装包的 -legacy
版本很重要,因为 Node-RED 的启动脚本要求您的 Node.js 二进制文件命名为 node
,但标准包使用nodejs
代替。 这是由于与预先存在的包的命名冲突。
通过检查版本来验证安装是否成功。
node -v
你会看到 Node.js 输出它的版本号:
Outputv4.2.6
Node Package Manager (npm
) 帮助您安装和管理 Node.js 软件包,我们将使用它来安装 Node-RED。 使用 apt-get
安装 npm
。
sudo apt-get install npm
要验证安装是否成功,请让 npm
打印其版本信息:
npm -v
Output3.5.2
如果它打印的版本号没有错误,我们可以继续下一步,我们将使用 npm
安装 Node-RED 本身。
第 2 步 — 安装 Node-RED
使用 npm
安装 node-red
和一个名为 node-red-admin
的辅助实用程序。
sudo npm install -g --unsafe-perm node-red node-red-admin
npm
通常会将其包安装到您的当前目录中。 在这里,我们使用 -g
标志来“全局”安装包,因此它们被放置在标准系统位置,例如 /usr/local/bin
。 --unsafe-perm
标志帮助我们避免在 npm
尝试编译本机模块(以 C 或 C++ 等编译语言编写的模块与 JavaScript)。
经过一些下载和文件改组后,您将返回到正常的命令行提示符。 让我们测试一下我们的安装。
首先,我们需要在防火墙上打开一个端口。 Node-RED 默认使用端口 1880
,所以让我们允许它。
sudo ufw allow 1880
现在启动 Node-RED 本身。 不需要 sudo
,因为端口 1880
足够高,不需要 root 权限。
node-red
一些“欢迎使用 Node-RED”消息将打印到终端。 在您的计算机上,将 Web 浏览器指向服务器的端口 1880
。 在我们的示例中,即 http://node-red.example.com:1880
。 将加载 Node-RED 的主管理界面。
如果成功,您可以在终端中键入 CTRL+C
以关闭 Node-RED 并返回命令提示符。 我们已经成功安装 Node-RED 并对其进行了测试,接下来,我们将设置它以在系统启动期间启动。
第 3 步 — 在启动时启动 Node-RED
为了在启动时自动启动 Node-RED,我们需要安装一个 node-red.service
文件,而不是更传统的 init 脚本。 这是因为 Ubuntu 16.04 是第一个使用 systemd
作为其 init 系统的 LTS 版本。 您可以在 What's New in Ubuntu 16.04 中找到此更改和其他 Ubuntu 16.04 更改的摘要。
打开一个名为 node-red.service
的空白服务文件。
sudo nano /etc/systemd/system/node-red.service
复制并粘贴以下内容,然后保存并关闭文件。
/etc/systemd/system/node-red.service
[Unit] Description=Node-RED After=syslog.target network.target [Service] ExecStart=/usr/local/bin/node-red-pi --max-old-space-size=128 -v Restart=on-failure KillSignal=SIGINT # log output to syslog as 'node-red' SyslogIdentifier=node-red StandardOutput=syslog # non-root user to run as WorkingDirectory=/home/sammy/ User=sammy Group=sammy [Install] WantedBy=multi-user.target
systemd 服务文件的完整解释不在本教程范围内,但您可以通过阅读 Systemd Essentials:使用服务、单元和日志 了解更多信息。
也就是说,让我们分解一下我们的服务文件中的一些部分:
/etc/systemd/system/node-red.service
[Unit] Description=Node-RED After=syslog.target network.target
这描述了我们的服务,并表明它应该在网络和系统日志运行后启动。
/etc/systemd/system/node-red.service
[Service] ExecStart=/usr/local/bin/node-red-pi --max-old-space-size=128 -v Restart=on-failure KillSignal=SIGINT
ExecStart
是启动我们的服务所需的命令。 我们调用 node-red-pi
而不是普通的 node-red
以便我们可以将一些节省内存的选项传递给 Node.js。 这应该允许它在任何合理大小的服务器上运行良好,当然这取决于您在 Node-RED 中创建的流的数量(以及它们的复杂程度)。 Restart=on-failure
意味着 systemd 将在 Node-RED 崩溃时尝试重新启动它,并且 KillSignal
告诉 systemd 在需要关闭或重新启动进程时退出 Node-RED 的最佳方式。
/etc/systemd/system/node-red.service
# log output to syslog as 'node-red' SyslogIdentifier=node-red StandardOutput=syslog
这将设置记录时使用的标签,并将所有输出记录到 syslog 服务。
/etc/systemd/system/node-red.service
# non-root user to run as WorkingDirectory=/home/sammy/ User=sammy Group=sammy
我们想以非 root 用户身份运行 Node-RED。 上面的几行告诉 systemd 使用我们的用户和组从我们的主目录中启动 Node-RED。
/etc/systemd/system/node-red.service
[Install] WantedBy=multi-user.target
WantedBy
表示我们的服务应该运行的目标。 在这种情况下,当 Ubuntu 启动到多用户模式时,它会知道也启动我们的 Node-RED 服务。 多用户模式是默认的启动目标。
现在我们的服务文件已安装并理解,我们需要启用它。 这将使它能够在启动时执行。
sudo systemctl enable node-red
现在让我们手动启动该服务以测试它是否仍在工作。
sudo systemctl start node-red
将浏览器指向服务器的端口 1880
并验证 Node-RED 是否已备份。 如果是,请将其关闭,直到我们在下一步中保护安装。
sudo systemctl stop node-red
第 4 步 — 设置 Nginx
我们将使用 Nginx 来 代理 Node-RED 服务。 这意味着 Nginx 将处理端口 443
上的所有 SSL 连接(使用您之前设置的 Let's Encrypt 证书),然后将流量传递给 Node-RED。
为站点打开一个新的 Nginx 配置。
sudo nano /etc/nginx/sites-enabled/node-red.example.com
复制并粘贴以下内容,更改服务器名称和证书路径:
/etc/nginx/sites-enabled/node-red.example.com
server { listen 80; listen 443 ssl http2; server_name node-red.example.com; ssl_certificate /etc/letsencrypt/live/node-red.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/node-red.example.com/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; ssl_prefer_server_ciphers On; ssl_session_cache shared:SSL:128m; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8; location / { if ($scheme = http) { return 301 https://$server_name$request_uri; } proxy_pass http://localhost:1880; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location '/.well-known/acme-challenge' { root /var/www/html; } }
保存并关闭文件。 让我们解释一下这个文件的作用。
前三行告诉 Nginx 监听什么端口,响应什么域名。 ssl_certificate
和 ssl_certificate_key
行指向我们从 Let's Encrypt 检索到的证书。 其余的 ssl_
行选择比默认值更安全的协议、密码和选项。
location /
开始我们实际定义 Node-RED 代理的块。
/etc/nginx/sites-enabled/node-red.example.com
if ($scheme = http) { return 301 https://$server_name$request_uri; }
此块将匹配任何普通的、非安全的 http 连接,并将它们重定向到站点的 https 版本。
/etc/nginx/sites-enabled/node-red.example.com
proxy_pass http://localhost:1880;
我们在这里指向我们的 Node-RED 服务。 它在 localhost
的端口 1880
上可用,所以我们在那里传递连接。 此配置块的其余部分设置了一些对代理正常运行很重要的标头。 Upgrade
和 Connection
标头对于处理 Node-RED 的 websocket 连接尤其重要。
最后,我们有一个块来确保继续从 Nginx 的默认 web 根中获取 Let's Encrypt 质询响应:
/etc/nginx/sites-enabled/node-red.example.com
location '/.well-known/acme-challenge' { root /var/www/html; }
重新加载 Nginx 以获取新配置。
sudo systemctl reload nginx
最后,再次启动 Node-RED。
sudo systemctl start node-red
再次导航到您的服务器:http://node-red.example.com
。 您应该被重定向到 https://node-red.example.com
(注意 https
)并查看 Node-RED 管理界面。 这意味着我们现在通过 Nginx 代理 Node-RED。 我们只需再做一些调整来锁定 Node-RED,然后我们就完成了。
第 5 步 — 保护 Node-RED 并结束
现在我们的连接是安全的,让我们为 Node-RED 管理员添加密码。 我们没有将裸密码直接放入我们的设置文件中,而是首先对其进行单向加密哈希,然后使用它。 我们将使用 node-red-admin
创建散列:
node-red-admin hash-pw
系统将提示您输入密码。 输入它,按ENTER
,屏幕上会打印一个哈希。 将其复制到剪贴板并打开 Node-RED 设置文件。
nano ~/.node-red/settings.js
向下滚动并取消注释 adminAuth
块(通过删除每行前面的“//”)。 将 username
更改为您喜欢的任何内容,并将哈希粘贴到 password
字段中。
设置.js
adminAuth: { type: "credentials", users: [{ username: "admin", password: "$2a$08$Ab9prIr1M8a5a1/Zx8.B9.uIOCPe.v90ZGuZc2kAATp6BHJ/WV5KS", permissions: "*" }] },
当我们打开文件时,通过删除行前面的 //
来取消注释 uihost
行。
设置.js
uiHost: "127.0.0.1",
这意味着 Node-RED 只会监听本地接口,而不会被外界直接访问(它只能通过 Nginx 代理访问)。 您现在可以保存并关闭文件。
最后一次更新防火墙,以确保永远无法直接访问 Node-RED。
sudo ufw deny 1880
最后,重新启动 Node-RED。
sudo systemctl restart node-red
导航到https://node-red.example.com
,您将看到一个登录屏幕,而不是主编辑界面。
如果您的站点显示登录屏幕和 https
连接,则您已正确设置所有内容。
结论
我们现在有一个相当安全的 Node-RED 安装,由 Nginx 使用 Let's Encrypt 为其 SSL 证书代理。 登录并获取接线! Node-RED 的网站 上提供了更多信息和项目灵感。