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 testH 用于指定 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 保护我们的安装。
Let’s Encrypt 是一个通过自动化 API 提供免费 SSL 证书的新服务。 官方的 Let’s Encrypt 客户机名为 Certbot,它包含在我们在前面步骤中安装的 EPEL 存储库中。
用 yum 安装 Certbot。
sudo yum -y install certbotCertbot 需要回答 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 在证书即将到期时自动更新它们。
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 以使其更加安全。
让我们设置蚊子使用密码。 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/passwdAllow 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 加密来解决这个问题。
要启用 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,可以按照最后一步操作。
为了在 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 功能。 让你的“东西”彼此交谈愉快!

# 设置repo
curl -sL https://deb.nodesource.com/setup_12.x | sudo bash -
# 安装Node.js
sudo apt-get install -y nodejs gcc g++ make python
# 测试node是否正常
node -v2.安装HomeBridge与HomeBridgeUI
sudo npm install -g --unsafe-perm homebridge homebridge-config-ui-x
sudo hb-service install --user homebridge3.通过Web访问HomeBridge
http://localhost:8581.
默认账号密码admin/admin
二、在LEDE上安装运行ZeroTier
1、在酷软中心安装ZeroTier插件,安装完成以后打开ZeroTier,在Network ID(网络ID)中,输入自己在ZeroTier上分配的网络,选中开启ZeroTier选项,点击开始运行按钮运行程序。
2、运行以后,修改配置文件,在终端输入以下命令:
vi /etc/config/zerotier找到以下两处进行修改:
config zerotier sample_config
option enabled 0 (这里把0替换成1,让选项生效)
list join ‘8056c2e21c000001’ (替换为自己的网络ID)
其他无需修改退出VI,按esc,然后按:(冒号)回车,再按wq保存退出编辑界面。然后输入reboot,重启。
你也可以使用WINSCP等软件直接进行修改。
3、在LEDE上点击网络->防火墙,在基本设置>区域设置里,把转发改为接受。区域下面的三行(出站,入站,转发)都选接受,其他选项保持不动。
在防火墙->自定义规则页面,增加下面三条记录:
iptables -I FORWARD -i ztc3qwyx5l -j ACCEPT
iptables -I FORWARD -o ztc3qwyx5l -j ACCEPT
iptables -t nat -I POSTROUTING -o ztc3qwyx5l -j MASQUERADEztc3qwyx5l是LEDE的ZeroTier虚拟接口的名称,在终端可以使用ifconfig命令查看,请自行替换。
设置完成后,点击重启防火墙。
三、配置ZEROTIER网络路由
在ZeroTier网络的Members部分,选中已出现的网络成员对其进行授权。稍等片刻,ZeroTier就会给每个成员分配Managed IPs(管理IP)。
在ZeroTier网络的Managed Routes(管理路由)部分,将子网与管理IP进行对应,设置路由,如下图所示。可以把多个子网都通过ZeroTier连接在一起,形成一个虚拟的局域网络。
四、测试
通过以上设置,LEDE的ZeroTier网络配置就已经完成了,可以在LEDE上PING家里的网关地址192.168.102.1,测试是否可以连通。
五、配置MOON(进阶)
MOON又称为自定义根服务器,通过自定义的服务器作为跳板加速内网机器之间的互相访问。我的LEDE版本是2.32,有固定公网IP,为了提高ZeroTier在不同子网之间互访的速度,建立MOON节点就非常有必要。
在启用ZeroTier后,我发现ZeroTier安装目录/var/lib/zerotier-one(这个目录实际链接到/var/lib/zerotier-one_sample_config)是临时目录 ,在重启后就自动删除,必须修改配置文件,才能保留MOON的配置。
1.修改配置
修改 /etc/config/zerotier,加入下面一行选项:
option config_path ‘/etc/zerotier'(注意分隔符)然后在根目录的/etc/目录下,新建zerotier目录用来存放moons的配置文件。为简化操作,可以将zerotier临时安装目录/var/lib/zerotier-one_sample_config中的所有文件复制一份到该目录中,下面所有的操作都在该目录进行。
注意:LEDE2.33的目录已修改为下面的路径,如果是从2.32保留配置升级到2.33,那么 zerotier将不能正常启动,需要重新安装和配置。
/tmp/lib/zerotier-one_sample_config2.生成MOON文件
进入ZeroTier目录:
cd /etc/zerotier运行下面两条命令:
zerotier-idtool generate identity.secret identity.public
zerotier-idtool initmoon identity.public >>moon.json在当前目录生成moon.json文件。
3.修改MOONS文件
修改 moon.json文件中”stableEndpoints” 字段为LEDE路由的公网IP,9993为端口号。
注意:LEDE2.33中生成的moon.json文件,需要把多余的签署密钥部分删除(下图绿框部分),否则不能生成签名文件。如下图所示:
4.生成签名文件
运行命令:
zerotier-idtool genmoon moon.json在当前目录下生成签名文件00000005ff20a0f6.moon
5.将MOON节点加入网络
将LEDE本机设为MOON节点。
在/etc/zerotier目录建立moons.d子目录,将生成的00000005ff20a0f6.moon复制到该文件夹中,并重启设备。
其他设备加入MOON节点方法
方法一
找到ZeroTier安装目录,新建moons.d文件夹,将00000005ff20a0f6.moon复制到该文件夹中,重启设备。
不同系统的ZeroTier安装目录位置:
Windows: C:\ProgramData\ZeroTier\One
Macintosh: /Library/Application Support/ZeroTier/One (在 Terminal 中应为 /Library/Application\ Support/ZeroTier/One)
Linux: /var/lib/zerotier-one
FreeBSD/OpenBSD: /var/db/zerotier-one方法二
在终端上执行命令:
zerotier-cli orbit 5ff20a0f66.验证测试
查看是否在MOON下运行,执行以下命令:
zerotier-cli listpeersPLANET :行星服务器,Zerotier 各地的根服务器,有日本、新加坡等地
MOON : 卫星级服务器,用户自建的私有根服务器,起到中转加速的作用
LEAF : 相当于各个枝叶,就是每台连接到该网络的机器节点
如果某一行显示有MOON字样,就证明MOON已被本机标识了。
注意:本机不能看自己,所以只能在别的设备上看。