在Ubuntu 16.04上安装和保护Mosquitto MQTT消息代理的方法

本文涉及的产品
云防火墙,500元 1000GB
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 在Ubuntu 16.04上安装和保护Mosquitto MQTT消息代理的方法

介绍

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

Mosquitto是一个流行的MQTT服务器(或者在MQTT术语中称为broker),它拥有强大的社区支持,并且易于安装和配置。

在本教程中,我们将安装Mosquitto,从Let’s Encrypt检索SSL证书,并设置我们的broker使用SSL来保护我们的密码保护的MQTT通信。

先决条件

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

  • 一个Ubuntu 16.04服务器,具有非root的sudo启用用户和基本防火墙设置,详细信息请参阅Ubuntu 16.04服务器设置教程。
  • 一个指向您服务器的域名,如何在DigitalOcean上设置主机名。本教程将始终使用mqtt.example.com

步骤1 — 安装Mosquitto

Ubuntu 16.04默认软件仓库中有一个相当新的Mosquitto版本。使用您的非root用户登录,并使用apt-get安装Mosquitto。

sudo apt-get install mosquitto mosquitto-clients

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

主题是您发布消息和订阅的标签。它们被安排为一个层次结构,因此您可以有传感器/外部/温度传感器/外部/湿度,例如。如何安排主题取决于您和您的需求。在本教程中,我们将使用一个简单的测试主题来测试我们的配置更改。

第二次登录服务器,这样您就可以并排拥有两个终端。在新终端中,使用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_sub相同,不过这次我们使用额外的-m选项来指定我们的消息。按下ENTER,您应该在另一个终端中看到hello world出现。您已经发送了您的第一条MQTT消息!

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

接下来,我们将使用Certbot来使用SSL保护我们的安装。

步骤2 — 安装Certbot以获取Let’s Encrypt证书

Let’s Encrypt是一个通过自动化API提供免费SSL证书的新服务。有许多客户端可以与API通信,Ubuntu在其默认仓库中包含官方客户端,但它有点过时并且缺少我们需要的一个重要功能。

相反,我们将从Ubuntu PPA(个人软件包存档)安装官方客户端。这些是打包更近期或更晦涩软件的替代存储库。首先,添加存储库。

sudo add-apt-repository ppa:certbot/certbot

您需要按ENTER接受。之后,更新软件包列表以获取新存储库的软件包信息。

sudo apt-get update

最后,安装官方Let’s Encrypt客户端,称为certbot

sudo apt-get install certbot

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

步骤3 — 运行Certbot

certbot需要回答Let’s Encrypt API发出的加密挑战,以证明我们控制我们的域。它使用端口80(HTTP)和/或443(HTTPS)来完成这一点。我们只会使用端口80,所以让我们现在允许该端口的传入流量:

sudo ufw allow http
已添加规则

现在我们可以运行Certbot来获取我们的证书。我们将使用--standalone选项告诉Certbot自行处理HTTP挑战请求,--standalone-supported-challenges http-01限制通信到端口80-d用于指定您想要证书的域,certonly告诉Certbot只获取证书而不执行任何其他配置步骤。

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

运行命令时,您将被提示输入电子邮件地址并同意服务条款。完成后,您应该看到一条消息,告诉您该过程成功,并且您的证书存储在何处。

我们已经获得了我们的证书。现在我们需要确保Certbot在证书即将到期时自动更新它们。

步骤 4 —— 设置 Certbot 自动续订

Let’s Encrypt 的证书只有九十天的有效期。这是为了鼓励用户自动化证书续订流程。我们需要设置一个定期运行的命令来检查即将过期的证书并自动续订它们。

为了每天运行续订检查,我们将使用 cron,这是一个用于运行周期性任务的标准系统服务。我们通过打开和编辑一个名为 crontab 的文件来告诉 cron 要做什么。

sudo crontab -e

