Added alternate agent port support.
Ylian Saint-Hilaire committed
May 3, 2020 at 10:46 UTC
dec34998d852fd1d2780dc9a0b1990b0a95ffc21
2 files changed
+68
-2
sample-config.json
+4
@@ -23,9 +23,13 @@
23
"_Port": 443,
24
"_AliasPort": 444,
25
"_RedirPort": 80,
26
+ "_RedirAliasPort": 80,
27
+ "_AgentPort": 1234,
28
"_ExactPorts": true,
29
"_AllowLoginToken": true,
30
"_AllowFraming": true,
31
+ "_CookieIpCheck": false,
32
+ "_CookieEncoding": "hex",
33
"_WebRTC": false,
34
"_Nice404": false,
35
"_ClickOnce": false,
webserver.js
+64
-2
@@ -67,15 +67,16 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
67
obj.webauthn = require('./webauthn.js').CreateWebAuthnModule();
68
69
// Variables
70
+ obj.args = args;
71
obj.parent = parent;
72
obj.filespath = parent.filespath;
73
obj.db = db;
74
obj.app = obj.express();
75
+ if (obj.args.agentport) { obj.agentapp = obj.express(); }
76
obj.app.use(require('compression')());
77
obj.tlsServer = null;
78
obj.tcpServer = null;
79
obj.certificates = certificates;
78
- obj.args = args;
80
obj.users = {}; // UserID --> User
81
obj.meshes = {}; // MeshID --> Mesh (also called device group)
82
obj.userGroups = {}; // UGrpID --> User Group
@@ -3789,6 +3790,25 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3790
obj.expressWs = require('express-ws')(obj.app, obj.tlsServer);
3791
}
3792
3793
+ // Start a second agent-only server if needed
3794
+ if (obj.args.agentport) {
3795
+ if (obj.args.notls || obj.args.tlsoffload) {
3796
+ // Setup the HTTP server without TLS
3797
+ obj.expressWsAlt = require('express-ws')(obj.agentapp);
3798
+ } else {
3799
+ // Setup the agent HTTP server with TLS, use only TLS 1.2 and higher with perfect forward secrecy (PFS).
3800
+ const tlsOptions = { cert: obj.certificates.web.cert, key: obj.certificates.web.key, ca: obj.certificates.web.ca, rejectUnauthorized: true, ciphers: "HIGH:TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_CHACHA20_POLY1305_SHA256", secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_COMPRESSION | constants.SSL_OP_CIPHER_SERVER_PREFERENCE | constants.SSL_OP_NO_TLSv1 | constants.SSL_OP_NO_TLSv1_1 };
3801
+ if (obj.tlsSniCredentials != null) { tlsOptions.SNICallback = TlsSniCallback; } // We have multiple web server certificate used depending on the domain name
3802
+ obj.tlsAltServer = require('https').createServer(tlsOptions, obj.agentapp);
3803
+ obj.tlsAltServer.on('secureConnection', function () { /*console.log('tlsAltServer secureConnection');*/ });
3804
+ obj.tlsAltServer.on('error', function (err) { console.log('tlsAltServer error', err); });
3805
+ //obj.tlsAltServer.on('tlsClientError', function (err) { console.log('tlsClientError', err); });
3806
+ obj.tlsAltServer.on('newSession', function (id, data, cb) { if (tlsSessionStoreCount > 1000) { tlsSessionStoreCount = 0; tlsSessionStore = {}; } tlsSessionStore[id.toString('hex')] = data; tlsSessionStoreCount++; cb(); });
3807
+ obj.tlsAltServer.on('resumeSession', function (id, cb) { cb(null, tlsSessionStore[id.toString('hex')] || null); });
3808
+ obj.expressWsAlt = require('express-ws')(obj.agentapp, obj.tlsAltServer);
3809
+ }
3810
+ }
3811
+
3812
// Setup middleware
3813
obj.app.engine('handlebars', obj.exphbs({ defaultLayout: null })); // defaultLayout: 'main'
3814
obj.app.set('view engine', 'handlebars');
@@ -3970,6 +3990,28 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3990
});
3991
}
3992
3993
+ // Setup the alternative agent-only port
3994
+ if (obj.args.agentport) {
3995
+ // Receive mesh agent connections on alternate port
3996
+ obj.agentapp.ws(url + 'agent.ashx', function (ws, req) {
3997
+ var domain = checkAgentIpAddress(ws, req);
3998
+ if (domain == null) { parent.debug('web', 'Got agent connection with bad domain or blocked IP address ' + cleanRemoteAddr(req.ip) + ', holding.'); return; }
3999
+ //console.log('Agent connect: ' + cleanRemoteAddr(req.ip));
4000
+ try { obj.meshAgentHandler.CreateMeshAgent(obj, obj.db, ws, req, obj.args, domain); } catch (e) { console.log(e); }
4001
+ });
4002
+
4003
+ // Setup mesh relay on alternative agent-only port
4004
+ obj.agentapp.ws(url + 'meshrelay.ashx', function (ws, req) {
4005
+ PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie) {
4006
+ if (((parent.config.settings.desktopmultiplex === true) || (domain.desktopmultiplex === true)) && (req.query.p == 2)) {
4007
+ obj.meshDesktopMultiplexHandler.CreateMeshRelay(obj, ws1, req1, domain, user, cookie); // Desktop multiplexor 1-to-n
4008
+ } else {
4009
+ obj.meshRelayHandler.CreateMeshRelay(obj, ws1, req1, domain, user, cookie); // Normal relay 1-to-1
4010
+ }
4011
+ });
4012
+ });
4013
+ }
4014
+
4015
// Memory Tracking
4016
if (typeof obj.args.memorytracking == 'number') {
4017
obj.app.get(url + 'memorytracking.csv', function (req, res) {
@@ -4030,8 +4072,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4072
});
4073
}
4074
4033
- // Start server on a free port
4075
+ // Start server on a free port.
4076
CheckListenPort(obj.args.port, StartWebServer);
4077
+
4078
+ // Start on a second agent-only alternative port if needed.
4079
+ if (obj.args.agentport) { CheckListenPort(obj.args.agentport, StartAltWebServer); }
4080
}
4081
4082
// Authenticates a session and forwards
@@ -4284,6 +4329,23 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4329
}
4330
}
4331
4332
+ // Start the ExpressJS web server on agent-only alternative port
4333
+ function StartAltWebServer(port) {
4334
+ if ((port < 1) || (port > 65535)) return;
4335
+ if (obj.tlsAltServer != null) {
4336
+ if (obj.args.lanonly == true) {
4337
+ obj.tcpAltServer = obj.tlsAltServer.listen(port, function () { console.log('MeshCentral HTTPS agent-only server running on port ' + port + ((args.aliasport != null) ? (', alias port ' + args.aliasport) : '') + '.'); });
4338
+ } else {
4339
+ obj.tcpAltServer = obj.tlsAltServer.listen(port, function () { console.log('MeshCentral HTTPS agent-only server running on ' + certificates.CommonName + ':' + port + ((args.aliasport != null) ? (', alias port ' + args.aliasport) : '') + '.'); });
4340
+ }
4341
+ if (obj.parent.authlog) { obj.parent.authLog('https', 'Server listening on 0.0.0.0 port ' + port + '.'); }
4342
+ obj.parent.updateServerState('https-agent-port', port);
4343
+ } else {
4344
+ obj.tcpAltServer = obj.app.listen(port, function () { console.log('MeshCentral HTTP agent-only server running on port ' + port + ((args.aliasport != null) ? (', alias port ' + args.aliasport) : '') + '.'); });
4345
+ obj.parent.updateServerState('http-agent-port', port);
4346
+ }
4347
+ }
4348
+
4349
// Force mesh agent disconnection
4350
obj.forceMeshAgentDisconnect = function (user, domain, nodeid, disconnectMode) {
4351
if (nodeid == null) return;