如何在 Ubuntu 16.04 上使用 Node-RED 连接你的物联网设备

发布于:2024-05-06 ⋅ 阅读:(42) ⋅ 点赞:(0)

简介

Node-RED 是物联网的交换机板,是一个可视化工具,帮助您将喜爱的应用程序、网站和硬件连接在一起,实现新的有用功能。Node-RED 往往被比作 IFTTT 或已经停止运营的 Yahoo Pipes,但 Node-RED 拥有更强大、更灵活的界面,以及一个庞大的开源社区,创建 节点 与各种应用程序和服务进行交互。

在本教程中,我们将安装 Node.js 和 Node-RED,从 Let’s Encrypt 获取 SSL 证书,并使用 Nginx 处理 Node-RED 的安全连接。

先决条件

要按照本教程操作,您需要:

  • 一个 Ubuntu 16.04 服务器,具有非 root sudo 用户,并通过遵循 Ubuntu 16.04 服务器设置教程设置了基本防火墙。在本教程中,我们将使用名为 sammy 的用户,但您当然可以选择任何您喜欢的用户名,并根据需要进行替换。

  • 已安装 Web 服务器 Nginx,并更新防火墙以允许端口 80 和 443 的流量(Nginx Full),如《在 Ubuntu 16.04 上安装 Nginx》中所述。

  • 将域名指向您的服务器,如《如何在 DigitalOcean 上设置主机名》中所述。本教程将在整个过程中使用 node-red.example.com

  • 已安装 Let’s Encrypt,并为您配置的域名生成了证书。《如何在 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 个月内继续支持此版本。

通过检查版本来验证安装是否成功。

node -v

您将看到 Node.js 输出其版本号:


v4.2.6

Node Package Manager (npm) 帮助您安装和管理 Node.js 软件包,我们将使用它来安装 Node-RED。使用 apt-get 安装 npm

sudo apt-get install npm

要验证安装是否成功,请要求 npm 打印其版本信息:

npm -v

3.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 的主管理界面将加载。

!Node-RED 的主编辑界面

如果成功,您可以在终端中键入 CTRL+C 来关闭 Node-RED 并返回到命令提示符。我们已成功安装并测试了 Node-RED,接下来,我们将设置它在系统启动时启动。

步骤 3 — 在启动时启动 Node-RED

为了在启动时自动启动 Node-RED,我们需要安装一个 node-red.service 文件,而不是更传统的 init 脚本。这是因为 Ubuntu 16.04 是第一个使用 systemd 作为其 init 系统的 LTS 发行版。您可以在《Ubuntu 16.04 中的新功能》中找到对此和其他 Ubuntu 16.04 更改的摘要。

打开一个名为 node-red.service 的空服务文件。

sudo nano /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


```markdown
# 将日志输出到 syslog,标识为 'node-red'
SyslogIdentifier=node-red
StandardOutput=syslog

# 以非 root 用户运行
WorkingDirectory=/home/sammy/
User=sammy
Group=sammy

[Install]
WantedBy=multi-user.target

对 systemd 服务文件的完整解释超出了本教程的范围,但你可以通过阅读《Systemd Essentials: Working with Services, Units, and the Journal》来了解更多。

话虽如此,让我们来分解一下服务文件中的一些部分:

[Unit]
Description=Node-RED
After=syslog.target network.target

这描述了我们的服务,并指示在网络和 syslog 正常运行后启动它。

[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 的方式。

# 将日志输出到 syslog,标识为 'node-red'
SyslogIdentifier=node-red
StandardOutput=syslog

这设置了日志输出时使用的标签,并将所有输出记录到 syslog 服务。

# 以非 root 用户运行
WorkingDirectory=/home/sammy/
User=sammy
Group=sammy

我们希望以非 root 用户身份运行 Node-RED。上面的行告诉 systemd 使用我们的用户和组启动 Node-RED,并从我们的主目录中启动。

[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

复制并粘贴以下内容,更改服务器名称和证书路径:

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 代理的块。

if ($scheme = http) {
    return 301 https://$server_name$request_uri;
}

这个块将匹配任何普通的非安全的 http 连接,并将其重定向到站点的 https 版本。

proxy_pass http://localhost:1880;

我们在这里指向我们的 Node-RED 服务。它在 localhost1880 端口上可用,所以我们将连接传递到那里。配置块的其余部分设置了一些对于正确代理功能非常重要的标头。UpgradeConnection 标头对于处理 Node-RED 的 websocket 连接尤为重要。

最后,我们有一个块,以确保 Let’s Encrypt 挑战响应继续从 Nginx 的默认网站根目录获取:

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,然后我们就完成了。


## 第五步 —— 安全地配置 Node-RED 并完成设置

现在我们的连接已经是安全的了,让我们给 Node-RED 管理员添加一个密码。我们不直接将密码放入设置文件中,而是先对其进行单向加密哈希处理,然后再使用。我们将使用 `node-red-admin` 来创建哈希:

```command
node-red-admin hash-pw

系统会提示你输入密码。输入密码后,按下 ENTER 键,屏幕上将打印出哈希值。将其复制到剪贴板中,然后打开 Node-RED 设置文件。

nano ~/.node-red/settings.js

向下滚动并取消注释 adminAuth 块(即删除每行开头的 "// ")。将 username 更改为你喜欢的任何内容,并将哈希值粘贴到 password 字段中。

adminAuth: {
    type: "credentials",
    users: [{
        username: "admin",
        password: "$2a$08$Ab9prIr1M8a5a1/Zx8.B9.uIOCPe.v90ZGuZc2kAATp6BHJ/WV5KS",
        permissions: "*"
    }]
},

在打开文件的同时,也取消注释 uihost 行(即删除行首的 //)。

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,你将看到一个登录界面,而不是主要的编辑界面。

!Node-RED 的登录界面

如果你的网站显示了登录界面和 https 连接,那么你已经正确设置了一切。

结论

现在我们已经相对安全地安装了 Node-RED,并且使用 Let’s Encrypt 为其 SSL 证书进行了 Nginx 代理。登录并开始连接吧!在 Node-RED 的网站上还有更多信息和项目灵感可供参考。