2021年7月

“欲速则不达,见小利则大事不成。”

wireshark 显示语法

data.len==16 and data.data[0-3]==c0:a8:06:fb

wireshark 根据数据内容显示过滤示例效果图:
wireshark-display-data-data.png

查找 wireshark data.data filter

可以在官网上看到关于data display 的 filter
https://www.wireshark.org/docs/dfref/d/data.html

对于太长的数据,可以使用 data.md5_hash 来判断是否是指定内容的数据。不过一般来说,长度和指定数据部分内容就能够区分了。

本文介绍mosquitto基于tls的使用方法。

搭建mosquitto server
mkdir -p /etc/mosquitto/ca_certificates
mkdir -p /etc/mosquitto/certs

生成证书并自签名

openssl req -config ssl/openssl.cnf -new -x509 -days 3650 -extensions v3_ca -keyout ca.key -out ca.crt

会要求输入一些必要的信息,按提示输入就好。
关于-config参数,OpenSSL命令(例如,req和ca)带有一个-config参数用于指定openssl配置文件的位置.
生成服务器端证书
1.生成不加密的服务器私钥

openssl genrsa -out server.key 2048

2.生成服务器证书签名请求

openssl req -config ssl/openssl.cnf -out server.csr -key server.key -new

3.服务器证书请求签名

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650

Signature ok
将server.crt和server.key复制到/etc/mosquitto/certs/目录

生成客户端证书
1.生成不加密的客户端私钥

openssl genrsa -out client.key 2048

2.生成客户端证书签名请求

openssl req -config ssl/openssl.cnf -out client.csr -key client.key -new

3.客户端证书请求签名

openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 3650

将client.crt和client.key复制到/etc/mosquitto/certs/目录

allow_anonymous true
user nobody
listener 8883
cafile /etc/mosquitto/ca_certificates/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
tls_version tlsv1.2
require_certificate true
use_identity_as_username true

运行mosquitto broker.

mosquitto -c mosquitto.conf -v 

后台运行就用

mosquitto -c mosquitto.conf -d

客户端使用示例

mosquitto_sub -h localhost --cert client.crt --key client.key --cafile ca.crt -t "/client/v1" --insecure -q 2

常见错误与常识
Error: Unsupported tls_version tlsv1
这个将配置文件中改为tlsv1.2就好。
openssl 指定 openssl.cnf
OpenSSL命令(例如,req和ca)带有一个-config参数用于指定openssl配置文件的位置.
Unable to drop privileges to 'mosquitto' because this user does not exist. Trying 'nobody' instead
这个在配置文件中指定 user nobody就好。
error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib)
这个是openssl报的错误,可能文件找不到,或者没有权限,openssl默认生成的key可能只有600的权限。
mosquitto tls证书单向认证与双向认证切换
单向认证只需要注释两行即可:

require_certificate true

use_identity_as_username true

mosquitto tls 要求双向认证
require_certificate true
use_identity_as_username true

关于 mosquitto-tls 官方手册地址:https://mosquitto.org/man/mosquitto-tls-7.html
mosquitto mqtt broker 官方测试服务器 https://test.mosquitto.org/ 
支持 mosquitto mqtt 常见端口
1883 : MQTT, unencrypted, unauthenticated
1884 : MQTT, unencrypted, authenticated
8883 : MQTT, encrypted, unauthenticated
8884 : MQTT, encrypted, client certificate required
8885 : MQTT, encrypted, authenticated
8887 : MQTT, encrypted, server certificate deliberately expired
8080 : MQTT over WebSockets, unencrypted, unauthenticated
8081 : MQTT over WebSockets, encrypted, unauthenticated
8090 : MQTT over WebSockets, unencrypted, authenticated
8091 : MQTT over WebSockets, encrypted, authenticated

官方还贴心的可以帮忙签发客户端证书来测试。

mqtt 订阅命令

mosquitto_sub -L mqtt://test.mosquitto.org:1883/const.net.cn/

mosquitto_sub -L参数说明

-L : specify user, password, hostname, port and topic as a URL in the form:

  mqtt(s)://[username[:password]@]host[:port]/topic

mqtt 发布命令

mosquitto_pub -L mqtt://test.mosquitto.org/const.net.cn/ -m 'mqtt hello world test.mosquitto.org 1883 : MQTT, unencrypted, unauthenticated'

带调试数据的 mqtt 发布命令

mosquitto_pub -L mqtt://test.mosquitto.org/const.net.cn/ -m 'mqtt hello world test.mosquitto.org 1883 : MQTT, unencrypted, unauthenticated' -d

