From e8fccb984ccc3eb194bdd8b6da75d6c6ea6b868c Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Wed, 30 Dec 2020 16:54:02 -0800 Subject: [PATCH] Can now specify IP and IP range for ignoreAgentHashCheck. --- meshagent.js | 23 ++++++++++++++++++++++- meshcentral-config-schema.json | 4 ++-- meshcentral.js | 10 ++++++---- package.json | 1 - 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/meshagent.js b/meshagent.js index 6f095234..e83e1631 100644 --- a/meshagent.js +++ b/meshagent.js @@ -402,7 +402,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { if ((msg.length != 98) || ((obj.receivedCommands & 1) != 0)) return; obj.receivedCommands += 1; // Agent can't send the same command twice on the same connection ever. Block DOS attack path. - if ((args.ignoreagenthashcheck === true) || (domain.ignoreagenthashcheck === true)) { + if (isIgnoreHashCheck()) { // Send the agent web hash back to the agent // Send 384 bits SHA384 hash of TLS cert + 384 bits nonce obj.sendBinary(common.ShortToStr(1) + msg.substring(2, 50) + obj.nonce); // Command 1, hash + nonce. Use the web hash given by the agent. @@ -1680,6 +1680,27 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { obj.send('{"action":"msg","type":"tunnel","value":"*/' + (((domain.dns == null) && (domain.id != '')) ? (domain.id + '/') : '') + 'agenttransfer.ashx?c=' + cookie + '","rights":"4294967295"}'); } + // Return true if we need to ignore the agent hash check + function isIgnoreHashCheck() { + if ((args.ignoreagenthashcheck === true) || (domain.ignoreagenthashcheck === true)) return true; + + // Check site wide exceptions + if (Array.isArray(args.ignoreagenthashcheck)) { + for (var i = 0; i < args.ignoreagenthashcheck.length; i++) { + if (require('ipcheck').match(obj.remoteaddr, args.ignoreagenthashcheck[i])) return true; + } + } + + // Check domain wide exceptions + if (Array.isArray(domain.ignoreagenthashcheck)) { + for (var i = 0; i < domain.ignoreagenthashcheck.length; i++) { + if (require('ipcheck').match(obj.remoteaddr, domain.ignoreagenthashcheck[i])) return true; + } + } + + return false; + } + // Generate a random Intel AMT password function checkAmtPassword(p) { return (p.length > 7) && (/\d/.test(p)) && (/[a-z]/.test(p)) && (/[A-Z]/.test(p)) && (/\W/.test(p)); } function getRandomAmtPassword() { var p; do { p = Buffer.from(parent.crypto.randomBytes(9), 'binary').toString('base64').split('/').join('@'); } while (checkAmtPassword(p) == false); return p; } diff --git a/meshcentral-config-schema.json b/meshcentral-config-schema.json index 44ed93fd..6e1687fd 100644 --- a/meshcentral-config-schema.json +++ b/meshcentral-config-schema.json @@ -42,7 +42,7 @@ "agentPortTls": { "type": "boolean", "default": true, "description": "Indicates if the agent-only port must perform TLS, this should be set to false if TLS is performed in front of this server." }, "agentCoreDump": { "type": "boolean", "default": false, "description": "Automatically activates and transfers any agent crash dump files to the server in meshcentral-data/coredumps." }, "agentCoreDumpUsers": { "type": "array", "description": "List of non-administrator users that have access to mesh agent crash dumps." }, - "ignoreAgentHashCheck": { "type": "boolean", "default": false, "description": "When true, the agent no longer checked the TLS certificate of the server. This should be used for debugging only." }, + "ignoreAgentHashCheck": { "type": [ "boolean", "string" ], "default": false, "description": "When true, the agent no longer checked the TLS certificate of the server. This should be used for debugging only. You can also set this to a comma seperated list of IP addresses to ignore, for example: \"192.168.2.100,192.168.1.0/24\"." }, "exactPorts": { "type": "boolean", "default": false }, "allowLoginToken": { "type": "boolean", "default": false }, "allowFraming": { "type": "boolean", "default": false, "description": "When enabled, the MeshCentral web site can be embedded within another website's iframe." }, @@ -85,7 +85,7 @@ }, "required": [ "name", "info" ] }, - "tlsOffload": { "type": [ "string", "boolean" ], "default": false }, + "tlsOffload": { "type": [ "boolean", "string" ], "default": false, "description": "When true, indicates that a TLS offloader is in front of the MeshCentral server. More typically, set this to the IP address of the reverse proxy or TLS offloader so that IP forwarding headers will be trusted. For example: \"127.0.0.1,192.168.1.100\"." }, "trustedProxy": { "type": "string" }, "mpsPort": { "type": "integer", "minimum": 1, "maximum": 65535 }, "mpsPortBind": { "type": "string" }, diff --git a/meshcentral.js b/meshcentral.js index cc0ec250..db172193 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -1096,10 +1096,11 @@ function CreateMeshCentralServer(config, args) { obj.config.domains[i].id = i; if (typeof obj.config.domains[i].loginkey == 'string') { obj.config.domains[i].loginkey = [obj.config.domains[i].loginkey]; } if ((obj.config.domains[i].loginkey != null) && (obj.common.validateAlphaNumericArray(obj.config.domains[i].loginkey, 1, 128) == false)) { console.log("ERROR: Invalid login key, must be alpha-numeric string with no spaces."); process.exit(); return; } - if (typeof obj.config.domains[i].userallowedip == 'string') { if (obj.config.domains[i].userallowedip == '') { obj.config.domains[i].userallowedip = null; } else { obj.config.domains[i].userallowedip = obj.config.domains[i].userallowedip.split(','); } } - if (typeof obj.config.domains[i].userblockedip == 'string') { if (obj.config.domains[i].userblockedip == '') { obj.config.domains[i].userblockedip = null; } else { obj.config.domains[i].userblockedip = obj.config.domains[i].userblockedip.split(','); } } - if (typeof obj.config.domains[i].agentallowedip == 'string') { if (obj.config.domains[i].agentallowedip == '') { obj.config.domains[i].agentallowedip = null; } else { obj.config.domains[i].agentallowedip = obj.config.domains[i].agentallowedip.split(','); } } - if (typeof obj.config.domains[i].agentblockedip == 'string') { if (obj.config.domains[i].agentblockedip == '') { obj.config.domains[i].agentblockedip = null; } else { obj.config.domains[i].agentblockedip = obj.config.domains[i].agentblockedip.split(','); } } + if (typeof obj.config.domains[i].userallowedip == 'string') { if (obj.config.domains[i].userallowedip == '') { delete obj.config.domains[i].userallowedip; } else { obj.config.domains[i].userallowedip = obj.config.domains[i].userallowedip.split(','); } } + if (typeof obj.config.domains[i].userblockedip == 'string') { if (obj.config.domains[i].userblockedip == '') { delete obj.config.domains[i].userblockedip; } else { obj.config.domains[i].userblockedip = obj.config.domains[i].userblockedip.split(','); } } + if (typeof obj.config.domains[i].agentallowedip == 'string') { if (obj.config.domains[i].agentallowedip == '') { delete obj.config.domains[i].agentallowedip; } else { obj.config.domains[i].agentallowedip = obj.config.domains[i].agentallowedip.split(','); } } + if (typeof obj.config.domains[i].agentblockedip == 'string') { if (obj.config.domains[i].agentblockedip == '') { delete obj.config.domains[i].agentblockedip; } else { obj.config.domains[i].agentblockedip = obj.config.domains[i].agentblockedip.split(','); } } + if (typeof obj.config.domains[i].ignoreagenthashcheck == 'string') { if (obj.config.domains[i].ignoreagenthashcheck == '') { delete obj.config.domains[i].ignoreagenthashcheck; } else { obj.config.domains[i].ignoreagenthashcheck = obj.config.domains[i].ignoreagenthashcheck.split(','); } } if ((obj.config.domains[i].passwordrequirements != null) && (typeof obj.config.domains[i].passwordrequirements == 'object')) { if (typeof obj.config.domains[i].passwordrequirements.skip2factor == 'string') { obj.config.domains[i].passwordrequirements.skip2factor = obj.config.domains[i].passwordrequirements.skip2factor.split(','); @@ -1171,6 +1172,7 @@ function CreateMeshCentralServer(config, args) { if (obj.args.minifycore === 0) obj.args.minifycore = false; if (typeof args.agentidletimeout != 'number') { args.agentidletimeout = 150000; } else { args.agentidletimeout *= 1000 } // Default agent idle timeout is 2m, 30sec. if ((obj.args.lanonly != true) && (obj.args.webrtconfig == null)) { obj.args.webrtconfig = { iceservers: [{ urls: 'stun:stun.l.google.com:19302' }, { urls: 'stun:stun.services.mozilla.com' }] }; } // Setup default WebRTC STUN servers + if (typeof obj.args.ignoreagenthashcheck == 'string') { if (obj.args.ignoreagenthashcheck == '') { delete obj.args.ignoreagenthashcheck; } else { obj.args.ignoreagenthashcheck = obj.args.ignoreagenthashcheck.split(','); } } // Setup a site administrator if ((obj.args.admin) && (typeof obj.args.admin == 'string')) { diff --git a/package.json b/package.json index 29cc82d1..10920cbe 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,6 @@ "express-ws": "^4.0.0", "ipcheck": "^0.1.0", "minimist": "^1.2.0", - "mongodb": "^3.6.3", "multiparty": "^4.2.1", "nedb": "^1.8.0", "node-forge": "^0.10.0",