如何在 Debian 8 上安装 Mosquitto MQTT 消息传递代理并确保其安全

介绍

MQTT是一个机器到机器的消息协议,旨在为物联网设备提供轻量级发布/订阅通信,通常用于车辆车队的地理跟踪,家庭自动化,环境传感器网络和公用事业规模的数据收集。

Mosquitto是一个流行的MQTT服务器(或 broker,在MQTT语言中)具有很好的社区支持,易于安装和配置。

在本教程中,我们将安装Mosquitto,从Let's Encrypt获取SSL证书,并设置我们的经纪人使用SSL来保护我们的密码保护的MQTT通信。

前提条件

在开始本教程之前,您将需要:

步骤1:安装蚊子

Debian 的 mosquitto 包不支持我们需要的一些功能,所以我们将从 Mosquitto 项目提供的更新的存储库中安装。

1wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key

然后安装apt-key的密钥。

1sudo apt-key add mosquitto-repo.gpg.key

这允许apt-get验证您从新存储库安装的任何软件的完整性。

现在,通过在 `/etc/apt/sources.list.d/ 中的文件中添加库 URL 来告诉 'apt-get' 在哪里找到软件。

1sudo nano /etc/apt/sources.list.d/mosquitto.list

这将打开一个新的,空的文件. 粘贴下面的行到文件中。

1[label /etc/apt/sources.list.d/mosquitto.list]
2deb http://repo.mosquitto.org/debian jessie main

保存并关闭编辑器,然后用apt-get更新,将新包信息拖入。

1sudo apt-get update

最后,安装mosquitto包及其客户端软件。

1sudo apt-get install mosquitto mosquitto-clients

默认情况下,Debian 会在安装后启动 Mosquitto 服务. 让我们测试默认配置. 我们将使用我们刚刚安装的客户端之一来订阅我们的经纪商的主题。

Topics 是您发布消息并订阅的标签,它们分为等级,因此您可以有传感器 / 外部 / 时间传感器 / 外部 / 湿度,例如.您如何安排主题取决于您和您的需求。

登录你的服务器第二次,所以你有两个终端旁边. 在新的终端中,使用mosquitto_sub订阅测试主题:

1[environment second]
2mosquitto_sub -h localhost -t test

-h 标志指定了 MQTT 服务器的主机名称,而 -t 是主题名称. 点击 ENTER 后,您将不会看到任何输出,因为 mosquitto_sub 正在等待消息到达。

1mosquitto_pub -h localhost -t test -m "hello world"

mosquitto_pub的选项与mosquitto_sub相同,但这次我们使用额外的-m选项来指定我们的消息。点击ENTER,你应该看到 hello world 在另一个终端出现。

在第二个终端中按CTRL+C,退出mosquitto_sub,但保持与服务器的连接开放。

接下来,我们将使用 SSL 保护我们的安装,使用 Certbot,新的 Let's Encrypt 客户端。

步骤 2 — 安装 Let’s Encrypt 证书的 Certbot

Let's Encrypt 是一个新的服务,通过自动化 API 提供免费的 SSL 证书. 有许多客户端可以与 API 交谈,Debian 将官方客户端纳入其默认存储库,但它有点过时,缺少我们需要的一个重要功能。

相反,我们将从Debian的后备端口存储库中安装客户端,这是一个正式的存储库,使已发布的Debian版本可获得更新的软件版本,我们需要将该存储库添加到我们的APT源列表中,就像我们在上一个步骤中一样。

首先,在 /etc/apt/sources.list.d/ 中打开新文件。

1sudo nano /etc/apt/sources.list.d/backports.list

将下列行插入文件中:

1[label /etc/apt/sources.list.d/backports.list]
2deb http://mirrors.digitalocean.com/debian jessie-backports main

保存文件,然后关闭编辑器,然后更新包信息。

1sudo apt-get update

最后,安装官方的 Let’s Encrypt 客户端,称为 Certbot,告诉 APT 将jessie-backports作为其来源:

1sudo apt-get install certbot -t jessie-backports

现在我们已经安装了Certbot,让我们运行它来获得我们的证书。

步骤3 - 运行Certbot

Certbot 需要回答由 Let's Encrypt API 发布的加密挑战,以证明我们控制了我们的域名. 它使用端口 80 (HTTP) 和/或 443' (HTTPS) 来完成这项任务。

1sudo ufw allow http
1[secondary_label Output]
2Rule added
3Rule added (v6)

现在我们可以运行Certbot来获取我们的证书,我们将使用--standalone选项告诉Certbot自己处理HTTP挑战请求,而--standalone-supported-challenges http-01将通信限制到端口80

1sudo certbot certonly --standalone --standalone-supported-challenges http-01 -d mqtt.example.com

在运行命令时,您将被要求输入电子邮件地址并同意服务条款. 这样做后,您将看到一个消息,告诉您过程成功,您的证书存储在哪里。

现在我们需要确保Certbot在即将到期时自动更新它们。

步骤 4 – 设置 Certbot 自动更新

Let's Encrypt 的证书仅有效 90 天,这是为了鼓励用户自动更新证书的过程,我们需要设置一个命令,该命令会定期检查已过期的证书并自动更新它们。

為了每天執行更新檢查,我們會使用 cron,一個標準的系統服務來執行定期工作,我們會告訴 'cron'開啟和編輯名為 'crontab' 的檔案。

1sudo crontab -e

您将被要求选择文本编辑器. 选择您最喜欢的,您将被呈现的默认 crontab 其中有一些帮助文本。

1[label crontab]
2. . .
315 3 * * * certbot renew --noninteractive --post-hook "systemctl restart mosquitto"

这个行的15 3 * * *部分意味着每天下午3点15分运行以下命令。Certbot的更新命令会检查系统上安装的所有证书,并更新任何在不到30天内到期的证书。

--post-hook "systemctl restart mosquitto" 将重新启动 Mosquitto 以获取新证书,但只有在证书被更新的情况下。这个 post-hook' 功能是 Let's Encrypt 客户端的旧版本所缺少的功能,以及为什么我们从后端安装而不是默认的 Debian 存储库。如果没有它,我们将不得不每天重新启动 Mosquitto,即使没有证书实际上被更新。

现在自动更新证书已经设置,我们将回到配置Mosquitto以更安全。

步骤5:设置MQTT密码

让我们将Mosquitto配置为使用密码,以便我们可以控制谁可以发布消息。Mosquitto包含一个工具来生成一个名为mosquitto_passwd的特殊密码文件。

1sudo mosquitto_passwd -c /etc/mosquitto/passwd sammy

现在为 Mosquitto 创建一个新的配置文件,并告诉它使用此密码文件来要求所有连接的登录。

1sudo nano /etc/mosquitto/conf.d/default.conf

这应该打开一个空的文件. 粘贴如下:

1[label /etc/mosquitto/conf.d/default.conf]
2allow_anonymous false
3password_file /etc/mosquitto/passwd

allow_anonymous false禁用所有未经身份验证的连接,而password_file行告诉Mosquitto在哪里搜索用户和密码信息。

现在你需要重新启动 Mosquitto 并测试你的更改。

1sudo systemctl restart mosquitto

首先,尝试发布没有密码的消息。

1mosquitto_pub -h localhost -t "test" -m "hello world"

该信息应该被拒绝:

1[secondary_label Output]
2Connection Refused: not authorised.
3Error: The connection was refused.

在我们再次尝试使用密码之前,请再次切换到您的第二个终端窗口,并订阅 test 主题,这次使用用户名和密码:

1[environment second]
2mosquitto_sub -h localhost -t test -u "sammy" -P "password"

它应该连接并坐下来,等待消息. 您可以让这个终端打开并连接至教程的剩余时间,因为我们会定期发送测试消息。

现在,与您的其他终端发布消息,再次使用用户名和密码。

1mosquitto_pub -h localhost -t "test" -m "hello world" -u "sammy" -P "password"

我们已经成功地将密码保护添加到Mosquitto。不幸的是,我们正在通过互联网发送未加密的密码。我们将通过向Mosquitto添加SSL加密来解决此问题。

步骤 6 – 配置 MQTT SSL

要启用SSL加密,我们需要告诉Mosquitto我们的Let's Encrypt证书存储在哪里。

1sudo nano /etc/mosquitto/conf.d/default.conf

在文件的末尾插入以下内容,留下我们已经添加的两行:

1[label /etc/mosquitto/conf.d/default.conf]
2. . .
3listener 1883 localhost
4
5listener 8883
6certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
7cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
8keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem

我们将两个单独的倾听器块添加到配置中。第一个倾听器1883 localhost更新了默认的MQTT倾听器在端口1883上,这是我们迄今为止所连接的。1883是默认的未加密MQTT端口。

Listener 8883在端口8883上设置了一个加密的倾听器,这是MQTT + SSL的标准端口,通常被称为MQTTS。接下来的三个行,certfile,cafilekeyfile,都指向Mosquitto到相应的Let’s Encrypt文件来设置加密连接。

保存和退出文件,然后重新启动 Mosquitto 以更新设置。

1sudo systemctl restart mosquitto

更新防火墙以允许连接到端口8883

1sudo ufw allow 8883
1[secondary_label Output]
2Rule added
3Rule added (v6)

现在再试用mosquitto_pub,为SSL提供几种不同的选项:

1mosquitto_pub -h mqtt.example.com -t test -m "hello again" -p 8883 --capath /etc/ssl/certs/ -u "sammy" -P "password"

请注意,我们正在使用完整的主机名称而不是localhost。由于我们的SSL证书为mqtt.example.com发行,如果我们尝试安全连接到localhost,我们会收到一个错误,称主机名称不匹配证书主机名称(即使它们都指向相同的Mosquitto服务器)。

--capath /etc/ssl/certs/ 允许 SSL 用于 mosquitto_pub,并告诉您在哪里寻找根证书. 这些证书通常由您的操作系统安装,因此路径不同于 macOS、Windows 等。 mosquitto_pub 使用根证书来验证 Mosquitto 服务器的证书是否被 Let's Encrypt 证书机构正确签名。 重要的是要注意 mosquitto_pubmosquitto_sub' 不会尝试没有此选项(或类似的 cafile选项)的 SSL 连接,即使您连接到标准安全端口8883`。

