參考文章segmentfault
系統版本: 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
命令, 因此從新爲其簽發了證書與密鑰對, 而後運行成功了.
因而猜想, 是否是CA
的Common 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.