advanced_configuration.js (9088B)
1#!/usr/bin/env node 2 3const GuacamoleLite = require('guacamole-lite'); 4const http = require("http"); 5 6// [OPTIONAL] websocketOptions 7// this is passed directly to 'ws' library when creating a websocket server. 8// like this: new WebSocket.Server(websocketOptions) 9// See https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback 10const websocketOptions = { 11 port: 8080 // We will accept connections to this port. Default: 8080 12}; 13 14// [OPTIONAL] guacdOptions 15// this is passed directly to net.connect() function when connecting to guacd. 16// See https://nodejs.org/api/net.html#net_net_connect_port_host_connectlistener 17const guacdOptions = { 18 host: 'localhost', // Hostname or IP address of guacd server, Default: '127.0.0.1' 19 port: 4822 // Port of guacd server. Default: 4822 20}; 21 22// [REQUIRED] clientOptions 23const clientOptions = { 24 25 // [REQUIRED] crypt 26 // Encryption settings used to decrypt the connection token. 27 // Ideally, you'd want to keep them in a separate file and not commit them to your repository. 28 crypt: { 29 cypher: 'AES-256-CBC', 30 key: 'MySuperSecretKeyForParamsToken12' 31 }, 32 33 // [OPTIONAL] log 34 // Logger settings. 35 log: { 36 // You can set the log level to one of the following values: 37 // 'QUIET' - no logs 38 // 'ERRORS' - only errors 39 // 'NORMAL' - errors + minimal logs (startup and shutdown messages) 40 // 'VERBOSE' - (default) normal + connection messages (opened, closed, guacd exchange, etc) 41 // 'DEBUG' - verbose + all OPCODES sent/received within guacamole sessions 42 level: 'DEBUG', 43 44 // By default, GuacamoleLite will log to stdout and stderr. 45 // You can override the default logging functions by providing your own stdLog and/or errorLog functions. 46 stdLog: (...args) => { 47 console.log('[MyLog]', ...args) 48 }, 49 errorLog: (...args) => { 50 console.error('[MyLog]', ...args) 51 } 52 }, 53 54 // [OPTIONAL] connectionDefaultSettings 55 // Default settings for different connection types. 56 // These are added to the connection settings received from the client in the encrypted connection token. 57 // Note that this it a mix of connection parameters and client handshake instructions. 58 // There is no common set of parameters for all connection types (RDP, VNC, etc.), each type must be configured 59 // separately. 60 // For the list of connection parameters 61 // see https://guacamole.incubator.apache.org/doc/gug/configuring-guacamole.html#configuring-connections 62 // For the list of client handshake instructions 63 // see https://guacamole.incubator.apache.org/doc/gug/protocol-reference.html#client-handshake-instructions 64 connectionDefaultSettings: { 65 rdp: { 66 // RDP connection parameters 67 // https://guacamole.incubator.apache.org/doc/gug/configuring-guacamole.html#rdp 68 // https://guacamole.incubator.apache.org/doc/gug/configuring-guacamole.html#common-configuration-options 69 'create-drive-path': true, 70 'security': 'any', 71 'ignore-cert': true, 72 'enable-wallpaper': false, 73 'create-recording-path': true, 74 75 // Client handshake instructions 76 // https://guacamole.incubator.apache.org/doc/gug/protocol-reference.html#client-handshake-instructions 77 'audio': ['audio/L16'], 78 'video': null, 79 'image': ['image/png', 'image/jpeg'], 80 'timezone': 'America/New_York', 81 }, 82 vnc: { 83 // VNC connection parameters 84 // https://guacamole.incubator.apache.org/doc/gug/configuring-guacamole.html#vnc 85 // https://guacamole.incubator.apache.org/doc/gug/configuring-guacamole.html#common-configuration-options 86 'swap-red-blue': true, 87 'disable-paste': false, 88 }, 89 ssh: { 90 // SSH connection parameters 91 // https://guacamole.incubator.apache.org/doc/gug/configuring-guacamole.html#ssh 92 // https://guacamole.incubator.apache.org/doc/gug/configuring-guacamole.html#common-configuration-options 93 'enable-sftp': true, 94 'green-black': true, 95 }, 96 telnet: { 97 // Telnet connection parameters 98 // https://guacamole.incubator.apache.org/doc/gug/configuring-guacamole.html#telnet 99 // https://guacamole.incubator.apache.org/doc/gug/configuring-guacamole.html#common-configuration-options 100 'login-success-regex': '.*', 101 }, 102 kubernetes: { 103 // Kubernetes connection parameters 104 // https://guacamole.incubator.apache.org/doc/gug/configuring-guacamole.html#kubernetes 105 // https://guacamole.incubator.apache.org/doc/gug/configuring-guacamole.html#common-configuration-options 106 'exec-command': 'bash', 107 } 108 }, 109 110 // [OPTIONAL] allowedUnencryptedConnectionSettings 111 // The connection parameters from the encrypted token can be overridden by the client by sending them 112 // unencrypted in the query string. 113 // For example: ws://guacamole-lite:8080/?token=<encrypted>&width=800&height=600&dpi=120 114 115 // This is useful when you want to generate a connection token on your backend server (which is a good idea, 116 // because you don't want to expose connection parameters like username, password, etc to the client), but 117 // allow your frontend to override some of the connection parameters like screen width, height, etc. 118 119 // Because we don't want the client to be able to override all parameters, including the sensitive ones, 120 // we need to specify the list parameters that can be sent unencrypted for each connection type. 121 122 // By default, only the following unencrypted parameters are allowed: 123 // width, height, dpi, audio, video, image, timezone 124 allowedUnencryptedConnectionSettings: { 125 rdp: [ 126 'width', 127 'height', 128 'dpi', 129 'create-drive-path' // we added this parameter to the list of allowed unencrypted parameters 130 ] 131 }, 132}; 133 134// [OPTIONAL] 135// Callbacks for different events. 136const callbacks = { 137 processConnectionSettings: (settings, callback) => { 138 // processConnectionSettings: 139 // This is called after establishing a websocket connection with the client, decrypting the connection token, 140 // and before opening a connection to guacd. 141 // Can be used to modify the connection settings "on the fly" based on the user id, connection id, etc. 142 // Or to validate the connection settings and reject the connection. 143 // It receives the connection settings and a callback function as parameters. 144 // The callback function must be called with two parameters: error and modified settings. 145 // In the end, you MUST call the callback function with either an error or the modified settings. 146 // If the callback is called with an error, the connection will be rejected. 147 148 // You can encrypt ANY custom parameters in the connection token and use them here. 149 // In this example, we are using the "expiration" parameter to validate the token's expiration date. 150 // This is a good practice to prevent token replay attacks. 151 if (settings['expiration'] < Date.now()) { 152 console.error('Token expired'); 153 154 // Reject the connection 155 return callback(new Error('Token expired')); 156 } 157 158 // You can also send "userId" in the connection token and use it dynamically modify the connection settings. 159 // In this example, we are using the "userId" parameter to set individual drive paths for each user. 160 settings.connection['drive-path'] = '/tmp/guacamole_' + settings['userId']; 161 162 // Forward the modified settings to guacd 163 callback(null, settings); 164 } 165}; 166 167// Create a new instance of GuacamoleLite 168const guacServer = new GuacamoleLite( 169 websocketOptions, 170 guacdOptions, 171 clientOptions, 172 callbacks 173); 174 175 176// In the following example, we are using the "open" and "close" events to notify our backend server 177// about the user's connection status. 178// Each event receives the ClientConnection object as a parameter, which contains the connection settings, including 179// the user id, etc. See ClientConnection.js for more details, 'close' and 'error' events also receive an error object, 180// containing the disconnect reason. 181guacServer.on('open', (clientConnection) => { 182 const url = 'http://our-backend-server/api/connection/open' 183 + '?userId=' + clientConnection.connectionSettings['userId']; 184 185 http.request(url).end(); 186}); 187 188guacServer.on('close', (clientConnection, error) => { 189 const url = 'http://our-backend-server/api/connection/close' 190 + '?userId=' + clientConnection.connectionSettings['userId'] 191 + '&error=' + encodeURIComponent(error.message); 192 193 http.request(url).end(); 194}); 195 196guacServer.on('error', (clientConnection, error) => { 197 console.error(clientConnection, error); 198});