如果测试顺利,你会看到在其他mosquitto_sub终端中再次出现 hello ,这意味着你的服务器已经完全设置了!如果你想扩展MQTT协议以与websockets合作,你可以按照最后一步。

步骤 7 — 配置 MQTT 通过 Web 插件(可选)

为了使用JavaScript在网页浏览器中使用MQTT进行交谈,该协议被调整为通过标准网页连接器工作。

我们需要为我们的 Mosqiutto 配置添加另一个倾听器块。

1sudo nano /etc/mosquitto/conf.d/default.conf

在文件的末尾,添加以下内容:

1[label /etc/mosquitto/conf.d/default.conf]
2. . .
3listener 8083
4protocol websockets
5certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
6cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
7keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem

这与前一个区块大多相同,除了端口号和协议网盘行之外,MQTT网盘上没有官方的标准化端口,但8083是最常见的。

保存和退出文件,然后重新启动 Mosquitto。

1sudo systemctl restart mosquitto

现在,打开防火墙中的端口8083

1sudo ufw allow 8083

要测试这个功能,我们将使用一个公共的,基于浏览器的 MQTT 客户端. 有一些在那里,但 mqtt-admin是简单和简单的。

mqtt-admin's initial screen

如下填写连接信息:

  • Protocol 应该是 wss (代表 w ebs ocket s ecure)。
  • Host 应该是您的Mosquitto服务器的域名, mqtt.example.com.
  • Port 应该是 8083.
  • 用户 应该是您的Mosquitto用户名;在这里,我们使用了 sammy .
  • Password 应该是您选择的密码。

