All Projects → vadimpronin → Guacamole Lite

vadimpronin / Guacamole Lite

Licence: apache-2.0
NodeJS replacement for guacamole-client (server-side Java servlet). Guacamole is a RDP/VNC client for HTML5 browsers.

Programming Languages

javascript
184084 projects - #8 most used programming language

Labels

Projects that are alternatives of or similar to Guacamole Lite

Premotem
Personal Remote Manager
Stars: ✭ 161 (+41.23%)
Mutual labels:  rdp, vnc
Guacamole
Guacamole是无客户端的远程桌面网关。它支持VNC,RDP和SSH等标准协议。 我们称之为无客户端,因为不需要插件或客户端软件。 感谢HTML5,一旦Guacamole安装在服务器上,您访问桌面所需的全部功能就是一个Web浏览器。
Stars: ✭ 99 (-13.16%)
Mutual labels:  rdp, vnc
Remmina
Mirror of https://gitlab.com/Remmina/Remmina The GTK+ Remmina Remote Desktop Client
Stars: ✭ 1,705 (+1395.61%)
Mutual labels:  rdp, vnc
Next Terminal
Next Terminal是一个轻量级堡垒机系统,易安装,易使用,支持RDP、SSH、VNC、Telnet、Kubernetes协议。
Stars: ✭ 2,354 (+1964.91%)
Mutual labels:  rdp, vnc
seahorse
ELKFH - Elastic, Logstash, Kibana, Filebeat and Honeypot (HTTP, HTTPS, SSH, RDP, VNC, Redis, MySQL, MONGO, SMB, LDAP)
Stars: ✭ 31 (-72.81%)
Mutual labels:  rdp, vnc
Chameleon
Customizable honeypots for monitoring network traffic, bots activities and username\password credentials (DNS, HTTP Proxy, HTTP, HTTPS, SSH, POP3, IMAP, STMP, RDP, VNC, SMB, SOCKS5, Redis, TELNET, Postgres and MySQL)
Stars: ✭ 230 (+101.75%)
Mutual labels:  rdp, vnc
Brutedum
BruteDum - Brute Force attacks SSH, FTP, Telnet, PostgreSQL, RDP, VNC with Hydra, Medusa and Ncrack
Stars: ✭ 212 (+85.96%)
Mutual labels:  rdp, vnc
docker-images
Kali and Parrot OS docker images accessible via VNC, RDP and Web
Stars: ✭ 66 (-42.11%)
Mutual labels:  rdp, vnc
installer
remote.it command line installer tool
Stars: ✭ 21 (-81.58%)
Mutual labels:  rdp, vnc
RabbitRemoteControl
Remote control. Support VNC, RDP, Terminal, SSH, TELNET etc
Stars: ✭ 82 (-28.07%)
Mutual labels:  rdp, vnc
guacamole-auth-jwt
Guacamole authentication extension based on JWT.
Stars: ✭ 28 (-75.44%)
Mutual labels:  rdp, vnc
Openiothub
💖A free IoT (Internet of Things) platform and private cloud. [一个免费的物联网和私有云平台,支持内网穿透]
Stars: ✭ 371 (+225.44%)
Mutual labels:  rdp, vnc
Seth
Perform a MitM attack and extract clear text credentials from RDP connections
Stars: ✭ 1,084 (+850.88%)
Mutual labels:  rdp
Bluekeep Exploit
Bluekeep(CVE 2019-0708) exploit released
Stars: ✭ 93 (-18.42%)
Mutual labels:  rdp
Myrtille
A native HTML4 / HTML5 Remote Desktop Protocol and SSH client
Stars: ✭ 1,007 (+783.33%)
Mutual labels:  rdp
Terminals
Terminals is a secure, multi tab terminal services/remote desktop client. It uses Terminal Services ActiveX Client (mstscax.dll). The project started from the need of controlling multiple connections simultaneously. It is a complete replacement for the mstsc.exe (Terminal Services) client. This is official source moved from Codeplex.
Stars: ✭ 971 (+751.75%)
Mutual labels:  rdp
Teleport
Certificate authority and access plane for SSH, Kubernetes, web apps, databases and desktops
Stars: ✭ 10,602 (+9200%)
Mutual labels:  rdp
Headmore
Top geek’s VNC client that runs in Linux terminal (Linux VT console, xterm, and more)
Stars: ✭ 82 (-28.07%)
Mutual labels:  vnc
Cloudconnect
Cloud aware client to connect ssh, sftp and rdp
Stars: ✭ 25 (-78.07%)
Mutual labels:  rdp
Rdesktop
🚨 rdesktop is in need of a new maintainter. Please see the home page for more details. 🚨
Stars: ✭ 922 (+708.77%)
Mutual labels:  rdp

guacamole-lite

Synopsis

guacamole-lite is a NodeJS replacement for guacamole-client (server-side Java servlet). Guacamole is a RDP/VNC client for HTML5 browsers.

This is the best solution for those ones who need to integrate Guacamole into an existing projects with their own users and connections management (or without them at all).

