Improved session recording and logs.
This commit is contained in:
parent
8155b86c73
commit
7927892855
58
meshrelay.js
58
meshrelay.js
|
@ -166,24 +166,36 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
|
||||||
// Setup session recording
|
// Setup session recording
|
||||||
var sessionUser = user;
|
var sessionUser = user;
|
||||||
if (sessionUser == null) { sessionUser = obj.peer.user; }
|
if (sessionUser == null) { sessionUser = obj.peer.user; }
|
||||||
if (domain.sessionrecording) {
|
if (domain.sessionrecording == true || ((typeof domain.sessionrecording == 'object') && ((domain.sessionrecording.protocols == null) || (domain.sessionrecording.protocols.indexOf(parseInt(req.query.p)) >= 0)))) {
|
||||||
try { parent.parent.fs.mkdirSync(parent.parent.recordpath); } catch (e) { }
|
var recFilename = 'relaysession' + ((domain.id == '') ? '' : '-') + domain.id + '-' + Date.now() + '-' + obj.id + '.mcrec'
|
||||||
var recFilename = 'relaysession' + ((domain.id == '') ? '' : '-') + domain.id + '-' + Date.now() + '-' + sessionUser.name + '-' + obj.id + '.mcrec'
|
var recFullFilename = null;
|
||||||
var recFullFilename = parent.parent.path.join(parent.parent.recordpath, recFilename);
|
if (domain.sessionrecording.filepath) {
|
||||||
|
try { parent.parent.fs.mkdirSync(domain.sessionrecording.filepath); } catch (e) { }
|
||||||
|
recFullFilename = parent.parent.path.join(domain.sessionrecording.filepath, recFilename);
|
||||||
|
} else {
|
||||||
|
try { parent.parent.fs.mkdirSync(parent.parent.recordpath); } catch (e) { }
|
||||||
|
recFullFilename = parent.parent.path.join(parent.parent.recordpath, recFilename);
|
||||||
|
}
|
||||||
parent.parent.fs.open(recFullFilename, 'w', function (err, fd) {
|
parent.parent.fs.open(recFullFilename, 'w', function (err, fd) {
|
||||||
// Write the recording file header
|
if (err != null) {
|
||||||
var firstBlock = Buffer.from(JSON.stringify({ magic: 'MeshCentralRelaySession', ver: 1, userid: sessionUser._id, username: sessionUser.name, sessionid: obj.id, ipaddr1: cleanRemoteAddr(ws._socket.remoteAddress), ipaddr2: cleanRemoteAddr(obj.peer.ws._socket.remoteAddress), time: new Date().toLocaleString() }));
|
// Unable to record
|
||||||
var header = Buffer.alloc(16); // Type (2) + Flags (2) + Size(4) + Time(8)
|
|
||||||
header.writeInt16BE(1, 0); // Type (1 = Header, 2 = Network Data)
|
|
||||||
header.writeInt16BE(0, 2); // Flags (1 = Binary, 2 = User)
|
|
||||||
header.writeInt32BE(firstBlock.length, 4); // Size
|
|
||||||
header.writeIntBE(ws.time, 10, 6); // Time
|
|
||||||
var block = Buffer.concat([header, firstBlock]);
|
|
||||||
parent.parent.fs.write(fd, block, 0, block.length, function (err, bytesWritten, buffer) {
|
|
||||||
relayinfo.peer1.ws.logfile = ws.logfile = { fd: fd, lock: false };
|
|
||||||
ws.send('c'); // Send connect to both peers
|
ws.send('c'); // Send connect to both peers
|
||||||
relayinfo.peer1.ws.send('c');
|
relayinfo.peer1.ws.send('c');
|
||||||
});
|
} else {
|
||||||
|
// Write the recording file header
|
||||||
|
var firstBlock = Buffer.from(JSON.stringify({ magic: 'MeshCentralRelaySession', ver: 1, userid: sessionUser._id, username: sessionUser.name, sessionid: obj.id, ipaddr1: cleanRemoteAddr(ws._socket.remoteAddress), ipaddr2: cleanRemoteAddr(obj.peer.ws._socket.remoteAddress), time: new Date().toLocaleString(), protocol: req.query.p, nodeid: req.query.nodeid }));
|
||||||
|
var header = Buffer.alloc(16); // Type (2) + Flags (2) + Size(4) + Time(8)
|
||||||
|
header.writeInt16BE(1, 0); // Type (1 = Header, 2 = Network Data)
|
||||||
|
header.writeInt16BE(0, 2); // Flags (1 = Binary, 2 = User)
|
||||||
|
header.writeInt32BE(firstBlock.length, 4); // Size
|
||||||
|
header.writeIntBE(ws.time, 10, 6); // Time
|
||||||
|
var block = Buffer.concat([header, firstBlock]);
|
||||||
|
parent.parent.fs.write(fd, block, 0, block.length, function (err, bytesWritten, buffer) {
|
||||||
|
relayinfo.peer1.ws.logfile = ws.logfile = { fd: fd, lock: false };
|
||||||
|
ws.send('c'); // Send connect to both peers
|
||||||
|
relayinfo.peer1.ws.send('c');
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Send session start
|
// Send session start
|
||||||
|
@ -195,7 +207,11 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
|
||||||
|
|
||||||
// Log the connection
|
// Log the connection
|
||||||
if (sessionUser) {
|
if (sessionUser) {
|
||||||
var event = { etype: 'relay', action: 'relaylog', domain: domain.id, userid: sessionUser._id, username: sessionUser.name, msg: 'Started relay session \"' + obj.id + '\" from ' + cleanRemoteAddr(obj.peer.ws._socket.remoteAddress) + ' to ' + cleanRemoteAddr(ws._socket.remoteAddress) };
|
var msg = 'Started relay session';
|
||||||
|
if (req.query.p == 1) { msg = 'Started terminal session'; }
|
||||||
|
else if (req.query.p == 2) { msg = 'Started desktop session'; }
|
||||||
|
else if (req.query.p == 5) { msg = 'Started file management session'; }
|
||||||
|
var event = { etype: 'relay', action: 'relaylog', domain: domain.id, userid: sessionUser._id, username: sessionUser.name, msg: msg + ' \"' + obj.id + '\" from ' + cleanRemoteAddr(obj.peer.ws._socket.remoteAddress) + ' to ' + cleanRemoteAddr(ws._socket.remoteAddress), protocol: req.query.p, nodeid: req.query.nodeid };
|
||||||
parent.parent.DispatchEvent(['*', user._id], obj, event);
|
parent.parent.DispatchEvent(['*', user._id], obj, event);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -308,11 +324,15 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
|
||||||
|
|
||||||
// Log the disconnection
|
// Log the disconnection
|
||||||
if (ws.time) {
|
if (ws.time) {
|
||||||
|
var msg = 'Ended relay session';
|
||||||
|
if (req.query.p == 1) { msg = 'Ended terminal session'; }
|
||||||
|
else if (req.query.p == 2) { msg = 'Ended desktop session'; }
|
||||||
|
else if (req.query.p == 5) { msg = 'Ended file management session'; }
|
||||||
if (user) {
|
if (user) {
|
||||||
var event = { etype: 'relay', action: 'relaylog', domain: domain.id, userid: user._id, username: parent.users[user._id].name, msg: 'Ended relay session \"' + obj.id + '\" from ' + cleanRemoteAddr(obj.peer.ws._socket.remoteAddress) + ' to ' + cleanRemoteAddr(ws._socket.remoteAddress) + ', ' + Math.floor((Date.now() - ws.time) / 1000) + ' second(s)' };
|
var event = { etype: 'relay', action: 'relaylog', domain: domain.id, userid: user._id, username: parent.users[user._id].name, msg: msg + ' \"' + obj.id + '\" from ' + cleanRemoteAddr(obj.peer.ws._socket.remoteAddress) + ' to ' + cleanRemoteAddr(ws._socket.remoteAddress) + ', ' + Math.floor((Date.now() - ws.time) / 1000) + ' second(s)', protocol: req.query.p, nodeid: req.query.nodeid };
|
||||||
parent.parent.DispatchEvent(['*', user._id], obj, event);
|
parent.parent.DispatchEvent(['*', user._id], obj, event);
|
||||||
} else if (peer.user) {
|
} else if (peer.user) {
|
||||||
var event = { etype: 'relay', action: 'relaylog', domain: domain.id, userid: peer.user._id, username: parent.users[peer.user._id].name, msg: 'Ended relay session \"' + obj.id + '\" from ' + cleanRemoteAddr(obj.peer.ws._socket.remoteAddress) + ' to ' + cleanRemoteAddr(ws._socket.remoteAddress) + ', ' + Math.floor((Date.now() - ws.time) / 1000) + ' second(s)' };
|
var event = { etype: 'relay', action: 'relaylog', domain: domain.id, userid: peer.user._id, username: parent.users[peer.user._id].name, msg: msg + ' \"' + obj.id + '\" from ' + cleanRemoteAddr(obj.peer.ws._socket.remoteAddress) + ' to ' + cleanRemoteAddr(ws._socket.remoteAddress) + ', ' + Math.floor((Date.now() - ws.time) / 1000) + ' second(s)', protocol: req.query.p, nodeid: req.query.nodeid };
|
||||||
parent.parent.DispatchEvent(['*', peer.user._id], obj, event);
|
parent.parent.DispatchEvent(['*', peer.user._id], obj, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -422,7 +442,7 @@ about this recording. It looks something like this:
|
||||||
}
|
}
|
||||||
|
|
||||||
The rest of the data blocks are all network traffic that was relayed thru the server. They are of TYPE 2 and have
|
The rest of the data blocks are all network traffic that was relayed thru the server. They are of TYPE 2 and have
|
||||||
a given size and timestamp. When looking at network traffic the flags are imporant.
|
a given size and timestamp. When looking at network traffic the flags are important:
|
||||||
|
|
||||||
- If traffic has the first (0x0001) flag set, the data is binary otherwise it's a string.
|
- If traffic has the first (0x0001) flag set, the data is binary otherwise it's a string.
|
||||||
- If the traffic has the second (0x0002) flag set, traffic is coming from the user's browser, if not, it's coming from the MeshAgent.
|
- If the traffic has the second (0x0002) flag set, traffic is coming from the user's browser, if not, it's coming from the MeshAgent.
|
||||||
|
|
|
@ -35,7 +35,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
|
||||||
//obj.debug = function (msg) { console.log(msg); }
|
//obj.debug = function (msg) { console.log(msg); }
|
||||||
|
|
||||||
obj.Start = function (nodeid) {
|
obj.Start = function (nodeid) {
|
||||||
var url2, url = window.location.protocol.replace("http", "ws") + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + "/meshrelay.ashx?browser=1&id=" + obj.tunnelid;
|
var url2, url = window.location.protocol.replace("http", "ws") + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + "/meshrelay.ashx?browser=1&p=" + obj.protocol + "&nodeid=" + nodeid + "&id=" + obj.tunnelid;
|
||||||
//if (serverPublicNamePort) { url2 = window.location.protocol.replace("http", "ws") + "//" + serverPublicNamePort + "/meshrelay.ashx?id=" + obj.tunnelid; } else { url2 = url; }
|
//if (serverPublicNamePort) { url2 = window.location.protocol.replace("http", "ws") + "//" + serverPublicNamePort + "/meshrelay.ashx?id=" + obj.tunnelid; } else { url2 = url; }
|
||||||
if ((authCookie != null) && (authCookie != '')) { url += '&auth=' + authCookie; }
|
if ((authCookie != null) && (authCookie != '')) { url += '&auth=' + authCookie; }
|
||||||
obj.nodeid = nodeid;
|
obj.nodeid = nodeid;
|
||||||
|
@ -48,7 +48,7 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
|
||||||
obj.socket.onclose = obj.xxOnSocketClosed;
|
obj.socket.onclose = obj.xxOnSocketClosed;
|
||||||
obj.xxStateChange(1);
|
obj.xxStateChange(1);
|
||||||
//obj.meshserver.send({ action: 'msg', type: 'tunnel', nodeid: obj.nodeid, value: url2 });
|
//obj.meshserver.send({ action: 'msg', type: 'tunnel', nodeid: obj.nodeid, value: url2 });
|
||||||
obj.meshserver.send({ action: 'msg', type: 'tunnel', nodeid: obj.nodeid, value: "*" + domainUrl + "meshrelay.ashx?id=" + obj.tunnelid, usage: obj.protocol });
|
obj.meshserver.send({ action: 'msg', type: 'tunnel', nodeid: obj.nodeid, value: "*" + domainUrl + "meshrelay.ashx?p=" + obj.protocol + "&nodeid=" + nodeid + "&id=" + obj.tunnelid, usage: obj.protocol });
|
||||||
//obj.debug("Agent Redir Start: " + url);
|
//obj.debug("Agent Redir Start: " + url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,11 @@
|
||||||
},
|
},
|
||||||
"_yubikey": { "id": "0000", "secret": "xxxxxxxxxxxxxxxxxxxxx", "_proxy": "http://myproxy.domain.com:80" },
|
"_yubikey": { "id": "0000", "secret": "xxxxxxxxxxxxxxxxxxxxx", "_proxy": "http://myproxy.domain.com:80" },
|
||||||
"_httpheaders": { "Strict-Transport-Security": "max-age=360000" },
|
"_httpheaders": { "Strict-Transport-Security": "max-age=360000" },
|
||||||
"_agentConfig": [ "webSocketMaskOverride=1" ]
|
"_agentConfig": [ "webSocketMaskOverride=1" ],
|
||||||
|
"_SessionRecording": {
|
||||||
|
"_filepath": "C:\\temp",
|
||||||
|
"protocols": [ 1, 2 ]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"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
|
@ -5992,7 +5992,6 @@
|
||||||
var icon = 'si3';
|
var icon = 'si3';
|
||||||
if (event.etype == 'user') icon = 'm2';
|
if (event.etype == 'user') icon = 'm2';
|
||||||
if (event.etype == 'server') icon = 'si3';
|
if (event.etype == 'server') icon = 'si3';
|
||||||
if (event.etype == 'relay') icon = 'relayIcon16';
|
|
||||||
|
|
||||||
var msg = EscapeHtml(event.msg).split('(R)').join('®');
|
var msg = EscapeHtml(event.msg).split('(R)').join('®');
|
||||||
if (event.username) {
|
if (event.username) {
|
||||||
|
@ -6002,6 +6001,7 @@
|
||||||
msg = EscapeHtml(event.username) + ' → ' + msg;
|
msg = EscapeHtml(event.username) + ' → ' + msg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (event.etype == 'relay' || event.action == 'relaylog') icon = 'relayIcon16';
|
||||||
x += '<tr onclick=showEventDetails(' + event.h + ',1) onmouseover=eventMouseHover(this,1) onmouseout=eventMouseHover(this,0) style=cursor:pointer><td style=width:18px><div class=' + icon + '></div></td><td class=g1> </td><td class=style10>' + printTime(time) + ' - ' + msg + '</td><td class=g2> </td></tr><tr style=height:2px></tr>';
|
x += '<tr onclick=showEventDetails(' + event.h + ',1) onmouseover=eventMouseHover(this,1) onmouseout=eventMouseHover(this,0) style=cursor:pointer><td style=width:18px><div class=' + icon + '></div></td><td class=g1> </td><td class=style10>' + printTime(time) + ' - ' + msg + '</td><td class=g2> </td></tr><tr style=height:2px></tr>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7379,7 +7379,6 @@
|
||||||
var icon = 'si3';
|
var icon = 'si3';
|
||||||
if (event.etype == 'user') icon = 'm2';
|
if (event.etype == 'user') icon = 'm2';
|
||||||
if (event.etype == 'server') icon = 'si3';
|
if (event.etype == 'server') icon = 'si3';
|
||||||
if (event.etype == 'relay') icon = 'relayIcon16';
|
|
||||||
|
|
||||||
var msg = EscapeHtml(event.msg).split('(R)').join('®');
|
var msg = EscapeHtml(event.msg).split('(R)').join('®');
|
||||||
if (event.nodeid) {
|
if (event.nodeid) {
|
||||||
|
@ -7396,6 +7395,7 @@
|
||||||
msg = EscapeHtml(event.username) + ' → ' + msg;
|
msg = EscapeHtml(event.username) + ' → ' + msg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (event.etype == 'relay' || event.action == 'relaylog') icon = 'relayIcon16';
|
||||||
x += '<tr onclick=showEventDetails(' + event.h + ',2) onmouseover=eventMouseHover(this,1) onmouseout=eventMouseHover(this,0) style=cursor:pointer><td style=width:18px><div class=' + icon + '></div></td><td class=g1> </td><td class=style10>' + printTime(time) + ' - ' + msg + '</td><td class=g2> </td></tr><tr style=height:2px></tr>';
|
x += '<tr onclick=showEventDetails(' + event.h + ',2) onmouseover=eventMouseHover(this,1) onmouseout=eventMouseHover(this,0) style=cursor:pointer><td style=width:18px><div class=' + icon + '></div></td><td class=g1> </td><td class=style10>' + printTime(time) + ' - ' + msg + '</td><td class=g2> </td></tr><tr style=height:2px></tr>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8085,7 +8085,6 @@
|
||||||
var icon = 'si3';
|
var icon = 'si3';
|
||||||
if (event.etype == 'user') icon = 'm2';
|
if (event.etype == 'user') icon = 'm2';
|
||||||
if (event.etype == 'server') icon = 'si3';
|
if (event.etype == 'server') icon = 'si3';
|
||||||
if (event.etype == 'relay') icon = 'relayIcon16';
|
|
||||||
|
|
||||||
var msg = EscapeHtml(event.msg).split('(R)').join('®');
|
var msg = EscapeHtml(event.msg).split('(R)').join('®');
|
||||||
if (event.nodeid) {
|
if (event.nodeid) {
|
||||||
|
@ -8102,6 +8101,7 @@
|
||||||
msg = EscapeHtml(event.username) + ' → ' + msg;
|
msg = EscapeHtml(event.username) + ' → ' + msg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (event.etype == 'relay' || event.action == 'relaylog') icon = 'relayIcon16';
|
||||||
x += '<tr onclick=showEventDetails(' + event.h + ',3) onmouseover=eventMouseHover(this,1) onmouseout=eventMouseHover(this,0) style=cursor:pointer><td style=width:18px><div class=' + icon + '></div></td><td class=g1> </td><td class=style10>' + printTime(time) + ' - ' + msg + '</td><td class=g2> </td></tr><tr style=height:2px></tr>';
|
x += '<tr onclick=showEventDetails(' + event.h + ',3) onmouseover=eventMouseHover(this,1) onmouseout=eventMouseHover(this,0) style=cursor:pointer><td style=width:18px><div class=' + icon + '></div></td><td class=g1> </td><td class=style10>' + printTime(time) + ' - ' + msg + '</td><td class=g2> </td></tr><tr style=height:2px></tr>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue