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

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
云防火墙,500元 1000GB
简介: 在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
目录
相关文章
|
10天前
|
并行计算 Ubuntu Linux
Ubuntu学习笔记(五):18.04安装多版本CUDA
这篇博客文章介绍了在Ubuntu 18.04系统上如何安装和切换不同版本的CUDA,以及如何安装不同版本的cuDNN。
57 2
|
10天前
|
并行计算 PyTorch TensorFlow
Ubuntu安装笔记(一):安装显卡驱动、cuda/cudnn、Anaconda、Pytorch、Tensorflow、Opencv、Visdom、FFMPEG、卸载一些不必要的预装软件
这篇文章是关于如何在Ubuntu操作系统上安装显卡驱动、CUDA、CUDNN、Anaconda、PyTorch、TensorFlow、OpenCV、FFMPEG以及卸载不必要的预装软件的详细指南。
768 3
|
4天前
|
Ubuntu Linux 测试技术
Linux系统之Ubuntu安装cockpit管理工具
【10月更文挑战第13天】Linux系统之Ubuntu安装cockpit管理工具
25 4
Linux系统之Ubuntu安装cockpit管理工具
|
9天前
|
Ubuntu 应用服务中间件 nginx
Ubuntu安装笔记(三):ffmpeg(3.2.16)源码编译opencv(3.4.0)
本文是关于Ubuntu系统中使用ffmpeg 3.2.16源码编译OpenCV 3.4.0的安装笔记,包括安装ffmpeg、编译OpenCV、卸载OpenCV以及常见报错处理。
42 2
Ubuntu安装笔记(三):ffmpeg(3.2.16)源码编译opencv(3.4.0)
|
9天前
|
Ubuntu Linux C语言
Ubuntu安装笔记(二):ubuntu18.04编译安装opencv 3.4.0 opencv_contrib3.4.0
本文介绍了在Ubuntu 18.04系统上编译安装OpenCV 3.4.0及其扩展包opencv_contrib 3.4.0的详细步骤,包括下载源码、安装依赖、配置CMake和编译安装,以及常见问题的解决方法。
14 1
Ubuntu安装笔记(二):ubuntu18.04编译安装opencv 3.4.0 opencv_contrib3.4.0
|
5天前
|
Kubernetes Ubuntu Docker
从0开始搞K8S:使用Ubuntu进行安装(环境安装)
通过上述步骤,你已经在Ubuntu上成功搭建了一个基本的Kubernetes单节点集群。这只是开始,Kubernetes的世界广阔且深邃,接下来你可以尝试部署应用、了解Kubernetes的高级概念如Services、Deployments、Ingress等,以及探索如何利用Helm等工具进行应用管理,逐步提升你的Kubernetes技能树。记住,实践是最好的老师,不断实验与学习,你将逐渐掌握这一强大的容器编排技术。
17 1
|
9天前
|
Ubuntu Linux
软件安装(五):Ubuntu 18.04安装Teamviewer 看一遍就会
这篇文章介绍了在Ubuntu 18.04系统上通过图形界面和命令行两种方法安装TeamViewer远程控制软件的步骤。
16 2
|
4天前
|
消息中间件 存储 弹性计算
云消息队列RabbitMQ实践
云消息队列RabbitMQ实践
|
6天前
|
消息中间件 安全 Java
云消息队列RabbitMQ实践解决方案评测
一文带你详细了解云消息队列RabbitMQ实践的解决方案优与劣
30 4
|
10天前
|
消息中间件 存储 监控
解决方案 | 云消息队列RabbitMQ实践
在实际业务中,网站因消息堆积和高流量脉冲导致系统故障。为解决这些问题,云消息队列 RabbitMQ 版提供高性能的消息处理和海量消息堆积能力,确保系统在流量高峰时仍能稳定运行。迁移前需进行技术能力和成本效益评估,包括功能、性能、限制值及费用等方面。迁移步骤包括元数据迁移、创建用户、网络打通和数据迁移。
45 4