如何在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_certificatessl_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 上可用,所以我们在那里传递连接。 此配置块的其余部分设置了一些对代理正常运行很重要的标头。 UpgradeConnection 标头对于处理 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 的网站 上提供了更多信息和项目灵感。