From 7f37b78d45f879d782d493595d76a14dbd31b7b5 Mon Sep 17 00:00:00 2001 From: Noah Kontur <35545508+konturn@users.noreply.github.com> Date: Wed, 19 Oct 2022 22:17:15 -0400 Subject: [PATCH] feat: support for MQTT TLS (#241) --- README.md | 10 ++++++++ api/src/constants/defaults.js | 3 +++ api/src/util/mqtt.util.js | 46 +++++++++++++++++++++-------------- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 568370d4..a36bb21a 100644 --- a/README.md +++ b/README.md @@ -280,6 +280,16 @@ mqtt: password: client_id: + tls: + # cert chains in PEM format: /path/to/client.crt + cert: + # private keys in PEM format: /path/to/client.key + key: + # optionally override the trusted CA certificates: /path/to/ca.crt + ca: + # if true the server will reject any connection which is not authorized with the list of supplied CAs + reject_unauthorized: false + topics: # mqtt topic for frigate message subscription frigate: frigate/events diff --git a/api/src/constants/defaults.js b/api/src/constants/defaults.js index 9edfdad6..7c79a500 100644 --- a/api/src/constants/defaults.js +++ b/api/src/constants/defaults.js @@ -30,6 +30,9 @@ module.exports = { min_area: 0, }, mqtt: { + tls: { + reject_unauthorized: false, + }, topics: { frigate: 'frigate/events', matches: 'double-take/matches', diff --git a/api/src/util/mqtt.util.js b/api/src/util/mqtt.util.js index 4c8e2ca0..aea78af4 100644 --- a/api/src/util/mqtt.util.js +++ b/api/src/util/mqtt.util.js @@ -1,3 +1,4 @@ +const filesystem = require('fs'); const { v4: uuidv4 } = require('uuid'); const axios = require('axios'); const mqtt = require('mqtt'); @@ -86,24 +87,33 @@ const processMessage = ({ topic, message }) => { module.exports.connect = () => { if (!MQTT || !MQTT.HOST) return; - CLIENT = mqtt.connect(`mqtt://${MQTT.HOST}`, { - reconnectPeriod: 10000, - username: MQTT.USERNAME || MQTT.USER, - password: MQTT.PASSWORD || MQTT.PASS, - clientId: MQTT.CLIENT_ID || `double-take-${Math.random().toString(16).substr(2, 8)}`, - }); - - CLIENT.on('connect', () => { - logStatus('connected', console.log); - this.publish({ topic: 'double-take/errors' }); - this.available('online'); - this.subscribe(); - }) - .on('error', (err) => logStatus(err.message, console.error)) - .on('offline', () => logStatus('offline', console.error)) - .on('disconnect', () => logStatus('disconnected', console.error)) - .on('reconnect', () => logStatus('reconnecting', console.warn)) - .on('message', async (topic, message) => processMessage({ topic, message }).init()); + + try { + CLIENT = mqtt.connect(`mqtt://${MQTT.HOST}`, { + reconnectPeriod: 10000, + username: MQTT.USERNAME || MQTT.USER, + password: MQTT.PASSWORD || MQTT.PASS, + clientId: MQTT.CLIENT_ID || `double-take-${Math.random().toString(16).substr(2, 8)}`, + key: MQTT.TLS.KEY ? filesystem.readFileSync(MQTT.TLS.KEY) : null, + cert: MQTT.TLS.CERT ? filesystem.readFileSync(MQTT.TLS.CERT) : null, + ca: MQTT.TLS.CA ? filesystem.readFileSync(MQTT.TLS.CA) : null, + rejectUnauthorized: MQTT.TLS.REJECT_UNAUTHORIZED === true, + }); + + CLIENT.on('connect', () => { + logStatus('connected', console.log); + this.publish({ topic: 'double-take/errors' }); + this.available('online'); + this.subscribe(); + }) + .on('error', (err) => logStatus(err.message, console.error)) + .on('offline', () => logStatus('offline', console.error)) + .on('disconnect', () => logStatus('disconnected', console.error)) + .on('reconnect', () => logStatus('reconnecting', console.warn)) + .on('message', async (topic, message) => processMessage({ topic, message }).init()); + } catch (error) { + logStatus(error.message, console.error); + } }; module.exports.available = async (state) => {