标签 mqtt 下的文章

“”

本文介绍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.

使用tls 双向认证时,需要提供客户端的证书。在mosquitto的测试服务器,有提供客户端证书的签发功能。需要自己实现证书签名请求。
操作如下:
1.生成rsa私钥

openssl genrsa -out mosquitto-client.key 2048

Generating RSA private key, 2048 bit long modulus (2 primes)
..+++++
........................+++++
e is 65537 (0x010001)
2.生成客户端证书签名请求

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

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.

Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:GD
Locality Name (eg, city) []:GZ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:GV
Organizational Unit Name (eg, section) []:RD
Common Name (e.g. server FQDN or YOUR name) []:const.net.cn
Email Address []:admin@const.net.cn

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

3.Generate a TLS client certificate for test.mosquitto.org
访问网址:https://test.mosquitto.org/ssl/ 将csr粘贴到网站下,下载客户端证书。保存为mosquitto-client.crt.
生成客户端证书网页如图
mosquitto-client-crt-request.png

下面开始测试mqtt 双向认证测试工作
发送订阅命令:

mosquitto_sub -L "mqtts://test.mosquitto.org:8884/const.net.cn/" --cert mosquitto-client.crt --key mosquitto-client.key --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参数的订阅命令:

mosquitto_sub -L "mqtts://test.mosquitto.org:8884/const.net.cn/" --cert mosquitto-client.crt --key mosquitto-client.key --cafile ../mosquto.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

注意,需要带上客户端证书,客户端私钥,还有ca证书,否则,可能会得到以下错误提示
OpenSSL Error[0]: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed
Error: A TLS error occurred.

发布命令:

mosquitto_pub -L "mqtts://test.mosquitto.org:8884/const.net.cn/" --cert mosquitto-client.crt --key mosquitto-client.key --cafile ../mosquitto.org.crt -m 'mqtt example 8884 : MQTT, encrypted, client certificate required' -d

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

mosquitto_sub接收到的数据
Client (null) received PUBLISH (d0, q0, r0, m0, 'const.net.cn/', ... (64 bytes))
mqtt example 8884 : MQTT, encrypted, client certificate required
Client (null) sending PINGREQ
Client (null) received PINGRESP