chore: refactor logging to debug

This commit is contained in:
Bill Church 2024-08-13 10:42:34 +00:00
parent 650f4eb8f0
commit 617ce151c0
No known key found for this signature in database
4 changed files with 57 additions and 35 deletions

View file

@ -2,6 +2,7 @@
// app/app.js // app/app.js
'use strict' 'use strict'
const createDebug = require('debug')
const http = require('http') const http = require('http')
const express = require('express') const express = require('express')
const socketIo = require('socket.io') const socketIo = require('socket.io')
@ -60,9 +61,14 @@ function createServer(app) {
* @param {Function} sessionMiddleware - The session middleware * @param {Function} sessionMiddleware - The session middleware
* @returns {import('socket.io').Server} The Socket.IO server instance * @returns {import('socket.io').Server} The Socket.IO server instance
*/ */
// var io = require('socket.io')(server, { serveClient: false, path: '/ssh/socket.io', origins: config.http.origins })
function configureSocketIO(server, sessionMiddleware) { function configureSocketIO(server, sessionMiddleware) {
const io = socketIo(server, { const io = socketIo(server, {
serveClient: false,
path: '/ssh/socket.io', path: '/ssh/socket.io',
pingTimeout: 60000, // 1 minute
pingInterval: 25000, // 25 seconds
cors: getCorsConfig() cors: getCorsConfig()
}); });

View file

@ -1,11 +1,14 @@
// server // server
// /app/routes.js // /app/routes.js
const createDebug = require('debug')
const debug = createDebug('webssh2:routes')
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const handleConnection = require('./connectionHandler'); const handleConnection = require('./connectionHandler');
const basicAuth = require('basic-auth'); const basicAuth = require('basic-auth');
function auth(req, res, next) { function auth(req, res, next) {
debug('Authenticating user with HTTP Basic Auth');
var credentials = basicAuth(req); var credentials = basicAuth(req);
if (!credentials) { if (!credentials) {
res.setHeader('WWW-Authenticate', 'Basic realm="WebSSH2"'); res.setHeader('WWW-Authenticate', 'Basic realm="WebSSH2"');
@ -16,13 +19,15 @@ function auth(req, res, next) {
next(); next();
} }
// Scenario 1: No auth required // Scenario 1: No auth required, uses websocket authentication instead
router.get('/', function(req, res) { router.get('/', function(req, res) {
debug('Accessed /ssh route');
handleConnection(req, res); handleConnection(req, res);
}); });
// Scenario 2: Auth required // Scenario 2: Auth required, uses HTTP Basic Auth
router.get('/host/:host', auth, function(req, res) { router.get('/host/:host', auth, function(req, res) {
debug(`Accessed /ssh/host/${req.params.host} route`);
handleConnection(req, res, { host: req.params.host }); handleConnection(req, res, { host: req.params.host });
}); });

View file

@ -2,8 +2,9 @@
// app/socket.js // app/socket.js
'use strict' 'use strict'
const debug = require('debug') const createDebug = require('debug')
const debugWebSSH2 = require('debug')('WebSSH2') const { header } = require('./config')
const debug = createDebug('webssh2:socket')
const SSH = require('ssh2').Client const SSH = require('ssh2').Client
/** /**
@ -26,15 +27,15 @@ function handleConnection(socket, config) {
let authenticated = false; let authenticated = false;
let isConnectionClosed = false; let isConnectionClosed = false;
console.log(`SOCKET CONNECT: ${socket.id}, URL: ${socket.handshake.url}`); debug(`CONNECT: ${socket.id}, URL: ${socket.handshake.url}`);
removeExistingListeners(socket) removeExistingListeners(socket)
setupInitialSocketListeners(socket, config) setupInitialSocketListeners(socket, config)
// Emit an event to the client to request authentication // Emit an event to the client to request authentication
if (!authenticated) { if (!authenticated) {
console.log(`Requesting authentication for ${socket.id} and authenticated is ${authenticated}`); debug(`Requesting authentication for ${socket.id} and authenticated is ${authenticated}`);
socket.emit('request_auth'); socket.emit('authentication', { action: 'request_auth' });
} }
/** /**
@ -56,8 +57,8 @@ function handleConnection(socket, config) {
socket.on('error', (error) => console.error(`Socket error for ${socket.id}:`, error)); socket.on('error', (error) => console.error(`Socket error for ${socket.id}:`, error));
socket.on('authenticate', creds => handleAuthentication(socket, creds, config)) socket.on('authenticate', creds => handleAuthentication(socket, creds, config))
socket.on('disconnect', (reason) => { socket.on('disconnect', (reason) => {
console.log(`Client ${socket.id} disconnected. Reason: ${reason}`); debug(`Client ${socket.id} disconnected. Reason: ${reason}`);
console.log('Socket state at disconnect:', socket.conn.transport.readyState); debug('Socket state at disconnect:', socket.conn.transport.readyState);
if (conn) { if (conn) {
conn.end(); conn.end();
conn = null; conn = null;
@ -72,18 +73,20 @@ function handleConnection(socket, config) {
/** /**
* Handles authentication attempts * Handles authentication attempts
* @param {import('socket.io').Socket} socket - The Socket.IO socket * @param {import('socket.io').Socket} socket - The Socket.IO socket
*
* @param {Credentials} creds - The credentials for authentication * @param {Credentials} creds - The credentials for authentication
* @param {Object} config - The configuration object * @param {Object} config - The configuration object
*/ */
function handleAuthentication(socket, creds, config) { function handleAuthentication(socket, creds, config) {
console.log(`SOCKET AUTHENTICATE: ${socket.id}, Host: ${creds.host}`); debug(`AUTHENTICATE: ${socket.id}, Host: ${creds.host}`);
if (isValidCredentials(creds)) { if (isValidCredentials(creds)) {
console.log(`SOCKET CREDENTIALS VALID: ${socket.id}, Host: ${creds.host}`); debug(`CREDENTIALS VALID: ${socket.id}, Host: ${creds.host}`);
initializeConnection(socket, creds, config); initializeConnection(socket, creds, config);
} else { } else {
console.log(`SOCKET CREDENTIALS INVALID: ${socket.id}, Host: ${creds.host}`); debug(`CREDENTIALS INVALID: ${socket.id}, Host: ${creds.host}`);
socket.emit('auth_result', { success: false, message: 'Invalid credentials format' }); socket.emit('authentication', { success: false, message: 'Invalid credentials format' });
} }
} }
@ -94,7 +97,7 @@ function handleAuthentication(socket, creds, config) {
* @param {Object} config - The configuration object * @param {Object} config - The configuration object
*/ */
function initializeConnection(socket, creds, config) { function initializeConnection(socket, creds, config) {
console.log(`INITIALIZING SSH CONNECTION: ${socket.id}, Host: ${creds.host}`); debug(`INITIALIZING SSH CONNECTION: ${socket.id}, Host: ${creds.host}`);
if (conn) { if (conn) {
conn.end() conn.end()
} }
@ -103,12 +106,20 @@ function handleAuthentication(socket, creds, config) {
conn.on('ready', () => { conn.on('ready', () => {
authenticated = true; authenticated = true;
console.log(`SSH CONNECTION READY: ${socket.id}, Host: ${creds.host}`); debug(`SSH CONNECTION READY: ${socket.id}, Host: ${creds.host}`);
socket.emit('auth_result', { success: true }) socket.emit('authentication', { action: 'auth_result', success: true });
console.log('allowReplay:', config.options.allowReplay)
socket.emit('allowReplay', config.options.allowReplay || false) // Emit consolidated permissions
console.log('allowReauth:', config.options.allowReauth) socket.emit('permissions', {
socket.emit('allowReauth', config.options.allowReauth || false) allowReplay: config.options.allowReplay || false,
allowReauth: config.options.allowReauth || false
});
if (config.header && config.header.text !== null) {
debug('header:', config.header)
socket.emit('updateUI', { header: config.header } || { header: { text: '', background: '' } })
}
setupSSHListeners(socket, creds) setupSSHListeners(socket, creds)
initializeShell(socket, creds) initializeShell(socket, creds)
}) })
@ -116,7 +127,7 @@ function handleAuthentication(socket, creds, config) {
conn.on('error', err => { conn.on('error', err => {
console.error(`SSH CONNECTION ERROR: ${socket.id}, Host: ${creds.host}, Error: ${err.message}`); console.error(`SSH CONNECTION ERROR: ${socket.id}, Host: ${creds.host}, Error: ${err.message}`);
if (err.level === 'client-authentication') { if (err.level === 'client-authentication') {
socket.emit('auth_result', { success: false, message: 'Authentication failed' }) socket.emit('authentication', { action: 'auth_result', success: false, message: 'Authentication failed' })
} else { } else {
handleError(socket, 'SSH CONNECTION ERROR', err) handleError(socket, 'SSH CONNECTION ERROR', err)
} }
@ -164,7 +175,7 @@ function handleAuthentication(socket, creds, config) {
message: code || signal ? `CODE: ${code} SIGNAL: ${signal}` : undefined message: code || signal ? `CODE: ${code} SIGNAL: ${signal}` : undefined
}) })
}) })
stream.stderr.on('data', data => console.log('STDERR: ' + data)) stream.stderr.on('data', data => debug('STDERR: ' + data))
} }
) )
} }
@ -183,7 +194,7 @@ function handleAuthentication(socket, creds, config) {
* @param {import('socket.io').Socket} socket - The Socket.IO socket * @param {import('socket.io').Socket} socket - The Socket.IO socket
*/ */
function handleSSHEnd(socket) { function handleSSHEnd(socket) {
console.log(`SSH CONNECTION ENDED: ${socket.id}`) debug(`SSH CONNECTION ENDED: ${socket.id}`)
handleConnectionClose(socket) handleConnectionClose(socket)
} }
@ -192,7 +203,7 @@ function handleAuthentication(socket, creds, config) {
* @param {import('socket.io').Socket} socket - The Socket.IO socket * @param {import('socket.io').Socket} socket - The Socket.IO socket
*/ */
function handleSSHClose(socket) { function handleSSHClose(socket) {
console.log(`SSH CONNECTION CLOSED: ${socket.id}`) debug(`SSH CONNECTION CLOSED: ${socket.id}`)
handleConnectionClose(socket) handleConnectionClose(socket)
} }
@ -219,7 +230,7 @@ function handleAuthentication(socket, creds, config) {
* @param {string} reason - The reason for disconnection * @param {string} reason - The reason for disconnection
*/ */
function handleDisconnect(socket, reason) { function handleDisconnect(socket, reason) {
console.log(`SOCKET DISCONNECT: ${socket.id}, Reason: ${reason}`) debug(`DISCONNECT: ${socket.id}, Reason: ${reason}`)
handleConnectionClose(socket) handleConnectionClose(socket)
} }
@ -234,11 +245,11 @@ function handleAuthentication(socket, creds, config) {
try { try {
stream.write(data) stream.write(data)
} catch (error) { } catch (error) {
console.log('Error writing to stream:', error.message) debug('Error writing to stream:', error.message)
handleConnectionClose(socket) handleConnectionClose(socket)
} }
} else if (isConnectionClosed) { } else if (isConnectionClosed) {
console.log('Attempted to write to closed connection') debug('Attempted to write to closed connection')
socket.emit('connection_closed') socket.emit('connection_closed')
} }
} }
@ -265,7 +276,7 @@ function handleAuthentication(socket, creds, config) {
* @param {Object} config - The configuration object * @param {Object} config - The configuration object
*/ */
function handleControl(socket, stream, credentials, controlData, config) { function handleControl(socket, stream, credentials, controlData, config) {
console.log(`Received control data: ${controlData}`); debug(`Received control data: ${controlData}`);
if (controlData === 'replayCredentials' && stream && credentials) { if (controlData === 'replayCredentials' && stream && credentials) {
replayCredentials(socket, stream, credentials, config); replayCredentials(socket, stream, credentials, config);
@ -285,10 +296,10 @@ function handleAuthentication(socket, creds, config) {
let allowReplay = config.options.allowReplay || false; let allowReplay = config.options.allowReplay || false;
if (allowReplay) { if (allowReplay) {
console.log(`Replaying credentials for ${socket.id}`); debug(`Replaying credentials for ${socket.id}`);
stream.write(credentials.password + '\n'); stream.write(credentials.password + '\n');
} else { } else {
console.log(`Credential replay not allowed for ${socket.id}`); debug(`Credential replay not allowed for ${socket.id}`);
} }
} }
@ -297,9 +308,9 @@ function handleAuthentication(socket, creds, config) {
* @param {import('socket.io').Socket} socket - The Socket.IO socket * @param {import('socket.io').Socket} socket - The Socket.IO socket
*/ */
function handleReauth(socket) { function handleReauth(socket) {
console.log(`Reauthentication requested for ${socket.id}`); debug(`Reauthentication requested for ${socket.id}`);
socket.emit('authentication', { action: 'reauth' });
handleConnectionClose(socket); handleConnectionClose(socket);
socket.emit('reauth');
} }
/** /**
@ -310,7 +321,7 @@ function handleAuthentication(socket, creds, config) {
*/ */
function handleError(socket, context, err) { function handleError(socket, context, err) {
const errorMessage = err ? `: ${err.message}` : '' const errorMessage = err ? `: ${err.message}` : ''
console.log(`WebSSH2 error: ${context}${errorMessage}`) debug(`WebSSH2 error: ${context}${errorMessage}`)
socket.emit('ssherror', `SSH ${context}${errorMessage}`) socket.emit('ssherror', `SSH ${context}${errorMessage}`)
handleConnectionClose(socket) handleConnectionClose(socket)
} }
@ -346,7 +357,7 @@ function handleAuthentication(socket, creds, config) {
readyTimeout: credentials.readyTimeout, readyTimeout: credentials.readyTimeout,
keepaliveInterval: credentials.keepaliveInterval, keepaliveInterval: credentials.keepaliveInterval,
keepaliveCountMax: credentials.keepaliveCountMax, keepaliveCountMax: credentials.keepaliveCountMax,
debug: debug('ssh2') debug: createDebug('webssh2:ssh')
} }
} }
} }

View file

@ -43,7 +43,7 @@
"read-config-ng": "~3.0.7", "read-config-ng": "~3.0.7",
"socket.io": "~2.2.0", "socket.io": "~2.2.0",
"ssh2": "~0.8.9", "ssh2": "~0.8.9",
"webssh2_client": "^0.2.16" "webssh2_client": "^0.2.17"
}, },
"scripts": { "scripts": {
"start": "node index.js", "start": "node index.js",