Added support for Crowdsec, an open-source and collaborative IPS (Intrusion Prevention System)
This commit is contained in:
parent
79d32b62e3
commit
947d9094cb
|
@ -159,7 +159,7 @@
|
||||||
"agentBlockedIP": { "type": [ "string", "array" ], "default": null, "description": "When set, agents from these denied IP address ranges will not be able to connect to the server. Example: \"192.168.2.100,192.168.1.0/24\"" },
|
"agentBlockedIP": { "type": [ "string", "array" ], "default": null, "description": "When set, agents from these denied IP address ranges will not be able to connect to the server. Example: \"192.168.2.100,192.168.1.0/24\"" },
|
||||||
"authLog": { "type": "string", "default": null, "description": "File path and name of the authentication log to be created. This log can be parsed by Fail2ban." },
|
"authLog": { "type": "string", "default": null, "description": "File path and name of the authentication log to be created. This log can be parsed by Fail2ban." },
|
||||||
"InterUserMessaging": { "type": "array", "uniqueItems": true, "items": { "type": "string" }, "description": "Users in this list are allowed to send and receive inter-user messages. This can be used to implement bots or other software where MeshCentral is used as data transport. See \"interuser\" websocket command in the code." },
|
"InterUserMessaging": { "type": "array", "uniqueItems": true, "items": { "type": "string" }, "description": "Users in this list are allowed to send and receive inter-user messages. This can be used to implement bots or other software where MeshCentral is used as data transport. See \"interuser\" websocket command in the code." },
|
||||||
"manageAllDeviceGroups": { "type": "array", "uniqueItems": true, "items": { "type": "string" }, "description": "Users in this list are allowed to see and manage all device groups within their domain." },
|
"manageAllDeviceGroups": { "type": "array", "uniqueItems": true, "items": { "type": " string" }, "description": "Users in this list are allowed to see and manage all device groups within their domain." },
|
||||||
"manageCrossDomain": { "type": "array", "uniqueItems": true, "items": { "type": "string" }, "description": "Users in this list are allowed to manage all users in all domains." },
|
"manageCrossDomain": { "type": "array", "uniqueItems": true, "items": { "type": "string" }, "description": "Users in this list are allowed to manage all users in all domains." },
|
||||||
"localDiscovery": {
|
"localDiscovery": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
@ -195,6 +195,16 @@
|
||||||
},
|
},
|
||||||
"required": [ "iceServers" ]
|
"required": [ "iceServers" ]
|
||||||
},
|
},
|
||||||
|
"crowdsec": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true,
|
||||||
|
"description": "Enabled the MeshCentral built-in Crowdsec bouncer. This section is passed directly to the bouncer, all of the settings are documented at https://www.npmjs.com/package/@crowdsec/express-bouncer",
|
||||||
|
"properties": {
|
||||||
|
"url": { "type": "string", "description": "The URL of your LAPI instance. Ex: http://localhost:8080" },
|
||||||
|
"apiKey": { "type": "string", "description": "The bouncer key (generated via cscli)" }
|
||||||
|
},
|
||||||
|
"required": [ "url", "apiKey" ]
|
||||||
|
},
|
||||||
"autoBackup": {
|
"autoBackup": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -698,7 +698,7 @@ function CreateMeshCentralServer(config, args) {
|
||||||
obj.args = args = config2.settings;
|
obj.args = args = config2.settings;
|
||||||
|
|
||||||
// Lower case all keys in the config file
|
// Lower case all keys in the config file
|
||||||
obj.common.objKeysToLower(config2, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate', 'httpheaders']);
|
obj.common.objKeysToLower(config2, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate', 'httpheaders', 'crowdsec']);
|
||||||
|
|
||||||
// Grad some of the values from the original config.json file if present.
|
// Grad some of the values from the original config.json file if present.
|
||||||
if ((config.settings.vault != null) && (config2.settings != null)) { config2.settings.vault = config.settings.vault; }
|
if ((config.settings.vault != null) && (config2.settings != null)) { config2.settings.vault = config.settings.vault; }
|
||||||
|
@ -1196,7 +1196,7 @@ function CreateMeshCentralServer(config, args) {
|
||||||
for (i in args) { config2.settings[i] = args[i]; }
|
for (i in args) { config2.settings[i] = args[i]; }
|
||||||
|
|
||||||
// Lower case all keys in the config file
|
// Lower case all keys in the config file
|
||||||
common.objKeysToLower(config2, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate', 'httpheaders']);
|
common.objKeysToLower(config2, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate', 'httpheaders', 'crowdsec']);
|
||||||
|
|
||||||
// Grad some of the values from the original config.json file if present.
|
// Grad some of the values from the original config.json file if present.
|
||||||
config2['mysql'] = config['mysql'];
|
config2['mysql'] = config['mysql'];
|
||||||
|
@ -1219,7 +1219,7 @@ function CreateMeshCentralServer(config, args) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Time to start the server of real.
|
// Time to start the server of real.
|
||||||
obj.StartEx1b = function () {
|
obj.StartEx1b = async function () {
|
||||||
var i;
|
var i;
|
||||||
|
|
||||||
// Setup certificate operations
|
// Setup certificate operations
|
||||||
|
@ -1232,6 +1232,12 @@ function CreateMeshCentralServer(config, args) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start CrowdSec bouncer if needed: https://www.crowdsec.net/
|
||||||
|
if (typeof obj.args.crowdsec == 'object') {
|
||||||
|
const expressCrowdsecBouncer = require("@crowdsec/express-bouncer");
|
||||||
|
try { obj.crowdsecMiddleware = await expressCrowdsecBouncer(obj.args.crowdsec); } catch (ex) { delete obj.crowdsecMiddleware; }
|
||||||
|
}
|
||||||
|
|
||||||
// Check if self update is allowed. If running as a Windows service, self-update is not possible.
|
// Check if self update is allowed. If running as a Windows service, self-update is not possible.
|
||||||
if (obj.fs.existsSync(obj.path.join(__dirname, 'daemon'))) { obj.serverSelfWriteAllowed = false; }
|
if (obj.fs.existsSync(obj.path.join(__dirname, 'daemon'))) { obj.serverSelfWriteAllowed = false; }
|
||||||
|
|
||||||
|
@ -3515,7 +3521,7 @@ function getConfig(createSampleConfig) {
|
||||||
|
|
||||||
// Lower case all keys in the config file
|
// Lower case all keys in the config file
|
||||||
try {
|
try {
|
||||||
require('./common.js').objKeysToLower(config, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate', 'httpheaders']);
|
require('./common.js').objKeysToLower(config, ['ldapoptions', 'defaultuserwebstate', 'forceduserwebstate', 'httpheaders', 'crowdsec']);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
console.log('CRITICAL ERROR: Unable to access the file \"./common.js\".\r\nCheck folder & file permissions.');
|
console.log('CRITICAL ERROR: Unable to access the file \"./common.js\".\r\nCheck folder & file permissions.');
|
||||||
process.exit();
|
process.exit();
|
||||||
|
@ -3713,6 +3719,7 @@ function mainStart() {
|
||||||
if (nodemailer || (config.smtp != null) || (config.sendmail != null)) { modules.push('nodemailer'); } // Add SMTP support
|
if (nodemailer || (config.smtp != null) || (config.sendmail != null)) { modules.push('nodemailer'); } // Add SMTP support
|
||||||
if (sendgrid || (config.sendgrid != null)) { modules.push('@sendgrid/mail'); } // Add SendGrid support
|
if (sendgrid || (config.sendgrid != null)) { modules.push('@sendgrid/mail'); } // Add SendGrid support
|
||||||
if (args.translate) { modules.push('jsdom'); modules.push('esprima'); modules.push('minify-js'); modules.push('html-minifier'); } // Translation support
|
if (args.translate) { modules.push('jsdom'); modules.push('esprima'); modules.push('minify-js'); modules.push('html-minifier'); } // Translation support
|
||||||
|
if (typeof config.settings.crowdsec == 'object') { modules.push('@crowdsec/express-bouncer'); } // Add CrowdSec bounser module (https://www.npmjs.com/package/@crowdsec/express-bouncer)
|
||||||
|
|
||||||
// Setup encrypted zip support if needed
|
// Setup encrypted zip support if needed
|
||||||
if (config.settings.autobackup && config.settings.autobackup.zippassword) {
|
if (config.settings.autobackup && config.settings.autobackup.zippassword) {
|
||||||
|
|
14
package.json
14
package.json
|
@ -37,6 +37,8 @@
|
||||||
"sample-config-advanced.json"
|
"sample-config-advanced.json"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@crowdsec/express-bouncer": "^0.1.0",
|
||||||
|
"@yetzt/nedb": "^1.8.0",
|
||||||
"archiver": "^5.3.1",
|
"archiver": "^5.3.1",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"cbor": "~5.2.0",
|
"cbor": "~5.2.0",
|
||||||
|
@ -45,13 +47,21 @@
|
||||||
"express": "^4.17.0",
|
"express": "^4.17.0",
|
||||||
"express-handlebars": "^5.3.5",
|
"express-handlebars": "^5.3.5",
|
||||||
"express-ws": "^4.0.0",
|
"express-ws": "^4.0.0",
|
||||||
|
"image-size": "^1.0.1",
|
||||||
"ipcheck": "^0.1.0",
|
"ipcheck": "^0.1.0",
|
||||||
|
"loadavg-windows": "^1.1.1",
|
||||||
"minimist": "^1.2.5",
|
"minimist": "^1.2.5",
|
||||||
"multiparty": "^4.2.1",
|
"multiparty": "^4.2.1",
|
||||||
"@yetzt/nedb": "^1.8.0",
|
|
||||||
"node-forge": "^1.0.0",
|
"node-forge": "^1.0.0",
|
||||||
|
"node-windows": "^0.1.4",
|
||||||
|
"otplib": "^10.2.3",
|
||||||
|
"pg": "^8.7.1",
|
||||||
|
"pgtools": "^0.3.2",
|
||||||
|
"ssh2": "^1.11.0",
|
||||||
|
"web-push": "^3.5.0",
|
||||||
"ws": "^5.2.3",
|
"ws": "^5.2.3",
|
||||||
"yauzl": "^2.10.0"
|
"yauzl": "^2.10.0",
|
||||||
|
"yubikeyotp": "^0.2.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
|
|
|
@ -39,6 +39,9 @@ module.exports.CreateRedirServer = function (parent, db, args, func) {
|
||||||
res.redirect('https://' + host + ':' + httpsPort + req.url);
|
res.redirect('https://' + host + ':' + httpsPort + req.url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup CrowdSec bouncer middleware if needed
|
||||||
|
if (parent.crowdsecMiddleware != null) { obj.app.use(parent.crowdsecMiddleware); }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Return the current domain of the request
|
// Return the current domain of the request
|
||||||
function getDomain(req) {
|
function getDomain(req) {
|
||||||
|
|
|
@ -154,6 +154,10 @@
|
||||||
"trustedFqdn": "sample.com",
|
"trustedFqdn": "sample.com",
|
||||||
"ip": "192.168.1.1"
|
"ip": "192.168.1.1"
|
||||||
},
|
},
|
||||||
|
"_crowdsec": {
|
||||||
|
"url": "http://localhost:8080",
|
||||||
|
"apiKey": "BOUNCER_API_KEY"
|
||||||
|
},
|
||||||
"_plugins": { "enabled": true }
|
"_plugins": { "enabled": true }
|
||||||
},
|
},
|
||||||
"_domaindefaults": {
|
"_domaindefaults": {
|
||||||
|
|
|
@ -36,6 +36,9 @@ module.exports.CreateWebRelayServer = function (parent, db, args, certificates,
|
||||||
var tlsSessionStoreCount = 0; // Number of cached TLS session information in store.
|
var tlsSessionStoreCount = 0; // Number of cached TLS session information in store.
|
||||||
|
|
||||||
function serverStart() {
|
function serverStart() {
|
||||||
|
// Setup CrowdSec bouncer middleware if needed
|
||||||
|
if (parent.crowdsecMiddleware != null) { obj.app.use(parent.crowdsecMiddleware); }
|
||||||
|
|
||||||
if (args.trustedproxy) {
|
if (args.trustedproxy) {
|
||||||
// Reverse proxy should add the "X-Forwarded-*" headers
|
// Reverse proxy should add the "X-Forwarded-*" headers
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -5706,9 +5706,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
|
||||||
obj.tlsAltServer.on('resumeSession', function (id, cb) { cb(null, tlsSessionStore[id.toString('hex')] || null); });
|
obj.tlsAltServer.on('resumeSession', function (id, cb) { cb(null, tlsSessionStore[id.toString('hex')] || null); });
|
||||||
obj.expressWsAlt = require('express-ws')(obj.agentapp, obj.tlsAltServer, { wsOptions: { perMessageDeflate: (args.wscompression === true) } });
|
obj.expressWsAlt = require('express-ws')(obj.agentapp, obj.tlsAltServer, { wsOptions: { perMessageDeflate: (args.wscompression === true) } });
|
||||||
}
|
}
|
||||||
|
if (parent.crowdsecMiddleware != null) { obj.agentapp.use(parent.crowdsecMiddleware); } // Setup CrowdSec bouncer middleware if needed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup middleware
|
// Setup middleware
|
||||||
|
if (parent.crowdsecMiddleware != null) { obj.app.use(parent.crowdsecMiddleware); } // Setup CrowdSec bouncer middleware if needed
|
||||||
obj.app.engine('handlebars', obj.exphbs({ defaultLayout: false }));
|
obj.app.engine('handlebars', obj.exphbs({ defaultLayout: false }));
|
||||||
obj.app.set('view engine', 'handlebars');
|
obj.app.set('view engine', 'handlebars');
|
||||||
if (obj.args.trustedproxy) {
|
if (obj.args.trustedproxy) {
|
||||||
|
|
Loading…
Reference in New Issue