CentOS 7上安装和保护 MQTT 的 mosquito

TAIDONG 2020-06-18 PM 2375℃ 0条

引言

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

Mosquito 是一个流行的 MQTT 服务器(或者用 MQTT 的说法是代理) ,它有很好的社区支持,并且易于安装和配置。

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

先决条件

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

设置了一个 CentOS 7服务器,该服务器具有一个非 root、支持 sudo 的用户和一个基本的防火墙。 新 CentOS 7服务器检查列表中包含了所有这些(以及更多)。
一个域名指向你的服务器,就像如何用 DigitalOcean 设置主机名一样。 本教程将在整个过程中使用 mqtt.example.com。
还可以选择使用纳米文本编辑器。 本教程将使用 nano 贯穿始终,你可以在任何时候用 sudo yum-y 安装 nano 安装它,或者替换你喜欢的文本编辑器。

第一步ー安装蚊子

缺省情况下 CentOS 7没有一个需要打包的蚊子。 为了安装它,我们将首先安装一个额外的 Linux 软件资源库,称为企业 Linux 的额外软件包,或者称为 EPEL。 这个存储库充满了可以很好地安装在 CentOS、 Red Hat 和其他面向企业的 Linux 发行版上的附加软件。

使用非 root 用户登录并使用 yum 包管理器安装 epel-release 包。

sudo yum -y install epel-release

这将向我们的系统添加 EPEL 存储库信息。 Y 选项会自动对整个过程中的几个提示回答 yes。 现在我们可以安装蚊子包。

sudo yum -y install mosquitto

这个包有一个简单的默认配置,所以让我们运行它来测试我们的安装。

sudo systemctl start mosquitto

我们还需要启用该服务,以确保在重新启动系统时启动:

sudo systemctl enable mosquitto

现在让我们测试默认配置。 Mosquito 包附带了一些命令行 MQTT 客户机。 我们将使用其中一个订阅我们代理的主题。

主题是发布邮件到并订阅的标签。 它们被安排成一个层次结构,例如,你可以有传感器 / 外部 / 温度和传感器 / 外部 / 湿度。 如何安排话题取决于你自己和你的需要。 在本教程中,我们将使用一个简单的测试主题来测试我们的配置更改。

第二次登录到您的服务器,这样您就有两个并排的终端。 在新的终端,使用蚊子子订阅测试主题:

mosquitto_sub -h localhost -t test

H 用于指定 MQTT 服务器的主机名,-t 是主题名。 你会看到没有输出后,按下 ENTER,因为蚊子子正在等待消息到达。 切换回你的另一个终端并发布一条消息:

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

蚊子到酒吧的选项是相同的蚊子到次,虽然这一次我们使用额外的-m 选项,以指定我们的信息。 点击回车,你应该会看到 hello world 在另一个终端弹出。 您已经发送了您的第一条 MQTT 消息!

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

接下来,我们将使用 Certbot (新的 Let’s Encrypt 客户机)使用 SSL 保护我们的安装。

步骤2ー为 Let’s Encrypt 证书安装和运行 Certbot

Let’s Encrypt 是一个通过自动化 API 提供免费 SSL 证书的新服务。 官方的 Let’s Encrypt 客户机名为 Certbot,它包含在我们在前面步骤中安装的 EPEL 存储库中。

用 yum 安装 Certbot。

sudo yum -y install certbot

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

使用 firewall-cmd 添加 HTTP 服务。

sudo firewall-cmd --permanent --add-service=http

重新装载防火墙,使更改生效。

sudo firewall-cmd --reload

我们现在可以运行 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 在证书即将到期时自动更新它们。

第三步: 建立 Certbot 自动更新系统

Let’s Encrypt 的证书只有90天的有效期。 这是为了鼓励用户自动化他们的证书更新过程。 我们需要设置一个定期运行的命令来检查到期证书并自动更新它们。

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

sudo EDITOR=nano crontab -e