系统会提示你选择一个文本编辑器。选择你喜欢的,然后会出现默认的 crontab,其中包含一些帮助文本。在文件末尾粘贴以下行,然后保存并关闭。

. . .
15 3 * * * certbot renew --noninteractive --post-hook "systemctl restart mosquitto"

这行中的 15 3 * * * 部分表示“每天凌晨 3:15 运行以下命令”。Certbot 的 renew 命令将检查系统上安装的所有证书,并更新任何设置在不到三十天后到期的证书。--noninteractive 告诉 Certbot 不要等待用户输入。

--post-hook "systemctl restart mosquitto" 将重新启动 Mosquitto 以获取新证书,但仅在证书被续订时。这个 post-hook 功能是旧版本的 Let’s Encrypt 客户端所缺少的,这也是为什么我们从 PPA 安装而不是使用默认的 Ubuntu 仓库。没有它,我们将不得不每天重新启动 Mosquitto,即使实际上没有更新任何证书。虽然你的 MQTT 客户端应该配置为自动重新连接,但明智的做法是避免每天无故中断它们。

现在自动证书续订已经设置好了,我们将继续配置 Mosquitto 以提高安全性。

步骤 5 —— 配置 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

这将打开一个空文件。粘贴以下内容:

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 加密来解决这个问题。

步骤 6 —— 配置 MQTT SSL

要启用 SSL 加密,我们需要告诉 Mosquitto 我们的 Let’s Encrypt 证书存储在哪里。打开我们之前开始的配置文件:

sudo nano /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 更新了默认的 MQTT 监听器,端口为 1883,这是我们到目前为止连接的标准未加密 MQTT 端口。localhost 部分指示 Mosquitto 仅将此端口绑定到本地主机接口,因此它不可从外部访问。外部请求本来已经被我们的防火墙阻止,但明确指定也是好的。

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

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

sudo systemctl restart mosquitto

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

sudo ufw allow 8883
Rule added

现在我们再次使用 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 的 SSL,并告诉它在哪里查找根证书。这些通常由你的操作系统安装,因此对于 Mac OS、Windows 等,路径是不同的。mosquitto_pub 使用根证书来验证 Mosquitto 服务器的证书是否由 Let’s Encrypt 证书颁发机构正确签名。重要的是要注意,即使你连接到标准的安全端口 8883,如果没有这个选项(或类似的 --cafile 选项),mosquitto_pubmosquitto_sub 将不会尝试 SSL 连接。

如果测试顺利,我们将在另一个 mosquitto_sub 终端中看到 hello again。这意味着你的服务器已经完全设置好了!如果你想扩展 MQTT 协议以使用 WebSockets,你可以按照最后一步进行操作。

第7步 — 配置 MQTT Over Websockets(可选)

为了在 web 浏览器中使用 JavaScript 来进行 MQTT 通信,该协议已经被调整以在标准的 websockets 上运行。如果您不需要这个功能,可以跳过这一步。

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

sudo nano /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 over websockets 没有官方标准化的端口,但 8083 是最常见的。

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

sudo systemctl restart mosquitto

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

sudo ufw allow 8083

为了测试这个功能,我们将使用一个公共的、基于浏览器的 MQTT 客户端。有一些选择,但 Eclipse Paho JavaScript 客户端简单且易于使用。在浏览器中打开 Paho 客户端。您将看到以下内容:

!Paho 客户端屏幕

填写连接信息如下:

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

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

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

要发布消息,导航到 Publish Message 面板,填写 Topictest,并在 Message 部分输入任何消息。然后,按下 Publish。消息将显示在您的 mosquitto_sub 终端中。

结论

我们现在已经设置了一个安全的、受密码保护的 MQTT 服务器,并从 Let’s Encrypt 服务获得了自动更新的 SSL 证书。这将为您梦想中的任何项目提供一个强大且安全的消息平台。一些与 MQTT 协议兼容的流行软件和硬件包括:

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