This diagram describes the architecture of Guacamole and the role of guacamole-lite in it: arch

Installation

npm install --save guacamole-lite

Code Example

Simple example which accepts connections to port 8080 and forwards all traffic to guacd on port 4822

#!/usr/bin/env node

const GuacamoleLite = require('guacamole-lite');

const websocketOptions = {
    port: 8080 // we will accept connections to this port
};

const guacdOptions = {
    port: 4822 // port of guacd
};

const clientOptions = {
    crypt: {
        cypher: 'AES-256-CBC',
        key: 'MySuperSecretKeyForParamsToken12'
    }
};

const guacServer = new GuacamoleLite(websocketOptions, guacdOptions, clientOptions);

Now to connect to guacamole-lite from the browser you need to add guacamole-common-js into your page. Please refer to Chapter 17 of Guacamole documentation for instructions on how to do it.

Then you need to open guacamole connection to

ws://your-guacamole-server:8080/?token=token

where token is an encrypted token object (json) containing all the parameters needed to establish connection (host ip, login, password, connection type, etc). Here is an example of what it can contain:


{
    "connection": {
        "type": "rdp",
        "settings": {
            "hostname": "10.0.0.12",
            "username": "Administrator",
            "password": "pAsSwOrD",
            "enable-drive": true,
            "create-drive-path": true,
            "security": "any",
            "ignore-cert": true,
            "enable-wallpaper": false
        }
    }
}

As seen in the example token object must contain property connection which in it's turn must contain type (rdp, vnc, ssh, telnet) and settings. For full list of settings and their meaning please refer to Chapter 5 of Guacamole documentation section Configuring connections).

Token object may contain any additional parameters you may need in your application. For example it can contain token expiration time (see below how to make use of it).

Now to get the token we need to encrypt and base64-encode this token object using cyper and key from clientOptions. This is an example how to do it in PHP:

<?php

function encryptToken($value)
{
    $iv = random_bytes(16);

    $value = \openssl_encrypt(
        json_encode($value),
        'AES-256-CBC',
        'MySuperSecretKeyForParamsToken12',
        0,
        $iv
    );

    if ($value === false) {
        throw new \Exception('Could not encrypt the data.');
    }

    $data = [
        'iv' => base64_encode($iv),
        'value' => $value,
    ];

    $json = json_encode($data);

    if (!is_string($json)) {
        throw new \Exception('Could not encrypt the data.');
    }

    return base64_encode($json);
}

another example in NodeJS:

const crypto = require('crypto');

const clientOptions = {
    cypher: 'AES-256-CBC',
    key: 'MySuperSecretKeyForParamsToken12'
}

const encrypt = (value) => {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv(clientOptions.cypher, clientOptions.key, iv);

    let crypted = cipher.update(JSON.stringify(value), 'utf8', 'base64');
    crypted += cipher.final('base64');

    const data = {
        iv: iv.toString('base64'),
        value: crypted
    };

    return new Buffer(JSON.stringify(data)).toString('base64');
};

In other words here's what you'd want to do to get the encrypted token:

  1. Generate initialization vector for encryption (iv).
  2. Take json object with connection settings (see example above) and encrypt it using cyper and key from clientOptions.
  3. Base64 encode result of p.2 (put it in value)
  4. Create anothe json object containing {"iv": iv, "value": value}
  5. Base64 encode result of p.4 and this will be your token

More examples

Websockets and guacd configuration

websocketOptions object is passed directly to ws library. Please refer to ws documentation for more options.

guacdOptions object may contain port and host properties which are passed to node's net.connect() function.

Default connection options

You don't necessary need to pass all connection parameters in the token. You can omit settings that are common for all your connections by moving them to clientOptions.connectionDefaultSettings in guacamole-lite server:

#!/usr/bin/env node

const GuacamoleLite = require('guacamole-lite');

const clientOptions = {
    crypt: {
        cypher: 'AES-256-CBC',
        key: 'MySuperSecretKeyForParamsToken12'
    },

    connectionDefaultSettings: {
        rdp: {
            'create-drive-path': true,
            'security': 'any',
            'ignore-cert': true,
            'enable-wallpaper': false,
            'create-recording-path': true
        }
    }

};

const guacServer = new GuacamoleLite({}, {}, clientOptions);

Query parameters

Some connection options can be modified in the query:

ws://your-guacamole-server:8080/?token=token&width=1024&height=768&dpi=32

Settings from the query override default settings and settings from the token. By default only width, height and dpi can be set in query. Others are ignored. The list of whitelisted parameters can be modified in clientOptions:

#!/usr/bin/env node

const GuacamoleLite = require('guacamole-lite');

const clientOptions = {
    crypt: {
        cypher: 'AES-256-CBC',
        key: 'MySuperSecretKeyForParamsToken12'
    },
    allowedUnencryptedConnectionSettings: {
        rdp: [
            'width',
            'height',
            'dpi',
            'create-drive-path'
        ]
    }
};

const guacServer = new GuacamoleLite({}, {}, clientOptions);

Callbacks

You may need to validate/modify connection parameters after the connection was established.

