翻译:如何在Ubuntu16.04上安装Mosquitto这个MQTT消息服务器并对其进行安全配置

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了翻译:如何在Ubuntu16.04上安装Mosquitto这个MQTT消息服务器并对其进行安全配置相关的知识,希望对你有一定的参考价值。

原文地址: https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-the-mosquitto-mqtt-messaging-broker-on-ubuntu-16-04

简介

MQTT是一个在机器和机器之间传递消息的协议,为实现物联网设备间轻量级的发布/订阅通信而设计。广泛应用于汽车地理位置追踪,智能家居自动化,环境传感网络,以及各项公共事业的数据收集。

Mosquitto是一个流行的MQTT服务器(在MQTT协议中叫中继器),拥有强大的社区支持,易于安装、配置。

在此教程中,我们将安装Mosquito,从Let‘s Encrypt获取证书,搭建我们自己的中继器,采用密码认证,采用SSL来确保MQTT通信安全。

前提条件

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

步骤1 安装Mosquitto

Ubuntu16.04默认软件仓库的Mosquitto版本就挺新的。用你的非root用户登录并使用 apt-get安装Mosquitto.

$ sudo apt-get install mosquitto mosquitto-clients

默认情况下,Ubuntu会在安装后启动Mosquitto服务。我们先测试一下默认配置。使用刚安装的Mosquitto客户端订阅中继器上的一个主题。

主题是发送和订阅消息的标签。它们按层次设置,比如你可以将主题设置为sensors/outside/tempsensors/outside/humidity。如何设置主题取决于的你需要。教程通篇将用一个简单的主题test来测试配置变化。

再打开一个服务器命令窗口,这样你就有两个并列的窗口了。在新的命令行中,使用mosquitto_sub来订阅test主题:

mosquitto_sub -h localhost -t test

-h用于指定MQTT服务器的主机名,-t用于指定主题。当按下回车键之后,没有任何输出,这是因为mosquitto_sub正在等待消息送达。回到另外一个命令行,发布一条消息:

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

mosquitto_pub的选项和mosquitto_sub的一样,除了这次我们用了一个-m选项来指定消息内容。按下回车,将会看到Hello world在另外一个命令行中出现。你刚刚发送了你的第一条MQTT消息。

在第二个命令行输入CTRL + C,退出mosquitto_sub, 但保持和服务器的连接。在步骤五将再次使用到它。

接下来,我们将用通过Certbot的SSL来确保我们Mosquitto的安全,Certbot是Let‘s Encrypt的新版客户端。

步骤2 为了获得Let‘s Encrypt证书,安装Certbot

Let‘s Encrypt是一个通过自动化的API,提供免费的SSL证书的服务。很多客户端可以调用这个API。Ubuntu的默认仓库包含了官方的客户端,但有点过时了,并且缺少了一个我们需要的新特性。

因此,我们从一个Ubuntu PPA(Personal Package Archive)安装官方的客户端。很多替代仓库的打包了更新的版本,或者是小众软件。首先,添加仓库:

sudo add-apt-respository ppa:certbot/certbot

需要敲一下回车来接受安装。接下来,更新包列表来获取新仓库的包信息。

sudo apt-get update

最后,安装Let‘s Encrypt的官方客户端,叫做certbot

sudo apt-get install certbot

certbot已经安装完成,接下来运行它来获得我们所需的证书。

步骤3 运行Certbot

certbot需要响应一个Let‘s Encrypt发出的密码质询,用来证明我们对这个域名有控制权。它使用端口80(HTTP) 且/或 443(HTTPS)来完成。我们将仅使用端口80,所以我们需要在这个端口上允许入网流量。

$ sudo ufw allow http
Rule added

现在我们可以运行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

运行上述命令时,命令行会提示你输入一个邮箱地址,并同意服务条款。再之后,你将会看到一条消息,告诉你处理成功,并且告知你证书的存放位置。

我们已经获得了证书,现在我们需要确保Certot在证书快过期时自动地更新他们。

步骤4 创建Certbot的自动更新策略

Let‘s Encrypt的证书有效期仅为90天。这是为了鼓励用户将他们的证书更新流程自动化。我们将创建一个定期运行的命令,检查证书过期情况并自动更新它们。

我们将通过cron每天运行更新检查。这是运行周期性工作的一个系统服务。打开并编辑一个叫做crontab的文件,来指定cron要完成的工作。

sudo crontab -e

你将会看到选择一个文本编辑器的提示。选一个你喜欢的,然后将会看到默认的corontab, 并且附带一个帮助说明。在文件的最后加入下面这一行,保存并关闭文件。

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