将在 nano 编辑器中打开 crontab 文件。 如果您喜欢使用缺省的 vi 编辑器,请关闭它。

现在应该显示默认的 crontab,一个空白文件。 粘贴下面的行,然后保存并关闭文件。

crontab

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

这一行的153 * 部分表示“每天凌晨3:15运行以下命令”。 Certbot 的续订命令将检查系统上安装的所有证书,并更新任何设置为在30天内过期的证书。 -- 非交互式告诉 Certbot 不要等待用户输入。

-- post-hook“ systemctl restart mosquito”将重启 Mosquitto 以获得新的证书,但前提是证书必须更新。

现在已经设置了自动证书更新,我们将继续配置 mosquito 以使其更加安全。

第四步ー设定 MQTT 密码

让我们设置蚊子使用密码。 Mosquito 包含一个工具,可以生成一个名为 mosquito passwd 的特殊密码文件。 这个命令将提示您输入指定用户名的密码,并将结果放在 / etc / mosquito / passwd 中。

sudo mosquitto_passwd -c /etc/mosquitto/passwd sammy

现在我们将替换默认的配置文件,并告诉 mosquito 使用这个密码文件要求所有连接都登录。 首先,删除现有的 mosquito. conf。

sudo rm /etc/mosquitto/mosquitto.conf

现在打开一个新的空白配置。

sudo nano /etc/mosquitto/mosquitto.conf

粘贴到下面。

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

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

现在我们需要重新启动 mosquito 并测试我们的变化。

sudo systemctl restart mosquitto

尝试在没有密码的情况下发布消息。

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

这个信息应该被拒绝:

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

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

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

步骤5ー配置 MQTT SSL

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

sudo nano /etc/mosquitto/mosquitto.conf

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

/etc/mosquitto/mosquitto.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

我们在配置中添加了两个独立的侦听器块。 第一个是侦听器1883 localhost,它在端口1883上更新缺省的 MQTT 侦听器,到目前为止我们一直连接到这个端口。 1883是标准的未加密 MQTT 端口。 该行的 localhost 部分指示 Mosquitto 只将该端口绑定到 localhost 接口,因此外部无法访问该端口。 外部请求无论如何都会被我们的防火墙阻止,但是显式的请求是好的。

监听器8883在8883端口设置了一个加密监听器。 这是 MQTT + SSL 的标准端口,通常称为 MQTTS。 接下来的三行代码 certfile、 cafile 和 keyfile 都将 mosquito 指向适当的 Let’s Encrypt 文件以设置加密连接。

保存并退出文件。

在重新启动 mosquito 以加载新配置之前,我们需要修复默认 mosquito 服务文件中的一个内容。 这是 systemd 用来确定如何运行蚊子的文件。 用你最喜欢的编辑器打开它。

sudo nano /etc/systemd/system/multi-user.target.wants/mosquitto.service

寻找一行,说用户蚊子和删除它,然后保存和退出文件。

Mosquito 仍将作为蚊子对用户运行,但当它第一次启动时,它将拥有 root 特权,并将能够加载我们的 Let’s Encrypt 证书(出于安全原因,这些证书仅限于 root 访问)。 加载证书后,它将下降到蚊子用户。

我们需要重新加载 systemd 本身,这样它就会注意到我们对服务文件所做的更改。

sudo systemctl daemon-reload

现在我们可以重新启动 mosquito 来更新设置。

sudo systemctl restart mosquitto

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

sudo firewall-cmd --permanent --add-port=8883/tcp

重新装载防火墙。

sudo firewall-cmd --reload

现在我们再次使用蚊子到酒吧进行测试,使用一些不同的 SSL 选项。

mosquitto_pub -h mqtt.example.com -t test -m "hello again" -p 8883 --cafile /etc/ssl/certs/ca-bundle.crt -u "sammy" -P "password"

注意,我们使用的是完整的主机名而不是本地主机。 因为我们的 SSL 证书是为 mqtt.example.com 服务器颁发的,如果我们尝试一个到本地主机的安全连接,我们会得到一个错误,说主机名与证书主机名不匹配(即使它们都指向同一个 mosquito 服务器)。

