guacamole集成到自己的项目中

本文档详细介绍了如何将guacamole集成到自己的项目中,包括部署guacamole、docker和mysql服务,创建及管理连接,以及前端如何嵌入guacamole。在部署过程中提到了防火墙配置、docker安装、mysql服务搭建,并提供了添加、查询和删除连接的API使用方法。
摘要由CSDN通过智能技术生成

将 guacamole嵌入到自己的应用当中

部署guacamole

选用了docker部署,需要部署三个应用,mysql服务, guacd服务 guacamole服务。


以下环境为centos7.6操作

关闭防火墙或者开启必要接口

firewall-cmd --zone=public --add-port=9090/tcp --permanent
firewall-cmd --zone=public --add-port=4822/tcp --permanent
firewall-cmd --zone=public --add-port=3306/tcp --permanent

firewall-cmd --reload


以是我部署时用到的,可以自行删除非必要的端口


或者直接关闭防火墙

部署docker

yum -y update
yum remove docker docker-common docker-selinux docker-engine
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum -y install docker-ce-18.03.1.ce
systemctl start docker
systemctl enable docker

部署mysql服务

我自己执行的命令如下(不是必须如此做),先映射了两个目录mariadb/conf mariadb/data
设定了密码,执行了如下操作。可以通过局域网ip访问到了。相关的文档都传到csdn的共享里了
docker run \
    --name mariadb \
    -d \
    -p 3306:3306 \
    -v /opt/data/mariadb/conf/my.cnf:/etc/mysql/my.cnf  \
    -v /opt/data/mariadb/data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD='123456' \
    --restart=always \
    mariadb:10.4.10



还可以简单执行一个docker命令来部署mysql服务,无论怎样,保证可以访问到,可以登录进去。
docker run  -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 mysql



获取一下镜像 
docker pull guacamole/guacamole
docker pull  guacamole/guacd


执行如下命令

docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --mysql > initdb.sql

会在执行命令目录下生成一个sql文件。我通过navicat连接上了mariadb,然后导入了这个文件,创建的数据库名字为
guacamole,编码是utf8 utf8_general_ci



部署guard

docker run --name guacd -d -p 4822:4822 --privileged=true guacamole/guacd

部署guacamole

docker run --name guacamole \
--link guacd \
-e MYSQL_DATABASE=guacamole \
-e MYSQL_USER=root \
-e MYSQL_HOSTNAME=192.168.1.61  \
-e MYSQL_PASSWORD='123456' \
--privileged=true \
-d -p 9090:8080 guacamole/guacamole

三个部署完,就可以通过映射出来的9090访问界面了

http://ip:9090/guacamole 可以看到页面

默认用户名密码 guacadmin guacadmin

首先需要测试一下配置一个windows试试 看看能不能远程,windows用的rdp配置如下,点击设置-》连接-》新建连接

在这里插入图片描述

在这里插入图片描述

可以修改下登录里的标题,需要修改docker里的文件

/home/guacamole/tomcat/webapps/guacamole/translations/zh.json
在这里插入图片描述

还可以修改css等。

如果是用docker cp的方式修改的文件需要注意权限,否则不生效。

需要docker exec -it -u root guacamole bash 进入容器

进入/home/guacamole/tomcat/webapps/guacamole/translations

执行chouwn guacamole:guacamole zh.json

然后docker restart guacamole 才能生效

接下来就是通过api获取token,只要有了token就可以访问界面上的network里的所有连接后边跟上?token=xxxxxxxx

获取token的java代码其他的一样 就是发送一个http请求

 // Guacamole API 认证信息
    private static final String GUAC_USERNAME = "guacadmin";
    private static final String GUAC_PASSWORD = "guacadmin";

    // Guacamole 服务器信息
    private static final String GUAC_HOST = "xx.xx.xx.xx";
    private static final String GUAC_PORT = "9090";

    // Guacamole API 基础 URL
    private static final String GUAC_API_BASE_URL = "http://" + GUAC_HOST + ":" + GUAC_PORT + "/guacamole/api";

    public String getToken() throws IOException {
        String authURL = GUAC_API_BASE_URL + "/tokens";
        URL url = new URL(authURL);
        String authString = GUAC_USERNAME + ":" + GUAC_PASSWORD;
        String encodedAuthString = Base64.getEncoder().encodeToString(authString.getBytes());
        String authData = "username=" + GUAC_USERNAME + "&password=" + GUAC_PASSWORD;
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Authorization", "Basic " + encodedAuthString);
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setDoOutput(true);
        conn.getOutputStream().write(authData.getBytes());
        int responseCode = conn.getResponseCode();

        if (responseCode != HttpURLConnection.HTTP_OK) {
            throw new RuntimeException("Failed : HTTP error code : " + responseCode);
        }

        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        StringBuilder responseBuilder = new StringBuilder();
        String output;
        while ((output = br.readLine()) != null) {
            responseBuilder.append(output);
        }
        conn.disconnect();

        JsonObject responseJson = JsonParser.parseString(responseBuilder.toString()).getAsJsonObject();
        return responseJson.get("authToken").getAsString();
    }