15 3 * * *表示每天上午3点15运行后面的命令。Certbot的renew命令会检查服务器上安装的所有证书,并更新那些过期时间不足30天的。--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"

这条消息会被拒绝:

Output
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增加了密码保护功能。不幸的是,我们发送密码的时候未进行加密。我们接下来将通过增加SSL加密来解决这一问题。

步骤6 配置MQTT的SSL

为开启SSL加密,需要在Mosquitto配置里制定证书存放的位置。打开刚才开始的配置文件:

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,更新了处于端口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

接下来,使用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/certsmosquitto_pub启动了SSL,并指定了去何处寻找根证书。这些证书被你的操作系统安装在特定的位置,所以这个地址在MacOS、Windows等系统上是不一样的。mosquitto_pub采用根证书来来检查Mosquitto服务器的证书是否是否被Let‘s Encrypt的证书授权机构认证过。有一点需要注意的是,没有这个选项,mosquitto_pubmosquitto_sub是不会尝试使用SSL链接的,即使你尝试连接到一个标准的安全端口8883。一个类似的选项为--cafile

如果测试顺利的话,会看到hello again出现在命令行中。到这里,意味着已经完成了服务器搭建!如果你对拓展MQTT协议,使其可以基于websocket协议工作的话,请参考下面最终一步。

步骤7 配置通过WebSockets来使用MQTT(可选)

为了在web浏览器中通过javascript调用MQTT,协议通过适配,可以支持标准的WebSockets。如果你不需要这项功能,可以跳过此步骤。

我们需要在配置文件添加一个新的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那一行。对于通过websockets方式提供的MQTT服务,没有官方的标准。但8083是最常用的。

保存并退出这个文件,然后重启Mosquitto。

sudo systemctl restart mosquitto

接下来,在防火墙开启8083端口。

sudo ufw allow 8083

为测试此功能,需要用到一个公开的,基于浏览器的MQTT客户端。这种客户端有很多,但mqtt-admin是最简单直接的。在浏览器打开mqtt-admin。将会看到设置窗口。

填入如下连接信息:

  • Protocol选择wss(websocket secure)。
  • Host填入Mosquitto服务器的域名。
  • Port填入8083
  • User填入Mosquitto的用户名。
  • Password填入你设置的密码。
  • ClientID保持默认。

点击保存设置之后,mqtt-admin会连接到Mosquitto服务器。接下来,在Topic处填入test,在Payload处填入任意信息,然后点击Publish。将会在mosquitto_sub命令行显示消息。

结语

到现在为止,我们已经建立起了一个安全,有密码保护机制的MQTT服务器,并设置了从Let‘s Encrypt服务自动更新SSL证书的方法。这对于你未来的任何项目都能够提供稳健和安全的消息平台。一些流行的软件和硬件在MQTT协议下运转良好:

  • OwnTracks, 是一个开源的地理位置追踪APP。OwnTracks会定期向服务器报告位置信息。随后你可以存储并将这些信息展示在底图上,创建警报器,基于地理位置激活你的物联网设备。
  • Node-RED, 一个基于浏览器的图形界面,用于将物联网设备连接起来。可以将一个节点的输出连接到另一个节点的输入上,并可以通过过滤器在不同的协议之间路由信息。存入数据库等等。
  • ESP8266是一个便宜的WiFi微控制器,并具备MQTT能力。可以通过它发布温度信息到一个主题上,或者可以订阅大气压主题再或者当暴风雨来临时让蜂鸣器响起来。

这仅是MQTT生态系统的一部分知名案例。有更多的一些硬件或者软件采用了这种协议。如果你已经有了一个自己喜爱的硬件平台,或者软件编程语言,它可能就已经具备了MQTT能力。在让你的“物”彼此通信的过程中享受乐趣吧。

以上是关于翻译:如何在Ubuntu16.04上安装Mosquitto这个MQTT消息服务器并对其进行安全配置的主要内容,如果未能解决你的问题,请参考以下文章

如何在 linux ubuntu 16.04 上安装 SDK 管理器?

text 如何在Ubuntu 16.04上安装GeckoDriver

markdown 如何在ubuntu 16.04上安装虚拟环境

如何在 ubuntu 16.04 机器上安装和配置 HSQL DB

如何在运行 Virtualmin 控制面板的 ubuntu 16.04 上安装 php 5.6

如何在同一台机器上安装 Windows Server 2012 和 Ubuntu 16.04 桌面