SpringBoot整合Guacamole教程

虛無境發表於2021-08-03

前言

本文主要介紹的是SpringBoot如何整合Guacamole在瀏覽器是遠端桌面的訪問。

Guacamole 介紹

Apache Guacamole 是一個無客戶端遠端桌面閘道器。它支援標準協議,如 VNC、RDP 和 SSH。我們稱之為無客戶端,因為不需要外掛或客戶端軟體。
使用者使用他們的網路瀏覽器連線到 Guacamole 伺服器。用 JavaScript 編寫的 Guacamole 客戶端由 Guacamole 伺服器內的網路伺服器提供給使用者。載入後,此客戶端使用 Guacamole 協議通過 HTTP 連線回伺服器。部署到 Guacamole 伺服器的 Web 應用程式讀取 Guacamole 協議並將其轉發到 guacd,即原生的 Guacamole 代理。這個代理實際上解釋了 Guacamole 協議的內容,代表使用者連線到任意數量的遠端桌面伺服器。Guacamole 協議與 guacd 結合提供了協議不可知性:Guacamole 客戶端和 Web 應用程式都不需要知道實際使用的是什麼遠端桌面協議。

架構圖如下:
在這裡插入圖片描述
協議

Web 應用程式根本不瞭解任何遠端桌面協議。它不包含對 VNC 或 RDP 或由 Guacamole堆疊支援的任何其他協議的支援。它其實只懂Guacamole協議,這是一個用於遠端顯示渲染和事件傳輸的協議。雖然具有這些屬性的協議自然具有與遠端桌面協議相同的能力,但遠端桌面協議和 Guacamole 協議背後的設計原則是不同的:Guacamole 協議並非旨在實現特定桌面環境的功能。
作為遠端顯示和互動協議,Guacamole 實現了現有遠端桌面協議的超集。因此,向 Guacamole 新增對特定遠端桌面協議(如RDP)的支援涉及編寫一箇中間層,在遠端桌面協議和 Guacamole 協議之間進行“轉換”。實現這樣的轉換與實現任何本地客戶端沒有什麼不同,只是這個特定的實現呈現到遠端顯示器而不是本地顯示器。
處理這種翻譯的中間層是 guacd。

guacd

guacd 是 Guacamole 的核心,它動態載入對遠端桌面協議(稱為“客戶端外掛”)的支援,並根據從 Web 應用程式收到的指令將它們連線到遠端桌面。 guacd 是一個守護程式,它與 Guacamole 一起安裝並在後臺執行,監聽來自 Web 應用程式的 TCP 連線。guacd 也不理解任何特定的遠端桌面協議,而是實現了足夠的 Guacamole 協議來確定需要載入哪些協議支援以及必須將哪些引數傳遞給它。載入客戶端外掛後,它會獨立於 guacd 執行,並完全控制自身與 Web 應用程式之間的通訊,直到客戶端外掛終止。 guacd 和所有客戶端外掛都依賴於一個公共庫 libguac,這使得通過 Guacamole
協議進行的通訊更容易也更抽象一些。

網路應用程式

使用者實際與之互動的 Guacamole 部分是 Web 應用程式。
如前所述,Web 應用程式沒有實現任何遠端桌面協議。它依賴於 guacd,並且僅實現了一個漂亮的 Web 介面和身份驗證層。
我們選擇用 Java 實現 Web 應用程式的伺服器端,但沒有理由不能用不同的語言編寫。事實上,因為 Guacamole 旨在成為一個 API,我們鼓勵這樣做。

RealMint

Guacamole 現在是一個通用的遠端桌面閘道器,但情況並非總是如此。Guacamole最初是用 JavaScript 編寫的純文字 Telnet 客戶端,稱為 RealMint(“RealMint”是“終端”的字謎)。它主要是為了演示而編寫的,雖然目的是有用,但它的主要名聲只是因為它是純 JavaScript。
RealMint 使用的隧道是用 PHP 編寫的。與 Guacamole 的 HTTP 隧道相比,RealMint 的隧道僅使用簡單的長輪詢,效率低下。RealMint 有一個不錯的鍵盤實現,現在在 Guacamole 的鍵盤程式碼的一部分中存在,但這實際上是 RealMint 的功能和可用性的範圍。

鑑於它只是一個遺留協議的實現,並且存在其他幾個 JavaScript 終端模擬器,其中大多數已經建立和穩定,該專案被放棄了。

VNC客戶端

