Container - mosquitto MQTT server
本页介绍如何使用 MikroTik RouterOS 容器为 IoT 应用运行 eclipse-mosquitto MQTT 服务器,详细说明容器设置步骤,包括网络、环境变量和挂载,并带有 SSL 支持相关警告。
容器 - mosquitto MQTT 服务器
简介
容器功能引入 RouterOS,使得在路由器内运行各种任务所需的各种服务器成为可能。这对于希望减少网络中设备数量的人尤其相关。与其在单独的设备/机器上运行服务器,何不在路由器内部运行呢?
在本指南中,我们将展示如何安装一个名为 eclipse-mosquitto 的基本 MQTT broker(换句话说,服务器)。MQTT 协议是一个非常流行的选择,尤其是在 IoT 拓扑中。它是一种开放的 OASIS 和 ISO 标准轻量级发布-订阅网络协议,用于在设备之间传输消息。典型的拓扑由 MQTT 发布者(发送信息的设备)、MQTT broker(存储数据的服务器)和 MQTT 订阅者(监听服务器上发布数据的设备)组成。
RouterOS 支持 MQTT 发布、订阅功能,而现在我们也可以运行 MQTT broker。
我们即将使用的镜像可以通过 hub.docker 链接找到。
概要
在继续配置之前,请务必研究我们的容器指南。请务必查看免责声明和要求部分,了解所有风险以及你可能需要采取的必要步骤。
你可以通过链接找到支持的架构。
在本指南发布时,eclipse-mosquitto 镜像可用于 ARM32、ARM64 和 AMD64(CHR 和 x86)设备。在本示例中,我们将在 ARM32 架构设备上运行它 → RB1100AHx4。
警告
将展示非常基础且快速的配置。请务必查看 mosquitto 文档页面,了解你可以实现的其他选项和设置的更多信息。如果你想将其用于生产环境,请务必以任何可能的方式加固安全性:
- 防火墙,以便仅允许来自你信任的 IP 地址访问容器;
- 从 mosquitto broker/服务器端提高安全性 → 使用强密码、非标准端口等;
- 使用 SSL MQTT。
容器配置
子菜单: /container
note: 需要 container 软件包。
容器模式
启用容器模式:
/system/device-mode/update container=yes
如果在 X86 上使用容器,你需要通过按下复位按钮或冷重启来确认 device-mode。
网络
为容器添加 veth 接口:
/interface/veth/add name=veth2 address=172.19.0.2/24 gateway=172.19.0.1
为容器创建网桥并将 veth 添加到其中:
/interface/bridge/add name=msqt
/ip/address/add address=172.19.0.1/24 interface=msqt
/interface/bridge/port/add bridge=msqt interface=veth2
如果需要 NAT(可选),为测试目的转发 TCP 1883 端口用于非 SSL MQTT(其中 192.168.88.1 是设备的 LAN IP 地址):
/ip/firewall/nat/add action=dst-nat chain=dstnat dst-address=192.168.88.1 dst-port=1883 protocol=tcp to-addresses=172.19.0.2 to-ports=1883
环境变量和挂载
按照 eclipse-mosquitto docker hub,为配置文件定义挂载。我们将不仅挂载配置文件,而是挂载整个文件夹,因为对于 SSL MQTT,我们还需要将证书上传到该文件夹:
/container/mounts/add list=msqt_config src=/mosquitto_mounted dst=/mosquitto/config
获取镜像
为简化配置,我们将从外部镜像库获取镜像,但你也可以通过 .tar 文件导入。
在本示例中,我们将使用设备自带的存储。RB1100AHx4 有 128 MB 磁盘空间,而基本的 mosquitto 安装占用的空间不应超过约 15 MB。
请确保你已相应设置 "Registry URL"、限制 RAM 使用量(如有必要),并为镜像设置一个目录:
/container/config/set registry-url=https://registry-1.docker.io tmpdir=pull
拉取镜像
/container/add remote-image=library/eclipse-mosquitto:latest interface=veth2 root-dir=mosquitto mountlists=msqt_config logging=yes
运行命令后,RouterOS 应开始 "extracting"(解压)软件包。检查 "File System" 中新建的文件夹,并使用命令 /container/print 监控容器状态。
设置 mosquitto 配置文件
要获取 mosquitto.conf 文件,我们需要使用 SFTP(基于 SSH 的文件传输)协议,因此请确保 SSH 服务已启用。你也可以使用 FTP。
打开你的命令终端(Windows 用户以管理员身份打开 "CMD",Linux 用户打开 "Linux Shell 或命令终端"),并导航到你希望下载配置文件的目录。例如,到你 "桌面" 上的 "Container" 文件夹:
C:\WINDOWS\system32>cd C:\Users\Administrator\Desktop\Container
C:\Users\Administrator\Desktop\Container>
向设备的 IP 地址发起 SFTP 连接:
C:\Users\Administrator\Desktop\Container>sftp admin@192.168.88.1
The authenticity of host '192.168.88.1 (192.168.88.1)' can't be established.
RSA key fingerprint is SHA256:lfxxs+xMrXlvP7hiHi9ZAEZlPi6/c5US+r6J7ljhkaA.
Are you sure you want to continue connecting (yes/no/[fingerprint])?yes
Warning: Permanently added '192.168.88.1' (RSA) to the list of known hosts.
Connected to 192.168.88.1.
sftp>
转到 mosquitto 配置文件所在文件夹(使用 dir 或 ls 命令查看当前所在文件夹的内容,使用 cd 命令转到你选择的文件夹)。默认情况下,配置从 "/mosquitto/config/mosquitto.conf" 加载,因此导航到那里并使用 get 命令下载它:
sftp> cd mosquitto/mosquitto/config
sftp> dir
mosquitto.conf
sftp> get mosquitto.conf
Fetching /mosquitto/mosquitto/config/mosquitto.conf to mosquitto.conf
/mosquitto/mosquitto/config/mosquitto.conf
通过你常用的文本编辑器(Notepad 或其他)打开 "mosquitto.conf",并用下面显示的两行覆盖它:
警告
在本节中,我们将为测试目的配置一个基本的非 SSL MQTT 设置。除非你确信所需的安全性/限制措施已经到位,否则非 SSL MQTT 对于生产环境并不安全。
对于生产环境,在可以捕获/嗅探 MQTT 流量的拓扑中,和/或将 MQTT 流量直接经由互联网路由(非本地)的拓扑中,请使用 SSL MQTT。查看 SSL MQTT 一节 获取更多信息。
listener 1883
allow_anonymous true
- 第一行 listener 1883 将使安装程序监听指定端口上的传入网络连接。
- 第二行 allow_anonymous true 决定是否允许不提供用户名即可连接的客户端进行连接。
使用相同的 mosquitto.conf 名称覆盖该文件。
在你创建了自己的自定义配置文件后,将其上传到已挂载的目录/文件夹 "mosquitto_mounted"。如果你还没有运行过容器,你将没有 "mosquitto_mounted" 文件夹,可以手动创建它。如果你运行过(/container/start 0),它应该已经自动创建:
sftp> dir
mosquitto mosquitto_mounted pub pull skins
从编辑后的 mosquitto.conf 文件所在目录使用 SFTP,并将其 put 到已挂载的目录:
C:\Users\Administrator\Desktop\Container>dir
Directory of C:\Users\Administrator\Desktop\Container
02/03/2023 12:09 PM <DIR> .
02/03/2023 12:09 PM <DIR> ..
02/03/2023 12:09 PM 40,449 mosquitto.conf
1 File(s) 40,449 bytes
2 Dir(s) 76,166,430,720 bytes free
C:\Users\Administrator\Desktop\Container>sftp admin@192.168.88.1
Connected to 192.168.88.1.
sftp> dir
mosquitto mosquitto_mounted pub pull skins
sftp> cd mosquitto_mounted
sftp> put mosquitto.conf
Uploading mosquitto.conf to /mosquitto_mounted/mosquitto.conf
mosquitto.conf 100% 162 40.5KB/s 00:00
重启容器:
[admin@MikroTik] > /container/stop 0
[admin@MikroTik] > /container/start 0
请确保等待容器停止(使用 /container/print 命令后应显示 status=stopped),然后再重新启动它。
启动容器
在你确认容器已添加,并且使用 /container/print 后状态已变为 status=stopped 之后,即可启动它:
/container/start 0
如果你启用了容器日志,你将在 Logs 部分看到类似以下内容:
12:12:46 container,info,debug 1707214366: mosquitto version 2.0.18 starting
12:12:46 container,info,debug 1707214366: Config loaded from /mosquitto/config/mosquitto.conf.
12:12:46 container,info,debug 1707214366: Opening ipv4 listen socket on port 1883.
12:12:46 container,info,debug 1707214366: Opening ipv6 listen socket on port 1883.
12:12:46 container,info,debug 1707214366: mosquitto version 2.0.18 running
MQTT 发布和订阅
子菜单: /iot/mqtt
note: 需要 iot 软件包。
添加一个 MQTT broker:
/iot/mqtt/brokers/add name=mosquitto username=test address=172.19.0.2
订阅 MQTT broker 和所需主题:
/iot/mqtt/subscribe broker=mosquitto topic=test/topic
发布一条静态 MQTT 消息:
/iot/mqtt/publish broker="mosquitto" topic="test/topic" message="{\"test\":\"123\"}"
检查订阅以查看收到的消息:
/iot/mqtt/subscriptions/recv/print
0 broker=mosquitto topic="test/topic" data="{"test":"123"}"
time=2023-07-12 10:01:40
你还可以检查容器日志(如果已启用),以确认 mosquitto 正在运行:
12:47:28 container,info,debug 1675421248: New connection from 172.19.0.1:42240 on port 1883.
12:47:28 container,info,debug 1675421248: New client connected from 172.19.0.1:42240 as MTD8580EC793C4 (p2, c1, k60, u'test').
12:47:38 container,info,debug 1675421258: Client MTD8580EC793C4 disconnected.
SSL MQTT
将 非 SSL MQTT 用于生产环境并不安全。人们可以轻易地捕获/嗅探 broker 与发布者之间交换的数据包,从而获取用户凭据和其他敏感信息。
为提高安全性,请使用 SSL MQTT。
第一步是生成证书。在本示例中,我们将使用一个简单的 Root CA 场景(不要求设备/客户端证书)。
请使用官方 mosquitto-tls 用户指南 作为分步参考。
服务器配置
你应该已经生成了 ca.crt(证书颁发机构文件)、server.crt(服务器证书)和 server.key(服务器密钥):
C:\Users\Administrator\Desktop\Container>dir
Directory of C:\Users\Administrator\Desktop\Container
07/12/2023 10:58 AM <DIR> .
07/12/2023 10:58 AM <DIR> ..
07/12/2023 10:56 AM 1,322 ca.crt
07/12/2023 10:56 AM 1,854 ca.key
07/12/2023 09:57 AM 35 mosquitto.conf
07/12/2023 10:58 AM 1,164 server.crt
07/12/2023 10:57 AM 960 server.csr
07/12/2023 10:56 AM 1,704 server.key
6 File(s) 7,039 bytes
2 Dir(s) 52,401,184,768 bytes free
通过你常用的文本编辑器(Notepad 或其他)打开已挂载的 "mosquitto.conf",并用下面显示的行覆盖它:
tls_version tlsv1.2
port 8883
allow_anonymous true
cafile /mosquitto/config/ca.crt
keyfile /mosquitto/config/server.key
certfile /mosquitto/config/server.crt
- tls_version 行设置最低 TLS 版本。
- port 8883 将使安装程序监听指定端口上的传入网络连接。
- allow_anonymous true 决定是否允许不提供用户名即可连接的客户端进行连接。
警告
我们使用的是用于测试目的的基本 SSL 配置。allow_anonymous true 对于生产环境来说不是一个安全的设置。
- cafile /mosquitto/config/ca.crt 行指定 CA 证书文件的路径。
- keyfile /mosquitto/config/server.key 行指定服务器密钥文件的路径。
- certfile /mosquitto/config/server.crt 行指定服务器证书文件的路径。
将证书文件和更新后的支持 SSL 的 mosquitto.conf 文件上传到已挂载的文件夹 "mosquitto_mounted":
C:\Users\Administrator\Desktop\Container>sftp admin@192.168.88.1
Connected to 192.168.88.1.
sftp> cd mosquitto_mounted
sftp> dir
mosquitto.conf
sftp> put ca.crt
Uploading ca.crt to /mosquitto_mounted/ca.crt
ca.crt 100% 1322 323.0KB/s 00:00
sftp> put server.crt
Uploading server.crt to /mosquitto_mounted/server.crt
server.crt 100% 1164 227.3KB/s 00:00
sftp> put server.key
Uploading server.key to /mosquitto_mounted/server.key
server.key 100% 1704 415.7KB/s 00:00
sftp> dir
ca.crt mosquitto.conf server.crt server.key
sftp> put mosquitto.conf
Uploading mosquitto.conf to /mosquitto_mounted/mosquitto.conf
mosquitto.conf 100% 162 32.2KB/s 00:00
重启容器:
[admin@MikroTik] > /container/stop 0
[admin@MikroTik] > /container/start 0
使用日志确认 broker 监听 8883 端口:
11:20:41 container,info,debug 1689160841: mosquitto version 2.0.15 starting
11:20:41 container,info,debug 1689160841: Config loaded from /mosquitto/config/mosquitto.conf.
11:20:41 container,info,debug 1689160841: Opening ipv4 listen socket on port 8883.
11:20:41 container,info,debug 1689160841: Opening ipv6 listen socket on port 8883.
11:20:41 container,info,debug 1689160841: mosquitto version 2.0.15 running
11:22:24 system,info,account user admin logged in from 10.5.217.34 via local
测试连接
将 CA 证书(ca.crt)上传到 RouterOS 中设备的 "File List":
/file/print
Columns: NAME, TYPE, SIZE, CREATION-TIME
# NAME TYPE SIZE CREATION-TIME
0 skins directory 1970-01-01 03:00:02
1 pub directory 2023-01-04 11:05:04
2 disk7 disk 2023-07-12 09:52:07
3 mosquitto container store 2023-07-12 09:52:09
4 mosquitto_mounted container store 2023-07-25 16:38:37
5 pull directory 2023-07-12 09:52:09
6 ca.crt .crt file 1322 2023-07-12 11:28:23
导入证书:
/certificate/import file-name=ca.crt passphrase=""
为 SSL 连接添加 MQTT broker:
/iot/mqtt/brokers/add name=mosquittoSSL username=test address=172.19.0.2 port=8883 ssl=yes
订阅 MQTT broker 和所需主题:
/iot/mqtt/subscribe broker=mosquittoSSL topic=test/topic
发布一条静态 MQTT 消息:
/iot/mqtt/publish broker="mosquittoSSL" topic="test/topic" message="{\"test\":\"123\"}"
检查订阅以查看收到的消息:
/iot/mqtt/subscriptions/recv/print
0 broker=mosquittoSSL topic="test/topic" data="{"test":"123"}"
time=2023-07-12 10:20:40