Updates agents, added agent no proxy support and agent IP allow/block.

This commit is contained in:
Ylian Saint-Hilaire 2019-01-30 13:43:42 -08:00
parent b0394da585
commit c1ac574af7
26 changed files with 90 additions and 54 deletions

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.

Binary file not shown.

View File

@ -95,13 +95,13 @@ DownloadAgent() {
mkdir -p /usr/local/mesh mkdir -p /usr/local/mesh
cd /usr/local/mesh cd /usr/local/mesh
echo "Downloading Mesh agent #$machineid..." echo "Downloading Mesh agent #$machineid..."
wget $url/meshagents?id=$machineid -q --no-check-certificate -O /usr/local/mesh/meshagent wget $url/meshagents?id=$machineid --no-check-certificate {{{noproxy}}}-O /usr/local/mesh/meshagent
# If it did not work, try again using http # If it did not work, try again using http
if [ $? != 0 ] if [ $? != 0 ]
then then
url=${url/"https://"/"http://"} url=${url/"https://"/"http://"}
wget $url/meshagents?id=$machineid -q -O /usr/local/mesh/meshagent wget $url/meshagents?id=$machineid {{{noproxy}}}-O /usr/local/mesh/meshagent
fi fi
if [ $? -eq 0 ] if [ $? -eq 0 ]
@ -109,12 +109,12 @@ DownloadAgent() {
echo "Mesh agent downloaded." echo "Mesh agent downloaded."
# TODO: We could check the meshagent sha256 hash, but best to authenticate the server. # TODO: We could check the meshagent sha256 hash, but best to authenticate the server.
chmod 755 /usr/local/mesh/meshagent chmod 755 /usr/local/mesh/meshagent
wget $url/meshsettings?id=$meshid -q --no-check-certificate -O /usr/local/mesh/meshagent.msh wget $url/meshsettings?id=$meshid --no-check-certificate {{{noproxy}}}-O /usr/local/mesh/meshagent.msh
# If it did not work, try again using http # If it did not work, try again using http
if [ $? -ne 0 ] if [ $? -ne 0 ]
then then
wget $url/meshsettings?id=$meshid -q -O /usr/local/mesh/meshagent.msh wget $url/meshsettings?id=$meshid {{{noproxy}}}-O /usr/local/mesh/meshagent.msh
fi fi
if [ $? -eq 0 ] if [ $? -eq 0 ]
@ -141,7 +141,7 @@ DownloadAgent() {
if [ $starttype -eq 3 ] if [ $starttype -eq 3 ]
then then
# initd # initd
wget $url/meshagents?script=2 -q --no-check-certificate -O /etc/init.d/meshagent wget $url/meshagents?script=2 --no-check-certificate {{{noproxy}}}-O /etc/init.d/meshagent
chmod +x /etc/init.d/meshagent chmod +x /etc/init.d/meshagent
update-rc.d meshagent defaults # creates symlinks for rc.d update-rc.d meshagent defaults # creates symlinks for rc.d
service meshagent start service meshagent start

View File

@ -759,29 +759,29 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
if (nodes.length != 1) return; if (nodes.length != 1) return;
var device = nodes[0]; var device = nodes[0];
if (device.agent) { if (device.agent) {
var changes = [], change = 0; var changes = [], change = 0, log = 0;
//if (command.users) { console.log(command.users); } //if (command.users) { console.log(command.users); }
// Check if anything changes // Check if anything changes
if (command.name && (command.name != device.name)) { change = 1; device.name = command.name; changes.push('name'); } if (command.name && (command.name != device.name)) { change = 1; log = 1; device.name = command.name; changes.push('name'); }
if ((command.caps != null) && (device.agent.core != command.value)) { if ((command.value == null) && (device.agent.core != null)) { delete device.agent.core; } else { device.agent.core = command.value; } change = 1; changes.push('agent core'); } if ((command.caps != null) && (device.agent.core != command.value)) { if ((command.value == null) && (device.agent.core != null)) { delete device.agent.core; } else { device.agent.core = command.value; } change = 1; } // Don't save this as an event to the db.
if ((command.caps != null) && ((device.agent.caps & 0xFFFFFFE7) != (command.caps & 0xFFFFFFE7))) { device.agent.caps = ((device.agent.caps & 24) + (command.caps & 0xFFFFFFE7)); change = 1; changes.push('agent capabilities'); } // Allow Javascript on the agent to change all capabilities except console and javascript support if ((command.caps != null) && ((device.agent.caps & 0xFFFFFFE7) != (command.caps & 0xFFFFFFE7))) { device.agent.caps = ((device.agent.caps & 24) + (command.caps & 0xFFFFFFE7)); change = 1; } // Allow Javascript on the agent to change all capabilities except console and javascript support, Don't save this as an event to the db.
if ((command.osdesc != null) && (device.osdesc != command.osdesc)) { device.osdesc = command.osdesc; change = 1; changes.push('os desc'); } if ((command.osdesc != null) && (device.osdesc != command.osdesc)) { device.osdesc = command.osdesc; change = 1; log = 1; changes.push('os desc'); }
if (command.intelamt) { if (command.intelamt) {
if (!device.intelamt) { device.intelamt = {}; } if (!device.intelamt) { device.intelamt = {}; }
if ((command.intelamt.ver != null) && (device.intelamt.ver != command.intelamt.ver)) { changes.push('AMT version'); device.intelamt.ver = command.intelamt.ver; change = 1; } if ((command.intelamt.ver != null) && (device.intelamt.ver != command.intelamt.ver)) { changes.push('AMT version'); device.intelamt.ver = command.intelamt.ver; change = 1; log = 1; }
if ((command.intelamt.state != null) && (device.intelamt.state != command.intelamt.state)) { changes.push('AMT state'); device.intelamt.state = command.intelamt.state; change = 1; } if ((command.intelamt.state != null) && (device.intelamt.state != command.intelamt.state)) { changes.push('AMT state'); device.intelamt.state = command.intelamt.state; change = 1; log = 1; }
if ((command.intelamt.flags != null) && (device.intelamt.flags != command.intelamt.flags)) { if ((command.intelamt.flags != null) && (device.intelamt.flags != command.intelamt.flags)) {
if (device.intelamt.flags) { changes.push('AMT flags (' + device.intelamt.flags + ' --> ' + command.intelamt.flags + ')'); } else { changes.push('AMT flags (' + command.intelamt.flags + ')'); } if (device.intelamt.flags) { changes.push('AMT flags (' + device.intelamt.flags + ' --> ' + command.intelamt.flags + ')'); } else { changes.push('AMT flags (' + command.intelamt.flags + ')'); }
device.intelamt.flags = command.intelamt.flags; change = 1; device.intelamt.flags = command.intelamt.flags; change = 1; log = 1;
} }
if ((command.intelamt.host != null) && (device.intelamt.host != command.intelamt.host)) { changes.push('AMT host'); device.intelamt.host = command.intelamt.host; change = 1; } if ((command.intelamt.host != null) && (device.intelamt.host != command.intelamt.host)) { changes.push('AMT host'); device.intelamt.host = command.intelamt.host; change = 1; log = 1; }
if ((command.intelamt.uuid != null) && (device.intelamt.uuid != command.intelamt.uuid)) { changes.push('AMT uuid'); device.intelamt.uuid = command.intelamt.uuid; change = 1; } if ((command.intelamt.uuid != null) && (device.intelamt.uuid != command.intelamt.uuid)) { changes.push('AMT uuid'); device.intelamt.uuid = command.intelamt.uuid; change = 1; log = 1; }
} }
if ((command.users != null) && (device.users != command.users)) { device.users = command.users; change = 1; } // Would be nice not to save this to the db. if ((command.users != null) && (device.users != command.users)) { device.users = command.users; change = 1; } // Don't save this to the db.
if (mesh.mtype == 2) { if (mesh.mtype == 2) {
if (device.host != obj.remoteaddr) { device.host = obj.remoteaddr; change = 1; changes.push('host'); } if (device.host != obj.remoteaddr) { device.host = obj.remoteaddr; change = 1; log = 1; changes.push('host'); }
// TODO: Check that the agent has an interface that is the same as the one we got this websocket connection on. Only set if we have a match. // TODO: Check that the agent has an interface that is the same as the one we got this websocket connection on. Only set if we have a match.
} }
@ -793,9 +793,9 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
// Event the node change // Event the node change
var event = { etype: 'node', action: 'changenode', nodeid: obj.dbNodeKey, domain: domain.id }; var event = { etype: 'node', action: 'changenode', nodeid: obj.dbNodeKey, domain: domain.id };
if (changes.length > 0) { event.msg = 'Changed device ' + device.name + ' from group ' + mesh.name + ': ' + changes.join(', '); } if (changes.length > 0) { event.msg = 'Changed device ' + device.name + ' from group ' + mesh.name + ': ' + changes.join(', '); }
if ((obj.agentInfo.capabilities & 0x20) || (changes.length == 0)) { event.nolog = 1; } // If this is a temporary device, don't log changes if ((log == 0) || (obj.agentInfo.capabilities & 0x20) || (changes.length == 0)) { event.nolog = 1; } // If this is a temporary device, don't log changes
var device2 = obj.common.Clone(device); var device2 = obj.common.Clone(device);
if (device2.intelamt && device2.intelamt.pass) delete device2.intelamt.pass; // Remove the Intel AMT password before eventing this. if (device2.intelamt && device2.intelamt.pass) { delete device2.intelamt.pass; } // Remove the Intel AMT password before eventing this.
event.node = device; event.node = device;
obj.parent.parent.DispatchEvent(['*', device.meshid], obj, event); obj.parent.parent.DispatchEvent(['*', device.meshid], obj, event);
} }

View File

@ -59,7 +59,7 @@ function CreateMeshCentralServer(config, args) {
obj.serverKey = Buffer.from(obj.crypto.randomBytes(48), 'binary'); obj.serverKey = Buffer.from(obj.crypto.randomBytes(48), 'binary');
obj.loginCookieEncryptionKey = null; obj.loginCookieEncryptionKey = null;
obj.serverSelfWriteAllowed = true; obj.serverSelfWriteAllowed = true;
obj.taskLimiter = obj.common.createTaskLimiterQueue(10, 20, 60); // This is a task limiter queue to smooth out server work. obj.taskLimiter = obj.common.createTaskLimiterQueue(30, 20, 60); // This is a task limiter queue to smooth out server work.
try { obj.currentVer = JSON.parse(obj.fs.readFileSync(obj.path.join(__dirname, 'package.json'), 'utf8')).version; } catch (e) { } // Fetch server version try { obj.currentVer = JSON.parse(obj.fs.readFileSync(obj.path.join(__dirname, 'package.json'), 'utf8')).version; } catch (e) { } // Fetch server version
// Setup the default configuration and files paths // Setup the default configuration and files paths
@ -95,7 +95,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. 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 // 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', 'dbexportmin', 'dbimport', 'dbencryptkey', 'selfupdate', 'tlsoffload', 'userallowedip', 'swarmallowedip', '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', 'dbexportmin', 'dbimport', 'dbencryptkey', 'selfupdate', 'tlsoffload', 'userallowedip', 'userblockedip', 'swarmallowedip', 'agentallowedip', 'agentblockedip', '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; } } 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 (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. 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.
@ -251,6 +251,9 @@ function CreateMeshCentralServer(config, args) {
if (obj.config.domains[i].dns == null) { obj.config.domains[i].url = (i == '') ? '/' : ('/' + i + '/'); } else { obj.config.domains[i].url = '/'; } if (obj.config.domains[i].dns == null) { obj.config.domains[i].url = (i == '') ? '/' : ('/' + i + '/'); } else { obj.config.domains[i].url = '/'; }
obj.config.domains[i].id = i; obj.config.domains[i].id = i;
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].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].userallowedip.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(','); } }
} }
// Log passed arguments into Windows Service Log // Log passed arguments into Windows Service Log
@ -268,6 +271,9 @@ function CreateMeshCentralServer(config, args) {
if (obj.args.notls == null && obj.args.redirport == null) obj.args.redirport = 80; if (obj.args.notls == null && obj.args.redirport == null) obj.args.redirport = 80;
if (obj.args.minifycore === 0) obj.args.minifycore = false; 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.userallowedip == 'string') { if (obj.args.userallowedip == '') { obj.args.userallowedip = null; } else { obj.args.userallowedip = obj.args.userallowedip.split(','); } }
if (typeof obj.args.userblockedip == 'string') { if (obj.args.userblockedip == '') { obj.args.userblockedip = null; } else { obj.args.userblockedip = obj.args.userblockedip.split(','); } }
if (typeof obj.args.agentallowedip == 'string') { if (obj.args.agentallowedip == '') { obj.args.agentallowedip = null; } else { obj.args.agentallowedip = obj.args.agentallowedip.split(','); } }
if (typeof obj.args.agentblockedip == 'string') { if (obj.args.agentblockedip == '') { obj.args.agentblockedip = null; } else { obj.args.agentblockedip = obj.args.agentblockedip.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.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 (typeof obj.args.debug == 'number') obj.debugLevel = obj.args.debug;
if (obj.args.debug == true) obj.debugLevel = 1; if (obj.args.debug == true) obj.debugLevel = 1;
@ -1053,7 +1059,8 @@ function CreateMeshCentralServer(config, args) {
var stream = null; var stream = null;
try { try {
stream = obj.fs.createReadStream(scriptpath); stream = obj.fs.createReadStream(scriptpath);
stream.on('data', function (data) { this.hash.update(data, 'binary'); }); stream.xdata = '';
stream.on('data', function (data) { this.hash.update(data, 'binary'); this.xdata += data; });
stream.on('error', function (data) { stream.on('error', function (data) {
// If there is an error reading this file, make sure this agent is not in the agent table // If there is an error reading this file, make sure this agent is not in the agent table
if (obj.meshAgentInstallScripts[this.info.id] != null) { delete obj.meshAgentInstallScripts[this.info.id]; } if (obj.meshAgentInstallScripts[this.info.id] != null) { delete obj.meshAgentInstallScripts[this.info.id]; }
@ -1063,6 +1070,7 @@ function CreateMeshCentralServer(config, args) {
obj.meshAgentInstallScripts[this.info.id] = obj.common.Clone(this.info); obj.meshAgentInstallScripts[this.info.id] = obj.common.Clone(this.info);
obj.meshAgentInstallScripts[this.info.id].hash = this.hash.digest('hex'); obj.meshAgentInstallScripts[this.info.id].hash = this.hash.digest('hex');
obj.meshAgentInstallScripts[this.info.id].path = this.agentpath; obj.meshAgentInstallScripts[this.info.id].path = this.agentpath;
obj.meshAgentInstallScripts[this.info.id].data = this.xdata;
obj.meshAgentInstallScripts[this.info.id].url = ((obj.args.notls == true) ? 'http://' : 'https://') + obj.certificates.CommonName + ':' + obj.args.port + '/meshagents?script=' + this.info.id; obj.meshAgentInstallScripts[this.info.id].url = ((obj.args.notls == true) ? 'http://' : 'https://') + obj.certificates.CommonName + ':' + obj.args.port + '/meshagents?script=' + this.info.id;
var stats = null; var stats = null;
try { stats = obj.fs.statSync(this.agentpath); } catch (e) { } try { stats = obj.fs.statSync(this.agentpath); } catch (e) { }

View File

@ -180,7 +180,16 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
obj.ProcessDataEx = function (str) { obj.ProcessDataEx = function (str) {
if (obj.debugmode > 1) { console.log("KRecv(" + str.length + "): " + rstr2hex(str.substring(0, Math.min(str.length, 40)))); } if (obj.debugmode > 1) { console.log("KRecv(" + str.length + "): " + rstr2hex(str.substring(0, Math.min(str.length, 40)))); }
if (str.length < 4) return; if (str.length < 4) return;
var cmdmsg = null, X = 0, Y = 0, command = ReadShort(str, 0), cmdsize = ReadShort(str, 2); var cmdmsg = null, X = 0, Y = 0, command = ReadShort(str, 0), cmdsize = ReadShort(str, 2), jumboAdd = 0;
if ((command == 27) && (cmdsize == 8)) {
// Jumbo packet
if (str.length < 12) return;
command = ReadShort(str, 8)
cmdsize = ReadInt(str, 4);
str = str.substring(8);
jumboAdd = 8;
//console.log('JUMBO', command, cmdsize, str.length);
}
if ((cmdsize != str.length) && (obj.debugmode > 0)) { console.log(cmdsize, str.length, cmdsize == str.length); } if ((cmdsize != str.length) && (obj.debugmode > 0)) { console.log(cmdsize, str.length, cmdsize == str.length); }
if ((command >= 18) && (command != 65)) { console.error("Invalid KVM command " + command + " of size " + cmdsize); console.log("Invalid KVM data", str.length, str, rstr2hex(str)); return; } if ((command >= 18) && (command != 65)) { console.error("Invalid KVM command " + command + " of size " + cmdsize); console.log("Invalid KVM data", str.length, str, rstr2hex(str)); return; }
if (cmdsize > str.length) { console.error("KVM invalid command size", cmdsize, str.length); return; } if (cmdsize > str.length) { console.error("KVM invalid command size", cmdsize, str.length); return; }
@ -254,7 +263,7 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
if (str[0] != '.') { console.log(str); alert('KVM: ' + str); } else { console.log('KVM: ' + str.substring(1)); } if (str[0] != '.') { console.log(str); alert('KVM: ' + str); } else { console.log('KVM: ' + str.substring(1)); }
break; break;
} }
return cmdsize; return cmdsize + jumboAdd;
} }
// Keyboard and Mouse I/O. // Keyboard and Mouse I/O.

View File

@ -15,7 +15,10 @@
"_WebRTC": false, "_WebRTC": false,
"_ClickOnce": false, "_ClickOnce": false,
"_SelfUpdate": true, "_SelfUpdate": true,
"_UserAllowedIP": "127.0.0.1,::1,192.168.0.100", "_UserAllowedIP": "127.0.0.1,192.168.1.0/24",
"_UserBlockedIP": "127.0.0.1,::1,192.168.0.100",
"_AgentAllowedIP": "192.168.0.100/24",
"_AgentBlockedIP": "127.0.0.1,::1",
"_LocalDiscovery": { "name": "Local server name", "info": "Information about this server" }, "_LocalDiscovery": { "name": "Local server name", "info": "Information about this server" },
"_TlsOffload": true, "_TlsOffload": true,
"_MpsTlsOffload": true, "_MpsTlsOffload": true,
@ -31,8 +34,12 @@
"NewAccounts": 1, "NewAccounts": 1,
"Footer": "<a href='https://twitter.com/mytwitter'>Twitter</a>", "Footer": "<a href='https://twitter.com/mytwitter'>Twitter</a>",
"_CertUrl": "https://192.168.2.106:443/", "_CertUrl": "https://192.168.2.106:443/",
"_PasswordRequirements": { "min": 8, "max": 128, "upper": 1, "lower": 1, "numeric": 1, "nonalpha": 1 },
"_AgentNoProxy": true,
"_UserAllowedIP": "127.0.0.1,192.168.1.0/24", "_UserAllowedIP": "127.0.0.1,192.168.1.0/24",
"_PasswordRequirements": { "min": 8, "max": 128, "upper": 1, "lower": 1, "numeric": 1, "nonalpha": 1 } "_UserBlockedIP": "127.0.0.1,::1,192.168.0.100",
"_AgentAllowedIP": "192.168.0.100/24",
"_AgentBlockedIP": "127.0.0.1,::1"
}, },
"customer1": { "customer1": {
"DNS": "customer1.myserver.com", "DNS": "customer1.myserver.com",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2310,14 +2310,15 @@
var servername = serverinfo.name; var servername = serverinfo.name;
if ((servername == 'un-configured') || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name. if ((servername == 'un-configured') || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name.
var noProxy = ((features & 0x2000) != 0)?'--no-proxy ':''; // Server asked that agent be installed to preferably not use a HTTP proxy.
if (serverinfo.https == true) { if (serverinfo.https == true) {
var portStr = (serverinfo.port == 443)?'':(":" + serverinfo.port); var portStr = (serverinfo.port == 443)?'':(":" + serverinfo.port);
Q('agins_linux_area').value = "wget https://" + servername + portStr + "/meshagents?script=1 --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://" + servername + portStr + " '" + meshid.split('/')[2] + "'\r\n"; Q('agins_linux_area').value = "wget https://" + servername + portStr + "/meshagents?script=1 " + noProxy + "--no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh https://" + servername + portStr + " '" + meshid.split('/')[2] + "'\r\n";
Q('agins_linux_area_un').value = "wget https://" + servername + portStr + "/meshagents?script=1 --no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n"; Q('agins_linux_area_un').value = "wget https://" + servername + portStr + "/meshagents?script=1 " + noProxy + "--no-check-certificate -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n";
} else { } else {
var portStr = (serverinfo.port == 80)?'':(":" + serverinfo.port); var portStr = (serverinfo.port == 80)?'':(":" + serverinfo.port);
Q('agins_linux_area').value = "wget http://" + servername + portStr + "/meshagents?script=1 -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://" + servername + portStr + " '" + meshid.split('/')[2] + "'\r\n"; Q('agins_linux_area').value = "wget http://" + servername + portStr + "/meshagents?script=1 " + noProxy + "-O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh http://" + servername + portStr + " '" + meshid.split('/')[2] + "'\r\n";
Q('agins_linux_area_un').value = "wget http://" + servername + portStr + "/meshagents?script=1 -O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n"; Q('agins_linux_area_un').value = "wget http://" + servername + portStr + "/meshagents?script=1 " + noProxy + "-O ./meshinstall.sh && chmod 755 ./meshinstall.sh && sudo ./meshinstall.sh uninstall\r\n";
} }
Q('aginsSelect').focus(); Q('aginsSelect').focus();
addAgentToMeshClick(); addAgentToMeshClick();

View File

@ -74,9 +74,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
obj.users = {}; obj.users = {};
obj.meshes = {}; obj.meshes = {};
obj.userAllowedIp = args.userallowedip; // List of allowed IP addresses for users obj.userAllowedIp = args.userallowedip; // List of allowed IP addresses for users
obj.agentAllowedIp = args.agentallowedip; // List of allowed IP addresses for agents
obj.agentBlockedIp = args.agentblockedip; // List of blocked IP addresses for agents
obj.tlsSniCredentials = null; obj.tlsSniCredentials = null;
obj.dnsDomains = {}; obj.dnsDomains = {};
//obj.agentConnCount = 0;
// Mesh Rights // Mesh Rights
const MESHRIGHT_EDITMESH = 1; const MESHRIGHT_EDITMESH = 1;
@ -268,15 +269,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
}; };
*/ */
// Check if the source IP address is allowed for a given allowed list, return false if not // Check if the source IP address is in the IP list, return false if not.
function checkUserIpAddressEx(req, res, allowedIpList) { function checkIpAddressEx(req, res, ipList, closeIfThis) {
if (allowedIpList == null) { return true; }
try { try {
var ip; var ip;
if (req.connection) { // HTTP(S) request if (req.connection) { // HTTP(S) request
ip = req.ip; ip = req.ip;
if (ip) { for (var i = 0; i < allowedIpList.length; i++) { if (require('ipcheck').match(ip, allowedIpList[i])) { return true; } } } if (ip) { for (var i = 0; i < ipList.length; i++) { if (require('ipcheck').match(ip, ipList[i])) { if (closeIfThis === true) { res.sendStatus(401); } return true; } } }
res.sendStatus(401); if (closeIfThis === false) { res.sendStatus(401); }
} else if (req._socket) { // WebSocket request } else if (req._socket) { // WebSocket request
ip = req._socket.remoteAddress; ip = req._socket.remoteAddress;
@ -284,18 +284,30 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
// This is not done automatically for web socket like it's done for HTTP requests. // This is not done automatically for web socket like it's done for HTTP requests.
if ((obj.args.tlsoffload) && (res.headers['x-forwarded-for']) && ((obj.args.tlsoffload === true) || (obj.args.tlsoffload === ip) || (('::ffff:') + obj.args.tlsoffload === ip))) { ip = res.headers['x-forwarded-for']; } if ((obj.args.tlsoffload) && (res.headers['x-forwarded-for']) && ((obj.args.tlsoffload === true) || (obj.args.tlsoffload === ip) || (('::ffff:') + obj.args.tlsoffload === ip))) { ip = res.headers['x-forwarded-for']; }
if (ip) { for (var i = 0; i < allowedIpList.length; i++) { if (require('ipcheck').match(ip, allowedIpList[i])) { return true; } } } if (ip) { for (var i = 0; i < ipList.length; i++) { if (require('ipcheck').match(ip, ipList[i])) { if (closeIfThis === true) { try { req.close(); } catch (e) { } } return true; } } }
try { req.close(); } catch (e) { } if (closeIfThis === false) { try { req.close(); } catch (e) { } }
} }
} catch (e) { console.log(e); } } catch (e) { console.log(e); } // Should never happen
return false; return false;
} }
// Check if the source IP address is allowed, return domain if allowed // Check if the source IP address is allowed, return domain if allowed
function checkUserIpAddress(req, res) { function checkUserIpAddress(req, res) {
if (checkUserIpAddressEx(req, res, obj.userAllowedIp) == false) { return null; } if ((obj.userBlockedIp != null) && (checkIpAddressEx(req, res, obj.userBlockedIp, true) == true)) { return null; }
if ((obj.userAllowedIp != null) && (checkIpAddressEx(req, res, obj.userAllowedIp, false) == false)) { return null; }
const domain = (req.url ? getDomain(req) : getDomain(res)); const domain = (req.url ? getDomain(req) : getDomain(res));
if (checkUserIpAddressEx(req, res, domain.userallowedip) == false) { return null; } if ((domain.userblockedip != null) && (checkIpAddressEx(req, res, domain.userblockedip, true) == true)) { return null; }
if ((domain.userallowedip != null) && (checkIpAddressEx(req, res, domain.userallowedip, false) == false)) { return null; }
return domain;
}
// Check if the source IP address is allowed, return domain if allowed
function checkAgentIpAddress(req, res) {
if ((obj.agentBlockedIp != null) && (checkIpAddressEx(req, res, obj.agentBlockedIp, null) == true)) { return null; }
if ((obj.agentAllowedIp != null) && (checkIpAddressEx(req, res, obj.agentAllowedIp, null) == false)) { return null; }
const domain = (req.url ? getDomain(req) : getDomain(res));
if ((domain.agentblockedip != null) && (checkIpAddressEx(req, res, domain.agentblockedip, null) == true)) { return null; }
if ((domain.agentallowedip != null) && (checkIpAddressEx(req, res, domain.agentallowedip, null) == false)) { return null; }
return domain; return domain;
} }
@ -796,6 +808,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (obj.args.lanonly == true || obj.args.mpsport == 0) { features += 0x0400; } // No CIRA if (obj.args.lanonly == true || obj.args.mpsport == 0) { features += 0x0400; } // No CIRA
if ((obj.parent.serverSelfWriteAllowed == true) && (user != null) && (user.siteadmin == 0xFFFFFFFF)) { features += 0x0800; } // Server can self-write (Allows self-update) if ((obj.parent.serverSelfWriteAllowed == true) && (user != null) && (user.siteadmin == 0xFFFFFFFF)) { features += 0x0800; } // Server can self-write (Allows self-update)
if ((domain.auth != 'sspi') && (obj.parent.certificates.CommonName != 'un-configured') && (obj.args.lanonly !== true) && (obj.args.nousers !== true)) { features += 0x1000; } // 2-step login supported if ((domain.auth != 'sspi') && (obj.parent.certificates.CommonName != 'un-configured') && (obj.args.lanonly !== true) && (obj.args.nousers !== true)) { features += 0x1000; } // 2-step login supported
if (domain.agentnoproxy === true) { features += 0x2000; } // Indicates that agents should be installed without using a HTTP proxy
// Create a authentication cookie // Create a authentication cookie
const authCookie = obj.parent.encodeCookie({ userid: user._id, domainid: domain.id }, obj.parent.loginCookieEncryptionKey); const authCookie = obj.parent.encodeCookie({ userid: user._id, domainid: domain.id }, obj.parent.loginCookieEncryptionKey);
@ -909,14 +922,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
// Returns the mesh server root certificate // Returns the mesh server root certificate
function handleRootCertRequest(req, res) { function handleRootCertRequest(req, res) {
if (checkUserIpAddressEx(req, res, obj.userAllowedIp) === false) { return; } // Check server-wide IP filter only. if (checkIpAddressEx(req, res, obj.userAllowedIp, false) === false) { return; } // Check server-wide IP filter only.
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=' + certificates.RootName + '.cer' }); res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=' + certificates.RootName + '.cer' });
res.send(Buffer.from(getRootCertBase64(), 'base64')); res.send(Buffer.from(getRootCertBase64(), 'base64'));
} }
// Returns an mescript for Intel AMT configuration // Returns an mescript for Intel AMT configuration
function handleMeScriptRequest(req, res) { function handleMeScriptRequest(req, res) {
if (checkUserIpAddressEx(req, res, obj.userAllowedIp) === false) { return; } // Check server-wide IP filter only. if (checkIpAddressEx(req, res, obj.userAllowedIp, false) === false) { return; } // Check server-wide IP filter only.
if (req.query.type == 1) { if (req.query.type == 1) {
var filename = 'cira_setup.mescript'; var filename = 'cira_setup.mescript';
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=' + filename }); res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=' + filename });
@ -1631,6 +1644,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + obj.getWebServerName(domain) + ":" + httpsPort + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; } if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + obj.getWebServerName(domain) + ":" + httpsPort + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; }
if (req.query.tag != null) { meshsettings += "Tag=" + req.query.tag + "\r\n"; } if (req.query.tag != null) { meshsettings += "Tag=" + req.query.tag + "\r\n"; }
if ((req.query.installflags != null) && (req.query.installflags != 0)) { meshsettings += "InstallFlags=" + req.query.installflags + "\r\n"; } if ((req.query.installflags != null) && (req.query.installflags != 0)) { meshsettings += "InstallFlags=" + req.query.installflags + "\r\n"; }
if (domain.agentnoproxy === true) { meshsettings += "ignoreProxyFile=1\r\n"; }
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=' + argentInfo.rname }); res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=' + argentInfo.rname });
obj.parent.exeHandler.streamExeWithMeshPolicy({ platform: 'win32', sourceFileName: obj.parent.meshAgentBinaries[req.query.id].path, destinationStream: res, msh: meshsettings, peinfo: obj.parent.meshAgentBinaries[req.query.id].pe }); obj.parent.exeHandler.streamExeWithMeshPolicy({ platform: 'win32', sourceFileName: obj.parent.meshAgentBinaries[req.query.id].path, destinationStream: res, msh: meshsettings, peinfo: obj.parent.meshAgentBinaries[req.query.id].pe });
@ -1640,7 +1654,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
var scriptInfo = obj.parent.meshAgentInstallScripts[req.query.script]; var scriptInfo = obj.parent.meshAgentInstallScripts[req.query.script];
if (scriptInfo == null) { res.sendStatus(404); return; } if (scriptInfo == null) { res.sendStatus(404); return; }
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename=' + scriptInfo.rname }); res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename=' + scriptInfo.rname });
res.sendFile(scriptInfo.path); res.send(scriptInfo.data.split('{{{noproxy}}}').join((domain.agentnoproxy === true)?'--no-proxy ':''));
} else if (req.query.meshcmd != null) { } else if (req.query.meshcmd != null) {
// Send meshcmd for a specific platform back // Send meshcmd for a specific platform back
var agentid = parseInt(req.query.meshcmd); var agentid = parseInt(req.query.meshcmd);
@ -1850,6 +1864,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + obj.getWebServerName(domain) + ":" + httpsPort + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; } if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + obj.getWebServerName(domain) + ":" + httpsPort + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; }
if (req.query.tag != null) { meshsettings += "Tag=" + req.query.tag + "\r\n"; } if (req.query.tag != null) { meshsettings += "Tag=" + req.query.tag + "\r\n"; }
if ((req.query.installflags != null) && (req.query.installflags != 0)) { meshsettings += "InstallFlags=" + req.query.installflags + "\r\n"; } if ((req.query.installflags != null) && (req.query.installflags != 0)) { meshsettings += "InstallFlags=" + req.query.installflags + "\r\n"; }
if (domain.agentnoproxy === true) { meshsettings += "ignoreProxyFile=1\r\n"; }
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=meshagent.msh' }); res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=meshagent.msh' });
res.send(meshsettings); res.send(meshsettings);
@ -1973,14 +1988,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
// Receive mesh agent connections // Receive mesh agent connections
obj.app.ws(url + 'agent.ashx', function (ws, req) { obj.app.ws(url + 'agent.ashx', function (ws, req) {
//console.log(++obj.agentConnCount); var domain = checkAgentIpAddress(ws, req);
/* if (domain == null) { Debug(1, 'Got agent connection from blocked IP address ' + ws._socket.remoteAddress + ', holding.'); return; }
var ip, port, type; // console.log('Agent connect: ' + ws._socket.remoteAddress);
if (req.connection) { ip = req.connection.remoteAddress; port = req.connection.remotePort; type = 1; } // HTTP(S) request try { obj.meshAgentHandler.CreateMeshAgent(obj, obj.db, ws, req, obj.args, domain); } catch (e) { console.log(e); }
else if (req._socket) { ip = req._socket.remoteAddress; port = req._socket.remotePort; type = 2; } // WebSocket request
console.log('AgentConnect', ip, port, type);
*/
try { obj.meshAgentHandler.CreateMeshAgent(obj, obj.db, ws, req, obj.args, getDomain(req)); } catch (e) { console.log(e); }
}); });
// Creates a login token using the user/pass that is passed in as URL arguments. // Creates a login token using the user/pass that is passed in as URL arguments.