这样就有token了,也可以用postman请求出来这个token

增加连接

String token = getToken();
String apiAdd = GUAC_API_BASE_URL + “/session/data/mysql/connections?token=” + token;

然后发送post请求,json格式的参数就可以增加成功

json 的格式,可以通过界面里设置保存的时候看到,调试开发工具里的network可以,拷贝一个示例,只需要传入额时候改下name, hostname, password,username就可以了

{
    "name": "123",
    "identifier": "6",
    "parentIdentifier": "ROOT",
    "protocol": "ssh",
    "attributes": {
        "guacd-encryption": "",
        "failover-only": "",
        "weight": "",
        "max-connections": "12",
        "guacd-hostname": null,
        "guacd-port": "",
        "max-connections-per-user": "1"
    },
    "activeConnections": 0,
    "lastActive": 1677653601000,
    "parameters": {
        "hostname": "xx.xx.xx.xx",
        "password": "123456",
        "port": "22",
        "username": "root",
        "color-scheme": "",
        "font-size": "",
        "scrollback": "",
        "read-only": "",
        "disable-copy": "",
        "disable-paste": "",
        "timezone": null,
        "server-alive-interval": "",
        "backspace": "",
        "terminal-type": "",
        "create-typescript-path": "",
        "recording-exclude-output": "",
        "recording-exclude-mouse": "",
        "recording-include-keys": "",
        "create-recording-path": "",
        "enable-sftp": "",
        "sftp-disable-download": "",
        "sftp-disable-upload": "",
        "wol-send-packet": "",
        "wol-udp-port": "",
        "wol-wait-time": ""
    }
}

再来一个windows的示例吧,改name, hostname, password username就可以了,用的rdp协议

{
    "name": "0637FGCZ49J13ARJ",
    "identifier": "29",
    "parentIdentifier": "ROOT",
    "protocol": "rdp",
    "attributes": {
        "guacd-encryption": "",
        "failover-only": "",
        "weight": "",
        "max-connections": "10",
        "guacd-hostname": null,
        "guacd-port": "",
        "max-connections-per-user": "5"
    },
    "activeConnections": 0,
    "lastActive": 1677668267000,
    "parameters": {
        "hostname": "xx.xx.xx.xx",
        "password": "123456",
        "security": "nla",
        "ignore-cert": "true",
        "port": "3389",
        "username": "admin",
        "disable-auth": "",
        "gateway-port": "",
        "server-layout": "",
        "timezone": null,
        "enable-touch": "",
        "console": "",
        "width": "",
        "height": "",
        "dpi": "",
        "color-depth": "",
        "force-lossless": "",
        "resize-method": "",
        "read-only": "",
        "normalize-clipboard": "",
        "disable-copy": "",
        "disable-paste": "",
        "console-audio": "",
        "disable-audio": "",
        "enable-audio-input": "",
        "enable-printing": "",
        "enable-drive": "",
        "disable-download": "",
        "disable-upload": "",
        "create-drive-path": "",
        "enable-wallpaper": "",
        "enable-theming": "",
        "enable-font-smoothing": "",
        "enable-full-window-drag": "",
        "enable-desktop-composition": "",
        "enable-menu-animations": "",
        "disable-bitmap-caching": "",
        "disable-offscreen-caching": "",
        "disable-glyph-caching": "",
        "preconnection-id": "",
        "recording-exclude-output": "",
        "recording-exclude-mouse": "",
        "recording-exclude-touch": "",
        "recording-include-keys": "",
        "create-recording-path": "",
        "enable-sftp": "",
        "sftp-port": "",
        "sftp-server-alive-interval": "",
        "sftp-disable-download": "",
        "sftp-disable-upload": "",
        "wol-send-packet": "",
        "wol-udp-port": "",
        "wol-wait-time": ""
    }
}

