0%

mosquitto

Mosquitto 是一个开源免费的 MQTT 代理服务。

Mosquitto

安装 mosquitto:

1
brew install mosquitto

启动 MQTT broker 服务:

1
brew services start mosquitto

Or

1
/usr/local/sbin/mosquitto -c /usr/local/etc/mosquitto/mosquitto.conf

停止 MQTT broker 服务:

1
brew services mosquitto stop

Mosquitto with TLS

tlsv1 alert internal error

按 “MQTT Essentials – A Lightweight IoT Protocol” 书中 “Configuring TLS transport security in Mosquitto” 章节所述的 Client subscribe 命令会报错:

1
2
3
$ mosquitto_sub -V mqttv311 -p 8883 --cafile /usr/local/etc/mosquitto/certificates/ca.crt -t sensors/drone01/altitude -d
Client mosqsub|1181-yangshiwei sending CONNECT
Error: A TLS error occurred.

Broker 端错误日志:

1
2
3
1517841349: OpenSSL Error: error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error
1517841349: OpenSSL Error: error:140940E5:SSL routines:ssl3_read_bytes:ssl handshake failure
1517841349: Socket error on client <unknown>, disconnecting.

Wireshark 抓包数据:

1
2
3
5	::1	::1	TLSv1.2	 383 Client Hello
7 ::1 ::1 TLSv1.2 2439 Server Hello, Certificate, Server Key Exchange, Server Hello Done
9 ::1 ::1 TLSv1.2 83 Alert (Level: Fatal, Description: Internal Error)
Transmission Control Protocol, Src Port: 49355, Dst Port: 8883, Seq: 308, Ack: 2364, Len: 7
Secure Sockets Layer
    TLSv1.2 Record Layer: Alert (Level: Fatal, Description: Internal Error)
        Content Type: Alert (21)
        Version: TLS 1.2 (0x0303)
        Length: 2
        Alert Message
            Level: Fatal (2)
            Description: Internal Error (80)

无论是错误日志还是抓包数据都看不出来具体原因,只能知道是 Client 发生了内部错误,主动断开了连接。

最终在 google 上找到了答案:

原来是因为我的 CA root certificate 是自签名的,mosquiito 认为有安全风险,所以主动断开了连接。

Tuturial: mbedTLS SSL Certificate Verification with Mosquitto, lwip and MQTT

Mosquitto Client and Server Certificate Usage

I’m running the broker with the following server certificate setting:

1
certfile C:\Program Files (x86)\mosquitto\certs\m2mqtt_srv.crt

Using the mosquitto client to subscribe, I can subscribe to a topic with the following command line, using that same certificate:

1
mosquitto_sub -c -i MyMQTTclient -h localhost -p 8883 -q 0 -t HSLU/test -v --cafile c:\tmp\tls_ssl\client\m2mqtt_srv.crt --insecure

Notice that I have to specify the option –insecure. Without the –insecure it will give an error message like this:

1
2
3
1492934878: OpenSSL Error: error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error
1492934878: OpenSSL Error: error:140940E5:SSL routines:ssl3_read_bytes:ssl handshake failure
1492934878: Socket error on client <unknown>, disconnecting.

It took me while to find out why it is failing. A good way to test the TLS handshaking and connection is to use

1
openssl s_client -connect localhost:8883

which gives me the reason in the last line of the output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
-----END CERTIFICATE-----
subject=/C=CH/ST=Switzerland/L=Lucerne/O=HSLU/OU=T&A/CN=ErichStyger-PC/emailAddress=mail@hslu.ch
issuer=/C=CH/ST=Switzerland/L=Lucerne/O=HSLU/OU=T&A/CN=ErichStyger-PC/emailAddress=mail@hslu.ch
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 1605 bytes and written 434 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: D241F3BFA8D26BDEE381353E2C517E46F8D04B48F307467A0E46FD7A2F3EB6BB
Session-ID-ctx:
Master-Key: <cut>
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 7200 (seconds)
TLS session ticket:
0000 - a0 fa a5 f5 8d 54 78 1a-7c 4e 86 51 4c 24 45 30 .....Tx.|N.QL$E0
0010 - 97 44 de c1 fb c7 06 96-46 ed ef 27 67 c2 91 6f .D......F..'g..o
0020 - 40 38 ef 86 2a 12 59 cb-f0 60 0d 34 e6 be 2a ef @8..*.Y..`.4..*.
0030 - e5 7c c8 ee c3 ac cb 25-ef 63 49 3c 27 2e b0 3c .|.....%.cI<'..<
0040 - e3 a6 88 53 08 20 4b 53-2f 2b 6e 44 20 1a e7 24 ...S. KS/+nD ..$
0050 - 60 a3 1a b0 08 74 74 56-46 13 22 0a 76 df 32 53 `....ttVF.".v.2S
0060 - d7 b1 6b 82 63 34 fc c8-9c 2c a6 16 a2 73 75 9d ..k.c4...,...su.
0070 - 33 03 dc c7 db e0 c7 89-d0 49 ac fd 7d d3 33 0e 3........I..}.3.
0080 - 35 eb df fc 05 b3 d0 bb-b7 02 25 67 86 71 76 f4 5.........%g.qv.
0090 - 56 59 3b 39 2a dc 04 0e-e1 60 ae e4 17 1c 8f 62 VY;9*....`.....b
00a0 - b9 bf f1 99 5e c5 15 3c-ae 60 60 cb 8e 63 1a af ....^..<.``..c..

Start Time: 1492935504
Timeout : 300 (sec)
Verify return code: 18 (self signed certificate)
---
closed

Ah, that makes sense: I have used a self-signed certificate :-). Now I know why I have to use the option –insecure with mosquitto_sub. I guess I could get rid of this with an non-self-signed certificate, but that’s too much of an effort for me now, as I’m only testing the connection.

mcuoneclipse.com

https://mcuoneclipse.com 是个非常好的 MCU 开发网站。

关于 MQTT 还有一系列文章:

Tutorial: Secure TLS Communication with MQTT using mbedTLS on top of lwip

Enable Secure Communication with TLS and the Mosquitto Broker

self-signed certificate

Self-signed certificate

In technical terms a self-signed certificate is one signed with its own private key.

root certificate

wikipeida

根证书没有上层机构再为其本身作数字签名,所以都是自签证书。许多应用软件(例如操作系统网页浏览器)会预先安装可被信任的根证书,这代表用户授权了应用软件代为审核哪些根证书机构属于可靠,例如是公认可靠的政府机关(如香港邮政[2])、专职机构(如Google[3]Let’s EncryptCAcert.orgComodoDigiCertGlobalSignVerisign)等。

坚持原创技术分享,您的支持将鼓励我继续创作!