For this example we will modify token object the following way:


{
    "expiration": 3510738000000,
    "userId": 777,
    "connection": {
        "type": "rdp",
        "settings": {
            "hostname": "10.0.0.12",
            "username": "Administrator",
            "password": "pAsSwOrD",
            "enable-drive": true
        }
    }
}

As you see we have added expiration and userId which are not used by guacamole-lite itself, buy may be used by your application built on top of it. Like in this example:

#!/usr/bin/env node

const GuacamoleLite = require('guacamole-lite');

const clientOptions = {
    crypt: {
        cypher: 'AES-256-CBC',
        key: 'MySuperSecretKeyForParamsToken12'
    },
};

const callbacks = {
    processConnectionSettings: function (settings, callback) {
        if (settings.expiration < Date.now()) {
            console.error('Token expired');

            return callback(new Error('Token expired'));
        }

        settings.connection['drive-path'] = '/tmp/guacamole_' + settings.userId;

        callback(null, settings);
    }
};

const guacServer = new GuacamoleLite({}, {}, clientOptions, callbacks);

In this example we have new object callbacks which contains function processConnectionSettings. This function accepts settings which is basically slightly flattened token object and callback. Callback in it's turn accepts two parameters: err (in case of an error) and settings which is modified token object (we have added 'drive-path' in the example). Callback must be called at the end of the function.

Please note that connection property does not contain rdp, but instead contains everything that was previously in rpd.

Also note the new fourth parameter (callbacks) in the last line with new GuacamoleLite.

Events

guacamole-lite also emits the following events:

  • open - when connection to the host is established
  • close - when connection is closed
  • error - when error in connection occured

In this example we will use these events to send postbacks to our backend:

#!/usr/bin/env node

const GuacamoleLite = require('guacamole-lite');
const Http = require('http');

const clientOptions = {
    crypt: {
        cypher: 'AES-256-CBC',
        key: 'MySuperSecretKeyForParamsToken12'
    },
};

const guacServer = new GuacamoleLite({}, {}, clientOptions);

guacServer.on('open', (clientConnection) => {
    const url = 'http://our-backend-server/api/connection/open?userId=' + clientConnection.connectionSettings.userId
    
    Http.request(url).end();
});

guacServer.on('close', (clientConnection) => {
    const url = 'http://our-backend-server/api/connection/close?userId=' + clientConnection.connectionSettings.userId
    
    Http.request(url).end();
});

guacServer.on('error', (clientConnection, error) => {
    console.error(clientConnection, error);
});

Note that clientConnection object is passed to all event listeners and can be used to access connectionSettings (which is token object).

ExpressJS example

#!/usr/bin/env node

const GuacamoleLite = require('guacamole-lite');
const express = require('express');
const http = require('http');

const app = express();

const server = http.createServer(app);

const guacdOptions = {
    port: 4822 // port of guacd
};

const clientOptions = {
    crypt: {
        cypher: 'AES-256-CBC',
        key: 'MySuperSecretKeyForParamsToken12'
    }
};

const guacServer = new GuacamoleLite({server}, guacdOptions, clientOptions);

server.listen(8080);

Log levels

#!/usr/bin/env node

const GuacamoleLite = require('guacamole-lite');

const websocketOptions = {
    port: 8080 // we will accept connections to this port
};

const guacdOptions = {
    port: 4822 // port of guacd
};

const clientOptions = {
    crypt: {
        cypher: 'AES-256-CBC',
        key: 'MySuperSecretKeyForParamsToken12'
    },
    log: {
        level: 'DEBUG'
    }
};

const guacServer = new GuacamoleLite(websocketOptions, guacdOptions, clientOptions);

clientOptions.log.level defines verbosity of logs. Possible values are:

  • "QUIET" - no logs
  • "ERRORS" - only errors
  • "NORMAL" - errors + minimal logs (startup and shutdown messages)
  • "VERBOSE" - (default) normal + connection messages (opened, closed, guacd exchange, etc)
  • "DEBUG" - verbose + all OPCODES sent/received within guacamole sessions

Custom log functions

By default guacamole-lite uses console.log and console.error functions for logging. You can redefine these functions by setting clientOptions.log.stdLog and clientOptions.log.errorLog like in the example below. Note that clientOptions.log.level is still applied, which means that messages that don't match desired log level won't be sent to your custom functions

#!/usr/bin/env node

const GuacamoleLite = require('guacamole-lite');

const websocketOptions = {
    port: 8080 // we will accept connections to this port
};

const guacdOptions = {
    port: 4822 // port of guacd
};

const clientOptions = {
    crypt: {
        cypher: 'AES-256-CBC',
        key: 'MySuperSecretKeyForParamsToken12'
    },
    log: {
        level: 'DEBUG',
        stdLog: (...args) => {
            console.log('[MyLog]', ...args)
        },
        errorLog: (...args) => {
            console.error('[MyLog]', ...args)
        }
    }
};

const guacServer = new GuacamoleLite(websocketOptions, guacdOptions, clientOptions);

Tests

No tests yet :(

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].