mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-24 06:05:53 -05:00
Improved dependency management, main web port now uses TLS 1.2 only.
This commit is contained in:
parent
682573d262
commit
49927f0abc
2
db.js
2
db.js
@ -25,7 +25,7 @@ module.exports.CreateDB = function (args, datapath) {
|
|||||||
if (args.mongodb) {
|
if (args.mongodb) {
|
||||||
// Use MongoDB
|
// Use MongoDB
|
||||||
obj.databaseType = 2;
|
obj.databaseType = 2;
|
||||||
var Datastore = require("mongojs");
|
var Datastore = require('mongojs');
|
||||||
var db = Datastore(args.mongodb);
|
var db = Datastore(args.mongodb);
|
||||||
var dbcollection = 'meshcentral';
|
var dbcollection = 'meshcentral';
|
||||||
if (args.mongodbcol) { dbcollection = args.mongodbcol; }
|
if (args.mongodbcol) { dbcollection = args.mongodbcol; }
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
// If app metrics is available
|
// If app metrics is available
|
||||||
if (process.argv[2] == '--launch') { try { require('appmetrics-dash').monitor({ url: '/', title: 'MeshCentral', port: 88, host: '127.0.0.1' }); } catch (e) { } }
|
if (process.argv[2] == '--launch') { try { require('appmetrics-dash').monitor({ url: '/', title: 'MeshCentral', port: 88, host: '127.0.0.1' }); } catch (e) { } }
|
||||||
|
|
||||||
function CreateMeshCentralServer() {
|
function CreateMeshCentralServer(config) {
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.db;
|
obj.db;
|
||||||
obj.webserver;
|
obj.webserver;
|
||||||
@ -33,7 +33,7 @@ function CreateMeshCentralServer() {
|
|||||||
obj.connectivityByNode = {}; // This object keeps a list of all connected CIRA and agents, by nodeid->value (value: 1 = Agent, 2 = CIRA, 4 = AmtDirect)
|
obj.connectivityByNode = {}; // This object keeps a list of all connected CIRA and agents, by nodeid->value (value: 1 = Agent, 2 = CIRA, 4 = AmtDirect)
|
||||||
obj.peerConnectivityByNode = {}; // This object keeps a list of all connected CIRA and agents of peers, by serverid->nodeid->value (value: 1 = Agent, 2 = CIRA, 4 = AmtDirect)
|
obj.peerConnectivityByNode = {}; // This object keeps a list of all connected CIRA and agents of peers, by serverid->nodeid->value (value: 1 = Agent, 2 = CIRA, 4 = AmtDirect)
|
||||||
obj.debugLevel = 0;
|
obj.debugLevel = 0;
|
||||||
obj.config = {}; // Configuration file
|
obj.config = config; // Configuration file
|
||||||
obj.dbconfig = {}; // Persistance values, loaded from database
|
obj.dbconfig = {}; // Persistance values, loaded from database
|
||||||
obj.certificateOperations = null;
|
obj.certificateOperations = null;
|
||||||
obj.defaultMeshCmd = null;
|
obj.defaultMeshCmd = null;
|
||||||
@ -82,6 +82,7 @@ function CreateMeshCentralServer() {
|
|||||||
var validArguments = ['_', 'notls', 'user', 'port', 'mpsport', 'redirport', 'cert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'shownodes', 'showmeshes', 'showevents', 'showpower', 'clearpower', 'showiplocations', 'help', 'exactports', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpsdebug', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbimport', 'selfupdate', 'tlsoffload', 'userallowedip', 'fastcert', 'swarmport', 'swarmdebug', 'logintoken', 'logintokenkey', 'logintokengen', 'logintokengen', 'mailtokengen'];
|
var validArguments = ['_', 'notls', 'user', 'port', 'mpsport', 'redirport', 'cert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'shownodes', 'showmeshes', 'showevents', 'showpower', 'clearpower', 'showiplocations', 'help', 'exactports', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpsdebug', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbimport', 'selfupdate', 'tlsoffload', 'userallowedip', 'fastcert', 'swarmport', 'swarmdebug', 'logintoken', 'logintokenkey', 'logintokengen', 'logintokengen', 'mailtokengen'];
|
||||||
for (var arg in obj.args) { obj.args[arg.toLocaleLowerCase()] = obj.args[arg]; if (validArguments.indexOf(arg.toLocaleLowerCase()) == -1) { console.log('Invalid argument "' + arg + '", use --help.'); return; } }
|
for (var arg in obj.args) { obj.args[arg.toLocaleLowerCase()] = obj.args[arg]; if (validArguments.indexOf(arg.toLocaleLowerCase()) == -1) { console.log('Invalid argument "' + arg + '", use --help.'); return; } }
|
||||||
if (obj.args.mongodb == true) { console.log('Must specify: --mongodb [connectionstring] \r\nSee https://docs.mongodb.com/manual/reference/connection-string/ for MongoDB connection string.'); return; }
|
if (obj.args.mongodb == true) { console.log('Must specify: --mongodb [connectionstring] \r\nSee https://docs.mongodb.com/manual/reference/connection-string/ for MongoDB connection string.'); return; }
|
||||||
|
for (var i in obj.config.settings) { obj.args[i] = obj.config.settings[i]; } // Place all settings into arguments, arguments have already been placed into settings so arguments take precedence.
|
||||||
|
|
||||||
if ((obj.args.help == true) || (obj.args['?'] == true)) {
|
if ((obj.args.help == true) || (obj.args['?'] == true)) {
|
||||||
console.log('MeshCentral2 Beta 2, a web-based remote computer management web portal.\r\n');
|
console.log('MeshCentral2 Beta 2, a web-based remote computer management web portal.\r\n');
|
||||||
@ -198,22 +199,6 @@ function CreateMeshCentralServer() {
|
|||||||
// Look to see if data and/or file path is specified
|
// Look to see if data and/or file path is specified
|
||||||
if (obj.args.datapath) { obj.datapath = obj.args.datapath; }
|
if (obj.args.datapath) { obj.datapath = obj.args.datapath; }
|
||||||
if (obj.args.filespath) { obj.filespath = obj.args.filespath; }
|
if (obj.args.filespath) { obj.filespath = obj.args.filespath; }
|
||||||
|
|
||||||
// Read configuration file if present and change arguments.
|
|
||||||
var configFilePath = obj.path.join(obj.datapath, 'config.json');
|
|
||||||
if (obj.fs.existsSync(configFilePath)) {
|
|
||||||
// Load and validate the configuration file
|
|
||||||
try { obj.config = require(configFilePath); } catch (e) { console.log('ERROR: Unable to parse ' + configFilePath + '.'); return; }
|
|
||||||
if (obj.config.domains == null) { obj.config.domains = {}; }
|
|
||||||
for (var i in obj.config.domains) { if ((i.split('/').length > 1) || (i.split(' ').length > 1)) { console.log("ERROR: Error in config.json, domain names can't have spaces or /."); return; } }
|
|
||||||
// Set the command line arguments to the config file if they are not present
|
|
||||||
if (obj.config.settings) { for (var i in obj.config.settings) { if (obj.args[i] == null) obj.args[i] = obj.config.settings[i]; } }
|
|
||||||
} else {
|
|
||||||
// Copy the "sample-config.json" to give users a starting point
|
|
||||||
var sampleConfigPath = obj.path.join(__dirname, 'sample-config.json');
|
|
||||||
if (obj.fs.existsSync(sampleConfigPath)) { obj.fs.createReadStream(sampleConfigPath).pipe(obj.fs.createWriteStream(configFilePath)); }
|
|
||||||
}
|
|
||||||
obj.common.objKeysToLower(obj.config); // Lower case all keys in the config file
|
|
||||||
|
|
||||||
// Read environment variables. For a subset of arguments, we allow them to be read from environment variables.
|
// Read environment variables. For a subset of arguments, we allow them to be read from environment variables.
|
||||||
var xenv = ['user', 'port', 'mpsport', 'redirport', 'exactport', 'debug'];
|
var xenv = ['user', 'port', 'mpsport', 'redirport', 'exactport', 'debug'];
|
||||||
@ -1033,10 +1018,49 @@ function CreateMeshCentralServer() {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the server configuration
|
||||||
|
function getConfig() {
|
||||||
|
// Figure out the datapath location
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
var datapath = null;
|
||||||
|
var args = require('minimist')(process.argv.slice(2));
|
||||||
|
if ((__dirname.endsWith('/node_modules/meshcentral')) || (__dirname.endsWith('\\node_modules\\meshcentral')) || (__dirname.endsWith('/node_modules/meshcentral/')) || (__dirname.endsWith('\\node_modules\\meshcentral\\'))) {
|
||||||
|
datapath = path.join(__dirname, '../../meshcentral-data');
|
||||||
|
} else {
|
||||||
|
datapath = path.join(__dirname, '../meshcentral-data');
|
||||||
|
}
|
||||||
|
if (args.datapath) { datapath = args.datapath; }
|
||||||
|
try { fs.mkdirSync(datapath); } catch (e) { }
|
||||||
|
|
||||||
|
// Read configuration file if present and change arguments.
|
||||||
|
var config = {}, configFilePath = path.join(datapath, 'config.json');
|
||||||
|
if (fs.existsSync(configFilePath)) {
|
||||||
|
// Load and validate the configuration file
|
||||||
|
try { config = require(configFilePath); } catch (e) { console.log('ERROR: Unable to parse ' + configFilePath + '.'); return null; }
|
||||||
|
if (config.domains == null) { config.domains = {}; }
|
||||||
|
for (var i in config.domains) { if ((i.split('/').length > 1) || (i.split(' ').length > 1)) { console.log("ERROR: Error in config.json, domain names can't have spaces or /."); return null; } }
|
||||||
|
} else {
|
||||||
|
// Copy the "sample-config.json" to give users a starting point
|
||||||
|
var sampleConfigPath = path.join(__dirname, 'sample-config.json');
|
||||||
|
if (fs.existsSync(sampleConfigPath)) { fs.createReadStream(sampleConfigPath).pipe(fs.createWriteStream(configFilePath)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the command line arguments to the config file if they are not present
|
||||||
|
if (!config.settings) { config.settings = {}; }
|
||||||
|
for (var i in args) { config.settings[i] = args[i]; }
|
||||||
|
|
||||||
|
// Lower case all keys in the config file
|
||||||
|
require('./common.js').objKeysToLower(config);
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a list of modules are present and install any missing ones
|
||||||
function InstallModules(modules, func) {
|
function InstallModules(modules, func) {
|
||||||
if (modules.length > 0) { InstallModule(modules.shift(), InstallModules, modules, func); } else { func(); }
|
if (modules.length > 0) { InstallModule(modules.shift(), InstallModules, modules, func); } else { func(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if a module is present and install it if missing
|
||||||
function InstallModule(modulename, func, tag1, tag2) {
|
function InstallModule(modulename, func, tag1, tag2) {
|
||||||
try {
|
try {
|
||||||
var module = require(modulename);
|
var module = require(modulename);
|
||||||
@ -1057,10 +1081,20 @@ function InstallModule(modulename, func, tag1, tag2) {
|
|||||||
// Detect CTRL-C on Linux and stop nicely
|
// Detect CTRL-C on Linux and stop nicely
|
||||||
process.on('SIGINT', function () { if (meshserver != null) { meshserver.Stop(); meshserver = null; } console.log('Server Ctrl-C exit...'); process.exit(); });
|
process.on('SIGINT', function () { if (meshserver != null) { meshserver.Stop(); meshserver = null; } console.log('Server Ctrl-C exit...'); process.exit(); });
|
||||||
|
|
||||||
// Build the list of required modules
|
// Load the really basic modules
|
||||||
var modules = ['nedb', 'https', 'unzip', 'xmldom', 'express', 'mongojs', 'archiver', 'minimist', 'nodemailer', 'multiparty', 'node-forge', 'express-ws', 'compression', 'body-parser', 'connect-redis', 'express-session', 'express-handlebars'];
|
|
||||||
if (require('os').platform() == 'win32') { modules.push("node-sspi"); modules.push("node-windows"); }
|
|
||||||
|
|
||||||
// Run as a command line, if we are not using service arguments, don't need to install the service package.
|
|
||||||
var meshserver = null;
|
var meshserver = null;
|
||||||
InstallModules(modules, function () { meshserver = CreateMeshCentralServer(); meshserver.Start(); });
|
InstallModules(['minimist'], function () {
|
||||||
|
// Get the server configuration
|
||||||
|
var config = getConfig();
|
||||||
|
if (config == null) { process.exit(); }
|
||||||
|
|
||||||
|
// Build the list of required modules
|
||||||
|
var modules = ['ws', 'nedb', 'https', 'unzip', 'xmldom', 'express', 'mongojs', 'archiver', 'multiparty', 'node-forge', 'express-ws', 'compression', 'body-parser', 'connect-redis', 'express-session', 'express-handlebars'];
|
||||||
|
if (require('os').platform() == 'win32') { modules.push('node-sspi'); modules.push('node-windows'); } // Add Windows modules
|
||||||
|
if (config.letsencrypt != null) { modules.push('greenlock'); modules.push('le-store-certbot'); modules.push('le-challenge-fs'); modules.push('le-acme-core'); } // Add Greenlock Modules
|
||||||
|
if (config.settings.mongodb != null) { modules.push('mongojs'); } // Add MongoDB
|
||||||
|
if (config.smtp != null) { modules.push('nodemailer'); } // Add SMTP support
|
||||||
|
|
||||||
|
// Install any missing modules and launch the server
|
||||||
|
InstallModules(modules, function () { meshserver = CreateMeshCentralServer(config); meshserver.Start(); });
|
||||||
|
});
|
||||||
|
18
package.json
18
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "meshcentral",
|
"name": "meshcentral",
|
||||||
"version": "0.1.3-r",
|
"version": "0.1.3-v",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Remote Management",
|
"Remote Management",
|
||||||
"Intel AMT",
|
"Intel AMT",
|
||||||
@ -29,32 +29,20 @@
|
|||||||
"archiver": "^1.3.0",
|
"archiver": "^1.3.0",
|
||||||
"body-parser": "^1.18.2",
|
"body-parser": "^1.18.2",
|
||||||
"compression": "^1.7.1",
|
"compression": "^1.7.1",
|
||||||
"connect-redis": "^3.3.2",
|
"connect-redis": "^3.3.3",
|
||||||
"express": "^4.16.2",
|
"express": "^4.16.2",
|
||||||
"express-handlebars": "^3.0.0",
|
"express-handlebars": "^3.0.0",
|
||||||
"express-session": "^1.15.6",
|
"express-session": "^1.15.6",
|
||||||
"express-ws": "^2.0.0",
|
"express-ws": "^2.0.0",
|
||||||
"meshcentral": "*",
|
"meshcentral": "*",
|
||||||
"minimist": "^1.2.0",
|
"minimist": "^1.2.0",
|
||||||
"mongojs": "^2.4.1",
|
|
||||||
"multiparty": "^4.1.3",
|
"multiparty": "^4.1.3",
|
||||||
"nedb": "^1.8.0",
|
"nedb": "^1.8.0",
|
||||||
"node-forge": "^0.6.49",
|
"node-forge": "^0.6.49",
|
||||||
"node-windows": "^0.1.14",
|
|
||||||
"nodemailer": "^4.4.1",
|
|
||||||
"unzip": "^0.1.11",
|
"unzip": "^0.1.11",
|
||||||
"ws": "^3.2.0",
|
"ws": "^3.3.3",
|
||||||
"xmldom": "^0.1.27"
|
"xmldom": "^0.1.27"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
|
||||||
"node-sspi": "^0.2.2",
|
|
||||||
"node-windows": "^0.1.14",
|
|
||||||
"mongojs": "^2.4.0",
|
|
||||||
"greenlock": "^2.1.18",
|
|
||||||
"le-store-certbot": "^2.0.5",
|
|
||||||
"le-challenge-fs": "^2.0.8",
|
|
||||||
"le-acme-core": "^2.1.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
"readme": "readme.txt"
|
"readme": "readme.txt"
|
||||||
}
|
}
|
||||||
|
13
webserver.js
13
webserver.js
@ -72,7 +72,6 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||||||
obj.tlsSniCredentials;
|
obj.tlsSniCredentials;
|
||||||
obj.dnsDomains = {};
|
obj.dnsDomains = {};
|
||||||
|
|
||||||
|
|
||||||
// Mesh Rights
|
// Mesh Rights
|
||||||
const MESHRIGHT_EDITMESH = 1;
|
const MESHRIGHT_EDITMESH = 1;
|
||||||
const MESHRIGHT_MANAGEUSERS = 2;
|
const MESHRIGHT_MANAGEUSERS = 2;
|
||||||
@ -140,14 +139,10 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||||||
// Setup the HTTP server without TLS
|
// Setup the HTTP server without TLS
|
||||||
obj.expressWs = require('express-ws')(obj.app);
|
obj.expressWs = require('express-ws')(obj.app);
|
||||||
} else {
|
} else {
|
||||||
// Setup the HTTP server with TLS
|
// Setup the HTTP server with TLS, use only TLS 1.2 and higher.
|
||||||
if (obj.tlsSniCredentials != null) {
|
var tlsOptions = { cert: obj.certificates.web.cert, key: obj.certificates.web.key, ca: obj.certificates.web.ca, rejectUnauthorized: true, secureOptions: obj.constants.SSL_OP_NO_SSLv2 | obj.constants.SSL_OP_NO_SSLv3 | obj.constants.SSL_OP_NO_COMPRESSION | obj.constants.SSL_OP_CIPHER_SERVER_PREFERENCE | obj.constants.SSL_OP_NO_TLSv1 | obj.constants.SSL_OP_NO_TLSv11 };
|
||||||
// We have multiple web server certificate used depending on the domain name
|
if (obj.tlsSniCredentials != null) { tlsOptions.SNICallback = TlsSniCallback; } // We have multiple web server certificate used depending on the domain name
|
||||||
obj.tlsServer = require('https').createServer({ SNICallback: TlsSniCallback, cert: obj.certificates.web.cert, key: obj.certificates.web.key, ca: obj.certificates.web.ca, rejectUnauthorized: true }, obj.app);
|
obj.tlsServer = require('https').createServer(tlsOptions, obj.app);
|
||||||
} else {
|
|
||||||
// We have a single web server certificate
|
|
||||||
obj.tlsServer = require('https').createServer({ cert: obj.certificates.web.cert, key: obj.certificates.web.key, ca: obj.certificates.web.ca, rejectUnauthorized: true }, obj.app);
|
|
||||||
}
|
|
||||||
obj.expressWs = require('express-ws')(obj.app, obj.tlsServer);
|
obj.expressWs = require('express-ws')(obj.app, obj.tlsServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user