这些只是 MQTT 生态系统中的一些流行示例。还有更多的硬件和软件支持该协议。如果您已经有喜爱的硬件平台或软件语言,它可能已经具备了 MQTT 的功能。祝您玩得开心,让您的“物”彼此交流!


相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
8天前
|
JSON Ubuntu 开发者
ubuntu 22安装lua环境&&编译lua cjson模块
通过上述步骤,可以在 Ubuntu 22.04 系统上成功安装 Lua 环境,并使用 LuaRocks 或手动编译的方式安装 lua-cjson 模块。本文详细介绍了每一步的命令和操作,确保每一步都能顺利完成,适合需要在 Ubuntu 系统上配置 Lua 开发环境的开发者参考和使用。
41 13
|
5天前
|
监控 关系型数据库 MySQL
Ubuntu24.04安装Librenms
此指南介绍了在Linux系统上安装和配置LibreNMS网络监控系统的步骤。主要内容包括:安装所需软件包、创建用户、克隆LibreNMS仓库、设置文件权限、安装PHP依赖、配置时区、设置MariaDB数据库、调整PHP-FPM与Nginx配置、配置SNMP及防火墙、启用命令补全、设置Cron任务和日志配置,最后通过网页完成安装。整个过程确保LibreNMS能稳定运行并提供有效的网络监控功能。
|
15天前
|
Ubuntu Linux Docker
Ubuntu22.04上Docker的安装
通过以上详细的安装步骤和命令,您可以在Ubuntu 22.04系统上顺利安装
208 11
|
2月前
|
Ubuntu 开发工具 git
Ubuntu安装homebrew的完整教程
本文介绍了如何在没有公网的情况下安装 Homebrew。首先访问 Homebrew 官网,然后通过阿里云的镜像克隆安装脚本,并创建普通用户进行安装。接着修改 `install.sh` 文件指向国内镜像,执行安装命令。最后配置环境变量并更换 Homebrew 源为国内镜像,确保安装顺利。
356 50
|
2月前
|
Ubuntu
ubuntu和debian 的安装包dpkg管理命令对安装包进行安装,查询,卸载
Ubuntu dpkg 软件包管理命令概览:安装、卸载、查看和配置软件包。包括解决依赖、强制卸载、列出及过滤已安装包、查看包详情等操作。
65 10
|
2月前
|
Ubuntu API 开发工具
PSOPT在Ubuntu22.04下的安装
通过上述步骤,可以在Ubuntu 22.04下成功安装并配置PSOPT。PSOPT是一个功能强大的工具,适用于解决各种最优控制问题。确保在安装前满足系统要求,并仔细按照步骤操作,可以避免大多数常见问题。通过MATLAB与PSOPT的结合,您可以更高效地处理复杂的控制问题,并获得准确的解决方案。
37 5
|
2月前
|
Ubuntu 网络协议 关系型数据库
超聚变服务器2288H V6使用 iBMC 安装 Ubuntu Server 24.04 LTS及后续系统配置
【11月更文挑战第15天】本文档详细介绍了如何使用iBMC在超聚变服务器2288H V6上安装Ubuntu Server 24.04 LTS,包括连接iBMC管理口、登录iBMC管理界面、配置RAID、安装系统以及后续系统配置等步骤。
178 4
|
3月前
|
消息中间件 JSON Java
开发者如何使用轻量消息队列MNS
【10月更文挑战第19天】开发者如何使用轻量消息队列MNS
141 6
|
3月前
|
消息中间件 安全 Java
云消息队列RabbitMQ实践解决方案评测
一文带你详细了解云消息队列RabbitMQ实践的解决方案优与劣
107 10
|
2月前
|
消息中间件 存储 Kafka
MQ 消息队列核心原理,12 条最全面总结!
本文总结了消息队列的12个核心原理,涵盖消息顺序性、ACK机制、持久化及高可用性等内容。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。