一旦開發人員瞭解了 HTML5 canvas 標籤,並看到它已經在 Firefox 和 Chrome 中實現,就開始在概念驗證JavaScript VNC 客戶端上開展工作。

這個客戶端是帶有 Java 伺服器元件的純 JavaScript,通過將 VNC 轉換為相同的基於 XML 的版本來工作。它的發展自然是由VNC 的特性驅動的,它的範圍僅限於將單個連線轉發給一組使用者。儘管相對較慢,但概念驗證執行良好,以至於該專案需要一個線上住所,並在SourceForge 上註冊為“Guacamole”——一個 HTML5 VNC 客戶端。

隨著 Guacamole 的發展並不僅僅是一個概念驗證,對速度的需求也增加了,舊的 RealMint 風格的長輪詢被放棄了,XML 的使用也是如此。

由於當時無法信任 WebSocket 得到支援,並且 Java 沒有用於 servlet 的 WebSocket 標準,因此開發了一個等效的基於 HTTP 的隧道。如果 WebSocket 因任何原因無法使用,此隧道今天仍在使用。

遠端桌面閘道器

開發了一種更快的基於文字的協議,它可以呈現多個遠端桌面協議的功能,而不僅僅是 VNC。整個系統被重新構建為一個標準守護程式 guacd 和一個公共庫 libguac,後者驅動守護程式和協議支援,並變得可擴充套件。 該專案的範圍從一個足夠的 VNC 客戶端擴充套件到一個高效能的 HTML5 遠端桌面閘道器和通用 API。在目前的狀態下,Guacamole可以用作中央閘道器來訪問執行不同遠端桌面伺服器的任意數量的機器。它提供可擴充套件的身份驗證,如果您需要更專業的東西,則可以使用用於基於 HTML5 的遠端訪問的通用 API。

官網:http://guacamole.apache.org/

Guacamole 安裝

參考官網安裝: https://guacamole.apache.org/doc/gug/users-guide.html

建議使用docker安裝,可以快速安裝,docker安裝教程https://www.cnblogs.com/xuwujing/p/15073174.html

Apache Guacamole分為服務端客戶端,均在同一伺服器上部署。

首先是下載映象,Guacamole資料庫可以選擇mysql或 PostgreSQL

docker pull guacamole/guacamole
docker pull guacamole/guacd
docker pull mysql/mysql-server

然後初始化mysql以及對mysql進行相關配置。

docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --mysql > initdb.sql
docker run --name mysql --restart=always  -e MYSQL_ROOT_PASSWORD=123456 -d mysql/mysql-server:5.7
docker cp initdb.sql mysql:/initdb.sql
sudo  docker exec -it mysql mysql -uroot -p123456

