mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-11-22 12:52:50 +03:00
Added swarm server IP filtering.
This commit is contained in:
parent
b22be096d7
commit
8d21e843a6
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
46
meshagent.js
46
meshagent.js
@ -266,7 +266,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
// Decode the certificate
|
||||
var certlen = obj.common.ReadShort(msg, 2);
|
||||
obj.unauth = {};
|
||||
try { obj.unauth.nodeid = Buffer.from(obj.forge.pki.getPublicKeyFingerprint(obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))).publicKey, { md: obj.forge.md.sha384.create() }).data, 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'); } catch (e) { return; }
|
||||
try { obj.unauth.nodeid = Buffer.from(obj.forge.pki.getPublicKeyFingerprint(obj.forge.pki.certificateFromAsn1(obj.forge.asn1.fromDer(msg.substring(4, 4 + certlen))).publicKey, { md: obj.forge.md.sha384.create() }).data, 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'); } catch (ex) { console.log(ex); return; }
|
||||
obj.unauth.nodeCertPem = '-----BEGIN CERTIFICATE-----\r\n' + Buffer.from(msg.substring(4, 4 + certlen), 'binary').toString('base64') + '\r\n-----END CERTIFICATE-----';
|
||||
|
||||
// Check the agent signature if we can
|
||||
@ -462,13 +462,43 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
// Verify the agent signature
|
||||
function processAgentSignature(msg) {
|
||||
if (obj.args.ignoreagenthashcheck !== true) {
|
||||
// Verify the signature. This is the fast way, without using forge.
|
||||
const verify = obj.parent.crypto.createVerify('SHA384');
|
||||
verify.end(Buffer.from(getWebCertHash(obj.domain) + obj.nonce + obj.agentnonce, 'binary')); // Test using the private key hash
|
||||
if (verify.verify(obj.unauth.nodeCertPem, Buffer.from(msg, 'binary')) !== true) {
|
||||
const verify2 = obj.parent.crypto.createVerify('SHA384');
|
||||
verify2.end(Buffer.from(getWebCertFullHash(obj.domain) + obj.nonce + obj.agentnonce, 'binary')); // Test using the full cert hash
|
||||
if (verify2.verify(obj.unauth.nodeCertPem, Buffer.from(msg, 'binary')) !== true) { return false; }
|
||||
var verified = false;
|
||||
|
||||
if (msg.length != 384) {
|
||||
// Verify a PKCS7 signature.
|
||||
var msgDer = null;
|
||||
try { msgDer = obj.forge.asn1.fromDer(obj.forge.util.createBuffer(msg, 'binary')); } catch (ex) { }
|
||||
if (msgDer != null) {
|
||||
try {
|
||||
var p7 = obj.forge.pkcs7.messageFromAsn1(msgDer);
|
||||
var sig = p7.rawCapture.signature;
|
||||
|
||||
// Verify with key hash
|
||||
var buf = Buffer.from(getWebCertHash(obj.domain) + obj.nonce + obj.agentnonce, 'binary');
|
||||
var verifier = obj.parent.crypto.createVerify('RSA-SHA384');
|
||||
verifier.update(buf);
|
||||
verified = verifier.verify(obj.unauth.nodeCertPem, sig, 'binary');
|
||||
if (verified == false) {
|
||||
// Verify with full hash
|
||||
buf = Buffer.from(getWebCertFullHash(obj.domain) + obj.nonce + obj.agentnonce, 'binary');
|
||||
verifier = obj.parent.crypto.createVerify('RSA-SHA384');
|
||||
verifier.update(buf);
|
||||
verified = verifier.verify(obj.unauth.nodeCertPem, sig, 'binary');
|
||||
}
|
||||
if (verified == false) { return false; } // Not a valid signature
|
||||
} catch (ex) { };
|
||||
}
|
||||
}
|
||||
|
||||
if (verified == false) {
|
||||
// Verify the RSA signature. This is the fast way, without using forge.
|
||||
const verify = obj.parent.crypto.createVerify('SHA384');
|
||||
verify.end(Buffer.from(getWebCertHash(obj.domain) + obj.nonce + obj.agentnonce, 'binary')); // Test using the private key hash
|
||||
if (verify.verify(obj.unauth.nodeCertPem, Buffer.from(msg, 'binary')) !== true) {
|
||||
const verify2 = obj.parent.crypto.createVerify('SHA384');
|
||||
verify2.end(Buffer.from(getWebCertFullHash(obj.domain) + obj.nonce + obj.agentnonce, 'binary')); // Test using the full cert hash
|
||||
if (verify2.verify(obj.unauth.nodeCertPem, Buffer.from(msg, 'binary')) !== true) { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
try { require('./pass').hash('test', function () { }); } catch (e) { console.log('Old version of node, must upgrade.'); return; } // TODO: Not sure if this test works or not.
|
||||
|
||||
// Check for invalid arguments
|
||||
var validArguments = ['_', 'notls', 'user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'cert', 'mpscert', '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', 'admin', 'unadmin', 'sessionkey', 'sessiontime', 'minify', 'minifycore'];
|
||||
var validArguments = ['_', 'notls', 'user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'cert', 'mpscert', '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', 'swarmallowedip', 'fastcert', 'swarmport', 'swarmdebug', 'logintoken', 'logintokenkey', 'logintokengen', 'logintokengen', 'mailtokengen', 'admin', 'unadmin', 'sessionkey', 'sessiontime', 'minify', 'minifycore'];
|
||||
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; }
|
||||
for (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.
|
||||
@ -252,6 +252,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
if (obj.args.notls == null && obj.args.redirport == null) obj.args.redirport = 80;
|
||||
if (obj.args.minifycore === 0) obj.args.minifycore = false;
|
||||
if (typeof obj.args.userallowedip == 'string') { if (obj.args.userallowedip == '') { obj.args.userallowedip = null; } else { obj.args.userallowedip = obj.args.userallowedip.split(','); } }
|
||||
if (typeof obj.args.swarmallowedip == 'string') { if (obj.args.swarmallowedip == '') { obj.args.swarmallowedip = null; } else { obj.args.swarmallowedip = obj.args.swarmallowedip.split(','); } }
|
||||
if (typeof obj.args.debug == 'number') obj.debugLevel = obj.args.debug;
|
||||
if (obj.args.debug == true) obj.debugLevel = 1;
|
||||
obj.db = require('./db.js').CreateDB(obj);
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.2.5-y",
|
||||
"version": "0.2.6-d",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
@ -122,7 +122,7 @@ module.exports.CreateSwarmServer = function (parent, db, args, certificates) {
|
||||
GUESTWEBRTCMESH: 2002 // Guest usage: WebRTC Mesh
|
||||
};
|
||||
|
||||
obj.server = tls.createServer({ key: certificates.swarmserver.key, cert: certificates.swarmserver.cert, requestCert: true }, onConnection);
|
||||
obj.server = tls.createServer({ key: certificates.swarmserver.key, cert: certificates.swarmserver.cert, requestCert: true, rejectUnauthorized: false }, onConnection);
|
||||
obj.server.listen(args.swarmport, function () { console.log('MeshCentral Legacy Swarm Server running on ' + certificates.CommonName + ':' + args.swarmport + '.'); obj.parent.updateServerState('swarm-port', args.swarmport); }).on('error', function (err) { console.error('ERROR: MeshCentral Swarm Server server port ' + args.swarmport + ' is not available.'); if (args.exactports) { process.exit(); } });
|
||||
loadMigrationAgents();
|
||||
|
||||
@ -147,6 +147,9 @@ module.exports.CreateSwarmServer = function (parent, db, args, certificates) {
|
||||
|
||||
// Called when a legacy agent connects to this server
|
||||
function onConnection(socket) {
|
||||
// Check for blocked IP address
|
||||
if (checkSwarmIpAddress(socket, obj.args.swarmallowedip) == false) { Debug(1, "SWARM:New blocked agent connection"); return; }
|
||||
|
||||
socket.tag = { first: true, clientCert: socket.getPeerCertificate(true), accumulator: "", socket: socket };
|
||||
socket.setEncoding('binary');
|
||||
socket.pingTimer = setInterval(function () { obj.SendCommand(socket, LegacyMeshProtocol.PING); }, 20000);
|
||||
@ -349,6 +352,16 @@ module.exports.CreateSwarmServer = function (parent, db, args, certificates) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the source IP address is allowed for a given allowed list, return false if not
|
||||
function checkSwarmIpAddress(socket, allowedIpList) {
|
||||
if (allowedIpList == null) { return true; }
|
||||
try {
|
||||
var ip = socket.remoteAddress;
|
||||
if (ip) { for (var i = 0; i < allowedIpList.length; i++) { if (require('ipcheck').match(ip, allowedIpList[i])) { return true; } } }
|
||||
} catch (e) { console.log(e); }
|
||||
return false;
|
||||
}
|
||||
|
||||
// Debug
|
||||
function Debug(lvl) {
|
||||
if (lvl > obj.parent.debugLevel) return;
|
||||
|
Loading…
Reference in New Issue
Block a user