Client mosq-m1kd4t2Yz2Hext8Zot sending CONNECT
Client mosq-m1kd4t2Yz2Hext8Zot received CONNACK (0)
Client mosq-m1kd4t2Yz2Hext8Zot sending PUBLISH (d0, q0, r0, m1, 'const.net.cn/', ... (77 bytes))
Client mosq-m1kd4t2Yz2Hext8Zot sending DISCONNECT

接收到的数据:

mosquitto_sub -L mqtt://test.mosquitto.org:1883/const.net.cn/ -v

const.net.cn/ mqtt hello world test.mosquitto.org 1883 : MQTT, unencrypted, unauthenticated
const.net.cn/ mqtt hello world test.mosquitto.org 1883 : MQTT, unencrypted, unauthenticated

mqtt 1884 通信采用不加密,但需要验证的方法,登录用户名与密码的参数为-u和-P.

不使用密码登录:

mosquitto_sub -L mqtt://test.mosquitto.org:1884/const.net.cn/ -v 
       

Connection error: Connection Refused: not authorised.
使用密码登录:
mosquitto_sub -L mqtt://test.mosquitto.org:1884/const.net.cn/ -v -u rw -P readwrite

不使用密码时:

mosquitto_pub -L mqtt://test.mosquitto.org:1884/const.net.cn/ -m 'mqtt hello world test.mosquitto.org 1884 : MQTT, unencrypted, authenticated' -d

Client mosq-dZTvqWrOBAwBY0e81Q sending CONNECT
Client mosq-dZTvqWrOBAwBY0e81Q received CONNACK (5)
Connection error: Connection Refused: not authorised.
Client mosq-dZTvqWrOBAwBY0e81Q sending DISCONNECT

使用用户名密码登录:

mosquitto_pub -L mqtt://test.mosquitto.org:1884/const.net.cn/ -m 'mqtt hello world test.mosquitto.org 1884 : MQTT, unencrypted, authenticated' -d -u rw -P readwrite

Client mosq-euDtfmG2k4QCjlSt9g sending CONNECT
Client mosq-euDtfmG2k4QCjlSt9g received CONNACK (0)
Client mosq-euDtfmG2k4QCjlSt9g sending PUBLISH (d0, q0, r0, m1, 'const.net.cn/', ... (75 bytes))
Client mosq-euDtfmG2k4QCjlSt9g sending DISCONNECT

接收到的消息:

mosquitto_sub -L mqtt://test.mosquitto.org:1884/const.net.cn/ -v -u rw -P readwrite

const.net.cn/ mqtt hello world test.mosquitto.org 1884 : MQTT, unencrypted, authenticated
const.net.cn/ mqtt hello world test.mosquitto.org 1884 : MQTT, unencrypted, authenticated

mqtt 8883 通信采用加密,不需要验证(匿名)的方法,不使用密码登录。

1.下载mosquitto.org的证书。

wget https://test.mosquitto.org/ssl/mosquitto.org.crt

2.订阅命令

mosquitto_sub -L mqtts://test.mosquitto.org:8883/const.net.cn/ --cafile mosquitto.org.crt -d

Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending SUBSCRIBE (Mid: 1, Topic: const.net.cn/, QoS: 0, Options: 0x00)
Client (null) received SUBACK
Subscribed (mid: 1): 0

设置Qos为2

mosquitto_sub -L mqtts://test.mosquitto.org:8883/const.net.cn/ --cafile mosquitto.org.crt -q 2 -d

Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending SUBSCRIBE (Mid: 1, Topic: const.net.cn/, QoS: 2, Options: 0x00)
Client (null) received SUBACK
Subscribed (mid: 1): 2
Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending SUBSCRIBE (Mid: 2, Topic: const.net.cn/, QoS: 2, Options: 0x00)
Client (null) received SUBACK
Subscribed (mid: 2): 2

3.发布命令

mosquitto_pub -L mqtts://test.mosquitto.org:8883/const.net.cn/ --cafile mosquitto.org.crt -m 'mqtt hello world test.mosquitto.org 8883 : MQTT, encrypted, unauthenticated' -d

Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending PUBLISH (d0, q0, r0, m1, 'const.net.cn/', ... (75 bytes))
Client (null) sending DISCONNECT

4、接收内容
Client (null) received PUBLISH (d0, q0, r0, m0, 'const.net.cn/', ... (75 bytes))
mqtt hello world test.mosquitto.org 8883 : MQTT, encrypted, unauthenticated
Client (null) sending PINGREQ
Client (null) received PINGRESP

注意,mosquitto心跳包默认时长为60秒,可以通过-k参数设置。

-k : keep alive in seconds for this client. Defaults to 60.