如何在Ubuntu 18.04上安装和保护Mosquitto MQTT Messaging Broker

MQTT是一种机器到机器的消息传递协议,旨在为“物联网”设备提供轻量级的发布/订阅通信。 Mosquitto是一种流行的MQTT服务器(或MQTT中的代理),具有出色的社区支持,易于安装和配置。在本教程中,我们将安装Mosquitto,从Let的加密中检索SSL证书,并设置我们的代理使用SSL来保护受密码保护的MQTT通信。

介绍

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

Mosquitto是一种流行的MQTT服务器(或MQTT中的代理 ),具有出色的社区支持,易于安装和配置。

在本教程中,我们将安装Mosquitto并设置我们的代理以使用SSL来保护受密码保护的MQTT通信。

先决条件

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

第1步 - 安装Mosquitto

Ubuntu 18.04在其默认软件存储库中有一个相当新版本的Mosquitto,因此我们可以从那里安装它。

首先,使用非root用户登录并使用apt update包列表:

sudo apt update

现在,使用apt install安装Mosquitto:

sudo apt install mosquitto mosquitto-clients

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

主题是您向其发布消息和订阅的标签。 它们按层次排列,因此您可以使用sensors/outside/tempsensors/outside/humidity 您如何安排主题取决于您和您的需求。 在本教程中,我们将使用一个简单的测试主题来测试我们的配置更改。

第二次登录到您的服务器,因此您有两个并排的终端。 在新终端中,使用mosquitto_sub订阅测试主题:

mosquitto_sub -h localhost -t test

-h用于指定MQTT服务器的主机名, -t是主题名称。 点击ENTER后你会看到没有输出,因为mosquitto_sub正在等待消息到达。 切换回您的其他终端并发布消息:

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

mosquitto_pub的选项与mosquitto_pub相同,但这次我们使用额外的-m选项来指定我们的消息。 点击ENTER ,你应该看到另一个终端弹出hello world 您已发送了第一条MQTT消息!

在第二个终端输入CTRL+C以退出mosquitto_sub ,但保持与服务器的连接打开。 我们将在第5步中再次使用它进行另一次测试。

接下来,我们将使用基于密码的身份验证来保护我们的安装。

第2步 - 配置MQTT密码

让我们配置Mosquitto使用密码。 Mosquitto包含一个生成名为mosquitto_passwd的特殊密码文件的实用程序。 此命令将提示您输入指定用户名的密码,并将结果放在/etc/mosquitto/passwd

sudo mosquitto_passwd -c /etc/mosquitto/passwd sammy

现在我们将为Mosquitto打开一个新配置文件,并告诉它使用此密码文件来要求所有连接的登录:

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

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

/etc/mosquitto/conf.d/default.conf
allow_anonymous false
password_file /etc/mosquitto/passwd

请务必在文件末尾留下尾随换行符。

allow_anonymous false将禁用所有未经过身份验证的连接, password_file行告诉Mosquitto在哪里查找用户和密码信息。 保存并退出该文件。

现在我们需要重启Mosquitto并测试我们的更改。

sudo systemctl restart mosquitto

尝试发布没有密码的邮件:

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

该邮件应被拒绝:

Connection Refused: not authorised.
Error: The connection was refused.

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

mosquitto_sub -h localhost -t test -u "sammy" -P "password"

它应该连接并坐下,等待消息。 您可以将本终端打开并连接到本教程的其余部分,因为我们会定期发送测试消息。

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

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

该消息应该按照第1步进行。我们已经成功地为Mosquitto添加了密码保护。 不幸的是,我们通过互联网发送未加密的密码。 我们将通过向Mosquitto添加SSL加密来解决下一步问题。

第3步 - 配置MQTT SSL

要启用SSL加密,我们需要告诉Mosquitto存储Let的加密证书的位置。 打开我们之前启动的配置文件:

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

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

/etc/mosquitto/conf.d/default.conf
. . .
listener 1883 localhost

listener 8883
certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem

同样,请务必在文件末尾留下尾随换行符。

我们在配置中添加了两个单独的listener块。 第一个, listener 1883 localhost ,更新端口1883上的默认MQTT监听器,这是我们到目前为止所连接的。 1883是标准的未加密MQTT端口。 该行的localhost部分指示Mosquitto仅将此端口绑定到localhost接口,因此无法从外部访问它。 无论如何,我们的防火墙都会阻止外部请求,但明确是好的。

