Comments (16)
@robertsLando @mcollina Works!
Here's the example code for accomplishing Mutual TLS with Aedes MQTT Broker:
const aedes = require('aedes')();
const server = require('aedes-server-factory').createServer(aedes, {
/* Setup Encrypted mTLS Broker */
tls: {
ca: "<<Your Self Signed Root CA>>",
cert: "<<Your Server CA>>",
key: "<<Your Server Private Key>>",
requestCert: true, // Request certificate from client
rejectUnauthorized: true, // Reject unauthorized clients
minVersion: 'TLSv1.2'
}
});
aedes.preConnect = function (client, packet, callback) {
console.log('Client Preconnect Received: ');
console.log(`Client IP: ${client.connDetails.ipAddress}`);
console.log(`Client TLS Authorized: ${client.connDetails.certAuthorized}`);
// If certAuthorized is true, that means client certificate is valid and TLS handshake was successful ( you can trust this client )
if(client.connDetails.certAuthorized) {
console.log(`Client TLS Fingerprint: ${client.connDetails.cert.fingerprint}`);
console.log(`Client TLS Organization: ${client.connDetails.cert.subject.CN}`);
console.log(`Client TLS Issuer: ${client.connDetails.cert.issuer.CN}`);
}
callback(null, true);
}
server.listen(8883, function () {
console.log('MQTT broker started and listening on port: 8883');
});
So to clear some fundamentals in this Issue:
Part 1: Validation & Handshake & Authentication
Well, most of the client authentication stuff which was mentioned by @tienvv1234 , is handled by tls
module of nodejs, We just need to get the authorized
variable from socket
to know if the certificate supplied by the client was valid ( signed by our root CA ) or not.
Part 2: Client Authentication Identification
This part can vary depending on your business model or implementation, for this example I assume you have multiple IoT devices and each device has it's own unique client certificate
At last, we can do some client identification by matching "client username to certificate serial number" in our preconnect
or authenticate
aedes hooks ( which will vary from application to application ) using client.connDetails.cert
. The cert
object will contain every detail about the client's certificate, Reference.
from aedes-server-factory.
This is totally possible and every single time I forget on how to do it. I'd recommend to look on how to do it with bare tcp/Node.js and then port it on top of Aedes/MQTT.
from aedes-server-factory.
To parse/validate certs you could use node-forge
https://stackoverflow.com/questions/48377731/using-node-js-to-verify-a-x509-certificate-with-ca-cert
@mcollina What I don't understand is when does the parse should happen, I mean what I would do is to do it in aedes.decodeProtocol
, here I would popolate the client with the key
and cert
coming from the connection and in aedes.authenticate
I can validate the parsed certs using client.cert
and client.key
from aedes-server-factory.
Something like:
var aedes = require('aedes')
var { protocolDecoder, validateCerts } = require('aedes-x509-decoder')
var net = require('net')
var port = 1883
var broker = aedes({
decodeProtocol: function (client, buffer) {
var proto = protocolDecoder(client, buffer) // this will add parsed client.connDetails.key and client.connDetails.cert from buffer to client
return proto
},
preConnect: function (client, done) {
validateCerts(client.connDetails.key, client.connDetails.cert, done)
}
})
var server = net.createServer(broker.handle)
server.listen(port, function () {
console.log('server listening on port', port)
})
I think a good starting point would be: https://github.com/moscajs/aedes-protocol-decoder/blob/master/lib/protocol-decoder.js
from aedes-server-factory.
@tienvv1234 Let us know :) Could be useful to other users too
from aedes-server-factory.
@robertsLando @mcollina Added mTLS Decoder ( ayushsharma82/aedes-protocol-decoder@e2a3696 )
As far as I know, the client private key is not intended to be shared in Mutual TLS, so a cert
and certAuthorized
variable should be enough for client identification.
Looking forward to testing it. I'll keep you updated.
from aedes-server-factory.
Could try to use preConnect
hook https://github.com/moscajs/aedes/blob/master/docs/Aedes.md#handler-preconnect-client-callback
from aedes-server-factory.
Yes, I can, but I don't know how to send certificates from client to broker and how the broker access to certificates
client code
const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://localhost:8883', {
// username: 'test',
// password: 'test',
key: fs.readFileSync("./private.pem.key"),
cert: fs.readFileSync("./certificate.pem.crt"),
});
broker code
I can not find the certificate in the client
aedes.preConnect = function(client, callback){
// console.log('client', client);
callback(null, true)
}
aedes.authenticate = function(client, username, password, callback) {
console.log(client);
// where i can get the certificate
callback(null, true)
}
from aedes-server-factory.
I think you could try to give a look also to https://github.com/moscajs/aedes/blob/master/lib/client.js#L77
I think decodeProtocol
function isn't documented yet but it's used for example in https://github.com/moscajs/aedes-protocol-decoder to decode the protocol. Try to give a look at them @mcollina thoughts?
@tienvv1234 in case you develop a working example for this please share it here :) We could create a module for that
from aedes-server-factory.
thank you guys for quick response, I will try it
from aedes-server-factory.
@tienvv1234 Pay attention that with latest release 0.43.0 the preconnect signature has changed
from aedes-server-factory.
ok thank you
from aedes-server-factory.
Closing this for now
from aedes-server-factory.
@robertsLando Maybe we could keep track of that issue as reference for a feature we could add in the server-factory ?
from aedes-server-factory.
Right, moved to server factory :)
from aedes-server-factory.
Can be achieved with aedes-protocol-decoder >=2.1.0
from aedes-server-factory.
Related Issues (9)
- [bug] Typo in type definitions HOT 1
- When the port is occupied, the program hangs without throwing any errors HOT 1
- [question]how can i use one server to listen muti ports? HOT 1
- What are the best use case(s) of this package?[question] HOT 4
- [bug] incompatibilities with aedes 0.48.0 HOT 4
- Request client certificate behind a proxy [question] HOT 9
- [feat] Move mqtt parser to server-factory HOT 4
- Websocket errors are not handled HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from aedes-server-factory.