2015-03-30 193 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