查询identifier

根据名字获取identifier。这个很简单,循环里可以写自己的路基主要就是看那个路径

= GUAC_API_BASE_URL + “/session/data/mysql/connectionGroups/ROOT/tree?token=” + tok

    public String getConnections(String name) throws IOException {
        String token = getToken();
        String res = "none";
        String queryURL = GUAC_API_BASE_URL + "/session/data/mysql/connectionGroups/ROOT/tree?token=" + token;
        String json = HttpUtils.getApi(queryURL);
        Gson gson = new Gson();
        GuacamoleDTO guacamoleDTO = gson.fromJson(json, GuacamoleDTO.class);
        List<ChildConnections> list = guacamoleDTO.getChildConnections();
        for (ChildConnections childConnections : list) {
            if (name.equals(childConnections.getName())) {
                res =  childConnections.getIdentifier();
                break;
            }
        }
        return res;
    }

删除连接

        String token = getToken();
        String deleteURL = GUAC_API_BASE_URL + "/session/data/mysql/connections/" + identify + "?token=" + token
        // 以上url中的关键是identify 这个是个标识,这个就是查询获得的 
        http的method是DELETE
        附上java的代码示例吧
        public static void deleteQuery(String url) {
            String result = null;
            CloseableHttpClient httpclient = HttpClients.createDefault();
            try {

                HttpDelete httpDelete = new HttpDelete(url);
                httpDelete.addHeader("Content-type", "application/json; charset=utf-8");

                CloseableHttpResponse response = httpclient.execute(httpDelete);
                try {
                    // 获取响应实体
                    HttpEntity entity = response.getEntity();
                    // 打印响应状态
                    System.out.println(response.getStatusLine());
                    if (entity != null) {
                        result = EntityUtils.toString(entity, "UTF-8");
                    }
                } finally {
                    response.close();
                }
            } catch (Exception e) {
            System.out.println("executing httpDelete error: " + e.getMessage());
            } finally {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    System.out.println("executing httpDelete error: " + e.getMessage());
                }
           }
        }
        
        public static String postWithJson(String url, String json) {
        String result = null;
        // 创建默认的httpClient实例
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            // 创建httppost
            HttpPost httppost = new HttpPost(url);
            httppost.addHeader("Content-type", "application/json; charset=utf-8");
            System.out.println("executing request " + httppost.getURI());

            // 向POST请求中添加消息实体
            StringEntity se = new StringEntity(json, "UTF-8");
            httppost.setEntity(se);
            System.out.println("request parameters " + json);

            // 执行post请求
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                // 获取响应实体
                HttpEntity entity = response.getEntity();
                // 打印响应状态
                System.out.println(response.getStatusLine());
                if (entity != null) {
                    result = EntityUtils.toString(entity, "UTF-8");
                    // 打印响应内容
                    System.out.println("--------------------------------------");
                    System.out.println("Response content: " + EntityUtils.toString(entity, "UTF-8"));
                    System.out.println("--------------------------------------");
                }
            } finally {
                response.close();
            }
        } catch (Exception e) {
            System.out.println("executing httpPostWithJSON error: " + e.getMessage());
        } finally {
            // 关闭连接,释放资源
            try {
                httpclient.close();
            } catch (IOException e) {
                System.out.println("executing httpPostWithJSON error: " + e.getMessage());
            }
        }
        return result;
    }
前台怎么嵌入呢

后台通过http获取到的就是identifier,这个打印出来就是个数字。但是从首页上去点击链接访问,发现url是client/MjYAYwBteXNxbA client后有一个编码后的字符串。这个是前端的一个操作。通过查看代码guacamole-client的源码,总结出来下边js的代码

// 其中12 表示identifier 就是链接里的那个
// c表示的是connections,这个是固定的不用改,查看源码可以看到
// mysql 表示数据源, 这个也是固定的 还有的会用到mysql-shard 通过查看network可以看到这些
window.btoa(['12', 'c', 'mysql'].join('\0')).replace(/[+/=]/g,
            (str) => ({
              '+': '-',
              '/': '_',
              '=': ''
            })[str])


以上转换完就是那串加密后的字符了 然后拼接上/client/ 就可以给前台嵌入到iframe里了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰明子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值