2015-03-30 48 views
0

我想使用NodeJS將MQTT負載存儲在MongoDB數據庫中。 當我運行我的代碼,我得到以下錯誤在Mosquitto服務器彈出:蚊子安全錯誤:OpenSSL錯誤:例程:SSL3_GET_RECORD:錯誤的版本號

1427756032: Socket error on client <unknown>, disconnecting. 
1427756033: New connection from 146.175.138.141 on port 8883. 
1427756033: OpenSSL Error: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number 

我不是唯一一個面臨這樣的錯誤,但對谷歌提出的解決方案不會爲我工作。

我正在使用Ubuntu14.04 TLS(trusty)服務器環境。 OpenSSL的的,我用來做我自己的密鑰和證書的版本是:

OpenSSL 1.0.1f 6 Jan 2014 

爲了使這些按鍵我跟着Mosquitto的manual

的NodeJS的版本是:

v0.10.25 

mosquitto的配置文件:

port 8883 
cafile /etc/keys/ca.crt 
certfile /etc/keys/server.crt 
keyfile /etc/keys/server.key 
tls_version tlsv1 
require_certificate true 

的的NodeJS文件:

var mqtt=require('mqtt') 
var mongodbClient=require('mongodb').MongoClient; 
var deviceRoot="demo/device/" 
var mqtthost = '146.175.138.141'; 
var KEY = '/etc/keys/client.key'; 
var CERT = '/etc/keys/client.crt'; 
var CAfile = '/etc/keys/ca.crt'; 

var options = { 
    host: mqtthost, 
    port: 8883, 
    protocolId: 'MQIsdp', 
    ca: CAfile, 
    keyPath: KEY, 
    certPath: CERT, 
    secureProtocol: 'TLSv1_method', 
    protocolId: 'MQIsdp', 
    protocolVersion: 3 
}; 

var collection,client; 

mongodbClient.connect("mongodb://localhost:27017/exampleDb", function(err,db){ 
if(err){return console.dir(err);} 

collection=db.collection("test_mqtt"); 

client=mqtt.connect(options); 

client.subscribe("#"); 
client.publish(deviceRoot, '21'); 

client.on('message', function(topic,payload){ 
    str = payload.toString(); 
    console.log(str); 
    var key=topic.replace(deviceRoot,''); 

    collection.update(
    { _id:key }, 
    { $push: { events: { event: { value:str, when:new Date() } } } }, 
    { upsert:true } 
)})}) 

的關鍵應該是工作,因爲與出版以下命令不是問題:

mosquitto_pub -h 146.175.138.141 -p 8883 -t Server -m helloworld --cafile /etc/keys/ca.crt --cert /etc/keys/client.crt --key /etc/keys/client.key --tls-version tlsv1 

任何想法我做錯了什麼?

回答

0

使用「FS」保證對文件的訪問

var fs = require('fs'); 
var mongodbClient=require('mongodb').MongoClient; 
var deviceRoot="demo/device/" 
var mqtthost = '146.175.138.141'; 
var KEY = fs.readFileSync('/etc/keys/client.key'); 
var CERT = fs.readFileSync('/etc/keys/client.crt'); 
var CAfile = [fs.readFileSync('/etc/keys/ca.crt')]; 

var options = { 
host: mqtthost, 
port: 8883, 
protocol: 'mqtts', //also add this 
protocolId: 'MQIsdp', 
ca: CAfile, 
key: KEY, 
cert: CERT, 
secureProtocol: 'TLSv1_method', 
protocolId: 'MQIsdp', 
protocolVersion: 3 
}; 
1

我不能肯定地說,但我懷疑你的nodejs連接沒有使用TLS。您也可以用mosquitto_pub連接不經過--cafile驗證這一點:

mosquitto_pub -h 146.175.138.141 -p 8883 -t Server -m helloworld 

這應該產生在你與你的連接的NodeJS看到經紀人同樣的錯誤。

下一步是從您的mosquitto配置中刪除tls_version tlsv1行並重覆上述命令。在這種情況下,我希望得到的經紀人以下錯誤信息:

Client connection from ::1 failed: error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol. 

如果你現在使用您的客戶端的NodeJS重複測試,並得到同樣的錯誤信息,這是一個公平的賭注,我是什麼說的是對的。恐怕我不知道如何修復它!

一個簡單的測試就是讓你的nodejs代碼保持不變,但是設置mosquitto在不使用TLS的情況下監聽。如果節點連接良好,則確認情況。

在相關說明中,如果您使用的是mosquitto 1.4,最好的選擇是不強制特定版本的TLS,因爲默認行爲是允許TLS v1.0,v1.1和v1.2。早期版本僅爲每個偵聽器提供單個版本的TLS。

+0

事實上,這個錯誤彈出如果代理找不到憑證檔案錯誤。是的,如果我在mosquitto配置中刪除tls_version,則會出現「client_hello」錯誤。如果我將蚊子設置爲在不使用TLS的情況下偵聽,則nodejs代碼可以進行連接。所以你是對的。 謝謝你指點我的TLS設置。但是我的問題沒有得到解決。經紀人在啓動時不再要求我提供pem密碼,這是正常的嗎?會不會涉及任何所有權問題? – 2015-03-31 09:12:49

+1

我不認爲蚊子(經紀)是在過錯,因爲它與TLS與mosquitto_pub正確工作。儘管你告訴它nodejs代碼不使用TLS。我無法幫助,對不起。 – ralight 2015-03-31 15:41:39