-- cafile / etc / ssl / certs / ca-bundle. Crt 启用 SSL for mosquito to pub,并告诉它在哪里寻找根证书。 这些通常是由你的操作系统安装的,所以 Mac OS,Windows 等系统的路径是不同的。 蚊子酒吧使用加密根证书来验证蚊子酒吧服务器的证书是否由 Let’ s Encrypt 认证机构正确签署。 需要注意的是,如果没有这个选项(或类似的 capath 选项) ,mosquito to pub 和 mosquito to sub 将不会尝试 SSL 连接,即使您连接到标准的安全端口8883。

如果一切顺利的测试,我们将看到 hello 再次出现在其他次终端的蚊子。 这意味着您的服务器已经完全设置好了! 如果希望扩展 MQTT 协议以使用 websocket,可以按照最后一步操作。

步骤6ー通过 Websockets 配置 MQTT (可选)

为了在 web 浏览器中使用 JavaScript 来说明 MQTT,该协议被调整为可以在标准的 websocket 上工作。 如果你不需要这个功能,你可以跳过这一步。

我们需要添加一个更多的侦听器块到我们的蚊子配置。

sudo nano /etc/mosquitto/mosquitto.conf

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

/etc/mosquitto/mosquitto.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 websocket 行之外,这基本上与前一个块相同。 在 websockets 上没有 MQTT 的官方标准化端口,但8083是最常见的。

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

sudo systemctl restart mosquitto

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

sudo firewall-cmd --permanent --add-port=8083/tcp

再最后一次重新装载防火墙。

sudo firewall-cmd --reload

为了测试这个功能,我们将使用一个公共的、基于浏览器的 MQTT 客户机。 现在已经有了一些,但是 mqtt-admin 非常简单和直接。 在浏览器中打开 mqtt-admin。 你会看到以下内容:

填写连接信息如下:

协议应该是 wss (即 web socket secure)。
主机应该是你的 mosquito 服务器的域名, mqtt.example.com。
端口应该是8083。
用户名应该是你的蚊子用户名,在这里,我们使用 sammy。
密码应该是您选择的密码。
Clientid 可以保留为默认值 mqtt-admin。
按下保存设置后,mqtt-admin 将连接到您的 mosquito 服务器。 在下一个屏幕中,填写 Topic 作为测试,输入任何有效负载的消息,然后按 Publish。 该信息将显示在蚊子子子终端。

总结

现在,我们已经设置了一个安全的、受密码保护的 MQTT 服务器,该服务器具有来自 Let’s Encrypt 服务的自动更新 SSL 证书。 这将为您构想的任何项目提供一个健壮和安全的消息传递平台。 一些流行的软件和硬件可以很好地与 MQTT 协议协同工作,包括:

Owntracks,一个开源的地理追踪应用,你可以安装在你的手机上。 将定期向你的 MQTT 服务器报告位置信息,然后你可以将这些信息存储并显示在地图上,或者根据你的位置创建警报并激活物联网硬件。
Node-red 是一个基于浏览器的图形界面,用于“连接”物联网。 您可以将一个节点的输出拖动到另一个节点的输入,并且可以通过过滤器、在各种协议之间将信息路由到数据库中,等等。 Mqtt 非常好地支持 Node-RED。
Esp8266是一个便宜的带有 MQTT 功能的 wifi 微控制器。 你可以连接一个来发布一个主题的温度数据,或者订阅一个气压主题,当暴风雨来临时发出蜂鸣器!
这些只是 MQTT 生态系统中的一些流行示例。 还有更多的硬件和软件能够说明这个协议。 如果您已经有了最喜欢的硬件平台或软件语言,那么它可能具有 MQTT 功能。 让你的“东西”彼此交谈愉快!

标签: MQTT

非特殊说明,本博所有文章均为博主原创。

评论啦~


选择表情