listener 8883在端口8883上设置加密监听器。 这是MQTT + SSL的标准端口,通常称为MQTTS。 接下来的三行, certfilecafilekeyfile ,都将Mosquitto指向相应的Let's Encrypt文件以设置加密连接。

保存并退出该文件,然后重新启动Mosquitto以更新设置:

sudo systemctl restart mosquitto

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

sudo ufw allow 8883
Rule added
Rule added (v6)

现在我们使用mosquitto_pub再次测试,有几个不同的SSL选项:

mosquitto_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/mosquitto_pub启用S​​SL,并告诉它在哪里查找根证书。 这些通常由您的操作系统安装,因此Mac OS,Windows等的路径不同mosquitto_pub使用根证书来验证Mosquitto服务器的证书是否由Let的加密证书颁发机构正确签名。 重要的是要注意, mosquitto_pub没有此选项(或类似的--cafile选项), mosquitto_pubmosquitto_sub将不会尝试SSL连接,即使您连接到8883的标准安全端口也是如此。

如果测试结果一切正常,我们会再次看到hello出现在另一个mosquitto_sub终端中。 这意味着您的服务器已完全设置好! 如果您想扩展MQTT协议以使用websockets,您可以按照最后一步操作。

第4步 - 通过Websockets配置MQTT(可选)

为了在Web浏览器中使用JavaScript来说MQTT,该协议适用于标准websockets。 如果您不需要此功能,则可以跳过此步骤。

我们需要在Mosquitto配置中再添加一个listener块:

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

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

/etc/mosquitto/conf.d/default.conf
. . .
listener 8083
protocol websockets
certfile /etc/letsencrypt/live/mqtt.example.com/cert.pem
cafile /etc/letsencrypt/live/mqtt.example.com/chain.pem
keyfile /etc/letsencrypt/live/mqtt.example.com/privkey.pem

同样,请务必在文件末尾留下尾随换行符。

除了端口号和protocol websockets行之外,这与前一个块大致相同。 MQTT在websockets上没有官方标准化端口,但8083是最常见的。

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

sudo systemctl restart mosquitto

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

sudo ufw allow 8083

要测试此功能,我们将使用基于浏览器的公共MQTT客户端。 有一些,但Eclipse Paho JavaScript Client简单易用。 在浏览器中打开Paho客户端 你会看到以下内容:

Paho客户端屏幕

填写连接信息如下:

  • 主机应该是您的Mosquitto服务器的域, mqtt.example.com
  • 端口应为8083
  • ClientId可以保留为默认值js-utility-DI1m6
  • 路径可以保留为默认值/ ws
  • 用户名应该是您的Mosquitto用户名; 在这里,我们使用了sammy
  • 密码应该是您选择的密码。

其余字段可以保留其默认值。

按下Connect后 ,基于Paho浏览器的客户端将连接到您的Mosquitto服务器。

要发布消息,请导航到“ 发布消息”窗格,将“ 主题”填写为“ 测试” ,然后在“ 消息”部分中输入任何消息。 接下来,按发布 该消息将显示在您的mosquitto_sub终端中。

结论

我们现在已经建立了一个安全的,受密码保护且受SSL保护的MQTT服务器。 这可以作为您梦寐以求的任何项目的强大而安全的消息传递平台。 一些与MQTT协议配合良好的流行软件和硬件包括:

  • OwnTracks ,一款可以在手机上安装的开源地理跟踪应用。 OwnTracks将定期向您的MQTT服务器报告位置信息,然后您可以将其存储并显示在地图上,或根据您的位置创建警报并激活IoT硬件。
  • Node-RED是一个基于浏览器的图形界面,用于将物联网“连接”在一起。 您将一个节点的输出拖动到另一个节点的输入,并可以通过过滤器,各种协议之间,数据库等信息路由信息。 Node-RED非常支持MQTT。
  • ESP8266是一款具有MQTT功能的廉价wifi微控制器。 您可以连接一个以将温度数据发布到主题,或者可能订阅气压主题并在风暴来临时发出蜂鸣声!

这些只是MQTT生态系统中的一些流行示例。 有更多的硬件和软件可以说协议。 如果您已经拥有最喜欢的硬件平台或软件语言,它可能具有MQTT功能。 玩得开心让你的“事情”互相交流!