在按下 Save Settings 后,mqtt-admin将连接到您的 Mosquitto 服务器. 在下一个屏幕上,请填写 主题 作为 测试 ,输入任何消息为 Payload ,然后按 Publish

结论

我们现在已经设置了一个安全的,密码保护的MQTT服务器,从Let's Encrypt服务自动更新SSL证书,这将作为一个强大而安全的消息传输平台,无论您梦想的项目。

  • OwnTracks,一个可在手机上安装的开源地理跟踪应用程序。OwnTracks会定期向您的MQTT服务器报告位置信息,然后您可以存储并显示在地图上,或者创建警报并根据您的位置激活物联网硬件。
  • Node-RED是一个基于浏览器的图形界面,用于连接物联网。您可以将一个节点的输出拖动到另一个节点的输入,并可以通过各种协议之间的过滤器将信息路由到数据库中,到数据库,等等。MKTT非常受Node-RED的支持。 (ESP8266)(https://espressif.com/en/products/hardware/esp8266ex/overview)是一个廉价的WiFi

这些只是MQTT生态系统中的一些受欢迎的例子,有更多的硬件和软件在外面说话协议. 如果你已经有一个最喜欢的硬件平台,或软件语言,它可能有MQTT功能。

Published At
Categories with 技术
comments powered by Disqus