mosquitto日誌報錯SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca

參考文章segmentfault

  1. Mosquitto服務器的搭建以及SSL/TLS安全通訊配置
  2. Mosquitto SSL Configuration -MQTT TLS Security 讀者Abhinav Saxena的評論
  3. OpenSSL - error 18 at 0 depth lookup:self signed certificate

系統版本: CentOS7安全

mosquitto版本: 1.4.15服務器

openssl版本: 1.0.1eide

參考文章1對mosquitto的TLS配置步驟講解得十分詳細, 包含了openssl生成證書及密鑰, mosquitto的配置, 及其內置pub/sub客戶端對證書及密鑰的使用等. 測試

其實關於mosquitto的自簽名SSL/TLS配置, 在用yum安裝後可使用man mosquitto-tls查看, 其中也有詳細的操做步驟.ui

按照這樣的流程走下來, mosquitto啓動正常, 相關配置以下.日誌

cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
tls_version tlsv1

沒什麼問題, 可是在執行mosquitto_pub, mosquitto_sub命令時, 獲得了Error: A TLS error occurred.錯誤.code

$ mosquitto_pub  -t 'room01/sensors' -m '個人消息' --cafile /etc/mosquitto/certs/ca.crt --cert /etc/mosquitto/certs/client.crt --key /etc/mosquitto/certs/client.key -h 172.32.100.10 --tls-version tlsv1
Error: A TLS error occurred

對應的, mosquitto服務端的日誌以下.server

1523024283: New connection from 172.32.100.10 on port 1883.
1523024283: OpenSSL Error: error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
1523024283: OpenSSL Error: error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake failure
1523024283: Socket error on client <unknown>, disconnecting.
--tls-version tlsv1選項要加的, 由於 pub/sub兩個客戶端使用的tls版本默認爲 tls1.2, 不加這個選項的話, mosquitto服務會獲得 SSL routines:SSL3_READ_BYTES:tlsv1 alert protocol version錯誤.

網上關於這個問題有說是由於mosquitto與兩個客戶端版本不一致的, 或者mosquitto指定ca.crt與客戶端不是同一個的, 也有說是server.csr填寫的Common Name與服務器IP不一樣的...ssl

呵呵, 好笑, 我怎麼可能會犯這種低級錯誤.

我也嘗試過爲mosquitto_pub加上--insecure選項, 可是這是讓mosquitto_pub不去驗證服務端證書中Common Name與其地址是否匹配的, 無效.

後來按照參考文章2中Abhinav Saxena的提示, 把--cafile的值改爲了server.crt, 居然成功了...成功了...

$ mosquitto_pub  -t 'room01/sensors' -m '個人消息' --cafile /etc/mosquitto/certs/ca.crt --cert /etc/mosquitto/certs/client.crt --key /etc/mosquitto/certs/client.key -h 172.32.100.10 --tls-version tlsv1

mosquitto_sub的命令以下

$ mosquitto_sub  -t 'room01/sensors' -h 172.32.100.10 --tls-version tlsv1 --cafile /etc/mosquitto/certs/server.crt --cert /etc/mosquitto/certs/client.crt --key /etc/mosquitto/certs/client.key
個人消息

服務端的日誌以下

1523175367: New connection from 172.32.100.10 on port 1883.
1523175368: New client connected from 172.32.100.10 as mosqpub|6211-localhost. (c1, k60).
1523175368: Sending CONNACK to mosqpub|6211-localhost. (0, 0)
1523175368: Received PUBLISH from mosqpub|6211-localhost. (d0, q0, r0, m0, 'room01/sensors', ... (12 bytes))
1523175368: Received DISCONNECT from mosqpub|6211-localhost.
1523175368: Client mosqpub|6211-localhost. disconnected.

若是加了--insecure選項, 命令應該是這樣的

$ mosquitto_pub  -t 'room01/sensors' -m '個人消息' -h 172.32.100.10 --tls-version tlsv1 --cafile /etc/mosquitto/certs/server.crt --insecure

對應的, moquitto_sub的命令應該寫作

$ mosquitto_sub  -t 'room01/sensors' -h 172.32.100.10 --tls-version tlsv1 --cafile /etc/mosquitto/certs/server.crt --insecure
個人消息

個人世界觀都崩塌了...

以後的實驗裏, 認識到上面的TLS只是mosquitto的單向認證, 這種狀況下, 是要客戶端判斷服務端是否可信的, 就是說, 這種認證是爲了客戶端的安全而不是服務端安全.

mosquitto還有一個require_certificate字段, 表示是否驗證客戶端傳來的證書, 默認爲fasle.

...呵呵, 若是沒驗證客戶端證書, 那上面的錯誤是怎麼來的???

不過, 將這個字段設置爲true後, 上面兩種訂閱/發佈命令都沒用了.

心累.jpg, md必定是mosquitto_pub/sub兩個命令有問題!


隱隱以爲仍是和證書的Common Name字段有關, 以前的測試中, mosquitto服務與pub/sub客戶端是在同一臺服務器上. 嘗試在另外一臺服務器運行mosquitto_pub命令, 因此從新爲其簽發了證書與密鑰對, 而後運行成功了.

因而猜想, 是否是CACommon Name不能與被其簽發的證書的相同? 由於以前測試時, CA, server與client的Common Name都是172.32.100.10(以前也試過localhost, 127.0.0.1的).

而後從新生成CA證書, Common Name填的是0.0.0.0, server與client的依然是服務器自己的IP172.32.100.10.

事實證實個人猜想是對的.

網上你們人都只說mosquitto與其客戶端的證書Common Name要與其所在服務器IP相符, 卻沒有人說過自簽名的CA證書Common Name應該取什麼, 總有人踩坑的.

關於這一點, 能夠看一下參考文章3的最佳答案, 一票人來感謝這個回答...

When OpenSSL prompts you for the Common Name for each certificate, use different names.
相關文章
相關標籤/搜索