CREATE DATABASE guacamole;
CREATE USER 'guacamole'@'%' IDENTIFIED BY 'guacamole';
GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole.* TO 'guacamole'@'%';
FLUSH PRIVILEGES;
quit
docker exec -it mysql bashmysql –uroot –p123456 -Dguacamole<initdb.sql ```="" 依次啟動:="" docker="" run="" --name="" guacd="" --restart="always" -d="" guacamole="" --link="" guacd:guacd="" mysql:mysql="" -e="" mysql_database="guacamole" mysql_user="guacamole" mysql_password="guacamole" -p="" 8080:8080="" ![在這裡插入圖片描述](https:="" img-blog.csdnimg.cn="" 5e51fa6e79334274be699d6d6dcced0f.png?x-oss-process="image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FhendzeHBjbQ==,size_16,color_FFFFFF,t_70)" 可以用="" ps="" 命令檢視是否啟動成功!="" 啟動成功之後,可以在瀏覽器上面輸入:**http:="" ip:8080="" guacamole**="" 進行訪問,預設的賬號密碼都是**guacadmin**;="" deba51affc8e48c48f04c38e4130f433.png?x-oss-process="image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FhendzeHBjbQ==,size_16,color_FFFFFF,t_70)" ##="" springboot整合guacamole="" 在整合之前,需要guacamole已經啟動,且準備一臺windows的遠端機。="" 首先是核心pom檔案:="" <dependency="">
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-websocket</artifactid>
        

        <!-- Servlet API -->
        <dependency>
            <groupid>javax.servlet</groupid>
            <artifactid>servlet-api</artifactid>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <!-- Main Guacamole library -->
        <dependency>
            <groupid>org.apache.guacamole</groupid>
            <artifactid>guacamole-common</artifactid>
            <version>1.1.0</version>
        </dependency>
        <!-- Guacamole JavaScript library -->
        <dependency>
            <groupid>org.apache.guacamole</groupid>
            <artifactid>guacamole-common-js</artifactid>
            <version>1.1.0</version>
            <type>zip</type>
            <scope>runtime</scope>
        </dependency>

示例程式碼可以從這裡下載:http://guacamole.apache.org/api-documentation/
這裡我選擇的是java和js,這裡必須要下載js檔案,本篇文章示例在末尾,可以直接下載。

在這裡插入圖片描述

準備好了,編寫如下程式碼,在示例程式碼有,這裡使用的是webSocket,也可以選擇http方式建立連線。
Java程式碼如下:

 @ServerEndpoint(value = "/webSocket", subprotocols = "guacamole")
@Component
public class WebSocketTunnel extends GuacamoleWebSocketTunnelEndpoint {

    /**
     * Returns a new tunnel for the given session. How this tunnel is created
     * or retrieved is implementation-dependent.
     *
     * @param session        The session associated with the active WebSocket
     *                       connection.
     * @param endpointConfig information associated with the instance of
     *                       the endpoint created for handling this single connection.
     * @return A connected tunnel, or null if no such tunnel exists.
     * @throws GuacamoleException If an error occurs while retrieving the
     *                            tunnel, or if access to the tunnel is denied.
     */
    @Override
    protected GuacamoleTunnel createTunnel(Session session, EndpointConfig endpointConfig) throws GuacamoleException {
        //guacamole server地址 埠
        String hostname = "192.168.0.1";
        int port = 4822;
        GuacamoleConfiguration configuration = new GuacamoleConfiguration();
        configuration.setProtocol("rdp");
        // 遠端windows服務的地址
        configuration.setParameter("hostname", "192.168.0.2");
        configuration.setParameter("port", "3389");
        configuration.setParameter("username", "administrator");
        configuration.setParameter("password", "123456");
        configuration.setParameter("ignore-cert", "true");


        GuacamoleSocket socket = new ConfiguredGuacamoleSocket(
                new InetGuacamoleSocket(hostname, port),
                configuration
        );

        GuacamoleTunnel tunnel = new SimpleGuacamoleTunnel(socket);
        return tunnel;
    }

JavaScript程式碼主要是引用下載的js,使用http的話,核心使用程式碼就是:

  var guac = new Guacamole.Client(
                new Guacamole.HTTPTunnel("tunnel")
  );

WebSocket 程式碼如下:

  var guac = new Guacamole.Client(
                new Guacamole.WebSocketTunnel("webSocket")
             );

完整程式碼如下:


<!--
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
-->


    
        <link rel="stylesheet" type="text/css" href="guacamole.css">
        <title>Guacamole (EXAMPLE)</title>
    

    
    <h1>pancm Guacamole</h1>
        <!-- Display -->
        <div id="display"></div>

        <!-- Guacamole JavaScript API -->
        <script type="text/javascript" src="guacamole-common-js/all.min.js"></script>

        <!-- Init -->
        <script type="text/javascript"> /* <![CDATA[ */

            // Get display div from document
            var display = document.getElementById("display");

            // Instantiate client, using an HTTP tunnel for communications.
           // httl方式
            var guac = new Guacamole.Client(
                new Guacamole.HTTPTunnel("tunnel")
            );
		 // WebSocket 方式
            var guac = new Guacamole.Client(
                new Guacamole.WebSocketTunnel("webSocket")
             );

            // Add client to display div
            display.appendChild(guac.getDisplay().getElement());

            // Error handler
            guac.onerror = function(error) {
                alert(error);
            };

            // Connect
            guac.connect();

            // Disconnect on close
            window.onunload = function() {
                guac.disconnect();
            }

            // Mouse
            var mouse = new Guacamole.Mouse(guac.getDisplay().getElement());

            mouse.onmousedown =
            mouse.onmouseup   =
            mouse.onmousemove = function(mouseState) {
                guac.sendMouseState(mouseState);
            };

            // Keyboard
            var keyboard = new Guacamole.Keyboard(document);

            keyboard.onkeydown = function (keysym) {
                guac.sendKeyEvent(1, keysym);
            };

            keyboard.onkeyup = function (keysym) {
                guac.sendKeyEvent(0, keysym);
            };

        /* ]]> */ </script>

    


編寫完畢之後,我們啟動程式,在瀏覽器上面輸入localhost:9632/api 即可進行遠端桌面。

示例圖:
在這裡插入圖片描述

如何進行前後端分離

前後端在示例程式碼中是未分離的,如果進行分離的話, 在http或WebSocket請求的前面加上ip和埠即可。
如下:

  var guac = new Guacamole.Client(
                new Guacamole.WebSocketTunnel("ws://192.168.0.1:9632/api/webSocket")
             );

WebSocket方式如何傳遞引數以及取值

前端js在請求的url後面加上?key=value&key2=value2& 即可.
示例如下:

  var guac = new Guacamole.Client(
                new Guacamole.WebSocketTunnel("ws://192.168.0.1:9632/api/webSocket?ip=192.168.0.1&")
             );

後端取值程式碼示例:

String ip = session.getRequestParameterMap().get("ip").get(0);

如何設定螢幕寬高

在後端程式碼中,新增如下配置:

   GuacamoleClientInformation information = new GuacamoleClientInformation();
        information.setOptimalScreenHeight(height);
        information.setOptimalScreenWidth(width);

   GuacamoleSocket socket = new ConfiguredGuacamoleSocket(
                new InetGuacamoleSocket(hostname, port),
                configuration,
                information
        );

如何設定錄屏

在後端程式碼中,新增如下配置:

    String fileName = getNowTime() + ".guac";//檔名
    String outputFilePath = "/home/guacamole";
    //新增會話錄製--錄屏
    configuration.setParameter("recording-path", outputFilePath);
    configuration.setParameter("create-recording-path", "true");
    configuration.setParameter("recording-name", fileName);

錄屏的檔案是.guac,我們需要對其進行解碼,命令如下:

guacenc 檔名稱

當然也可以對其設定引數配置,示例圖如下:

在這裡插入圖片描述

如果對生成的檔案格式不滿意,想轉碼的話,可以使用ffmpeg進行轉碼。

如何關閉遠端桌面

關閉後端的session即可。程式碼如下:

  private void optClose(Session session) {
        // 判斷當前連線是否還線上
        if (session.isOpen()) {
            try {
                // 關閉連線
                CloseReason closeReason = new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "進行關閉!");
                session.close(closeReason);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

其他開源遠端桌面工具介紹

Teleport

Teleport是一款簡單易用的堡壘機系統,具有小巧、易用的特點,支援 RDP/SSH/SFTP/Telnet 協議的遠端連線和審計管理。

Teleport由兩大部分構成:

跳板核心服務 WEB操作介面

安裝方式
下載地址:
https://www.tp4a.com/download

Teleport 也是分為服務端和客戶端,服務端安裝如下,下載好檔案之後,上傳在linux服務中進行安裝,命令如下:

tar -zxvf teleport-linux-3.0.2.9.tar.gz
cd teleport-linux-3.0.2.9
sudo ./setup.sh

相關命令:

啟動: /etc/init.d/teleport start
停止: /etc/init.d/teleport stop
重啟: /etc/init.d/teleport restart
檢視執行狀態: /etc/init.d/teleport status

客戶端主要是在進行遠端桌面操作和錄影回放的時候使用, 安裝直接下載到本地執行即可。

啟動之後在瀏覽器輸入:http://teleport伺服器IP:7190/ 進行配置即可。

在這裡插入圖片描述

更多請查閱官網!
官網地址: https://docs.tp4a.com/

JumpServer

JumpServer 使用 Python / Django 為主進行開發,遵循 Web 2.0 規範,配備了業界領先的 Web
Terminal 方案,互動介面美觀、使用者體驗好。

JumpServer 採納分散式架構,支援多機房跨區域部署,支援橫向擴充套件,無資產數量及併發限制。

更多詳細瞭解請查閱官網。
官網地址:https://www.jumpserver.org/

在這裡插入圖片描述

其他

專案地址

專案工程地址:
https://github.com/xuwujing/springBoot-study/tree/master/springboot-guacamole

SpringBoot整個集合的地址:
https://github.com/xuwujing/springBoot-study

SpringBoot整合系列的文章

音樂推薦

原創不易,如果感覺不錯,希望給個推薦!您的支援是我寫作的最大動力!
版權宣告:
作者:虛無境
部落格園出處:http://www.cnblogs.com/xuwujing
CSDN出處:http://blog.csdn.net/qazwsxpcm    
個人部落格出處:http://www.panchengming.com

</initdb.sql>

相關文章