Guacamole是什么
对于Guacamole的解释,我想从三个层次谈起。首先,Guacamole 是一个 HTML5 网络应用程序,使用远程桌面协议(如VNC或RDP)来提供对桌面环境的访问。其次,Guacamole是一个API,这个 API 提供的核心组件和库可以用于在现有网络应用程序中添加 HTML5 远程访问的功能。最后,Guacamole是一个协议,该协议本身不具备远程连接功能,但具备远程屏幕绘制和事件传输的功能,提供跨浏览器的鼠标和键盘事件,以及具有加速合成同步的可嵌套图层,能够在浏览器页面呈现远程操作画面。通过Guacamole,我们可以在任何有浏览器的地方登入并操作远程服务器。
Guacamole的架构
Guacamole 不是一个独立的网络应用程序,它由三个部分组成,分别是guacamole客户端、guacamole服务端、guacd代理端。
-
guacamole客户端由JavaScript实现,它是直接和用户交互的部分,一旦它被加载到用户的web浏览器里,将立即连接到guacamole服务端。客户端和服务端之间的交互是通过HTTP 或 WebSocket之上的guacamole 协议完成的。客户端会实时绘制屏幕,捕获用户的键盘,鼠标等操作,并生成对应的guacamole协议的指令,通过服务端传递给guacd代理端。
-
guacamole服务端由Java实现,实际上它可以由任何语言实现,它最大的作用是作为中间人传递guacamole客户端和guacd代理端之间通信的消息,消息为guacamole协议的指令。guacamole服务端不仅可以读取guacamole协议的数据转发到guacd代理端,也可以在这一模块实现用户身份验证的功能。
-
guacamole 代理端(guacd)是一个原生应用程序,由 C 语言实现,它不具备任何身份验证功能。它负责将 Guacamole 协议的数据翻译成 RDP、VNC 等远程桌面协议的数据格式,并以客户端的身份连接到多个远程桌面服务端。guacd 是一个后台运行的守护进程,它与 Guacamole 一起安装。它监听来自guacamole服务端的 TCP 连接请求。实际上guacd 本身并不了解任何特定的远程桌面协议,而是仅实现了guacamole协议和其他远程协议的翻译,用于确定需要加载哪种远程协议的连接插件以及给插件传递参数。一旦加载了远程连接的客户端插件,它就可以独立于 guacd 运行,直到客户端插件终止。
以上三个组成部分中,guacamole 代理端(guacd)是 Guacamole 的核心组件,它动态加载支持不同远程桌面协议的客户端插件,并根据 Web 应用程序的指令将它们连接到相应的远程桌面。Guacamole 服务端和 Guacamole 客户端只需要了解 Guacamole 协议,捕获用户的鼠标键盘等事件并生成相应的guacamole协议的指令,并传输指令给guacd,它们无需知道具体使用的是哪种远程桌面协议。
Guacamole协议
开发的过程中,通常不使用官方的guacamole服务端,只需要基本的通信流程,虽然无需理解guacamole协议具体的内容,但需要知道协议的指令结构,如何读取解析指令,也需要知道如何向guacd发起连接。
Guacamole 协议由指令组成。每条指令都是个用逗号分隔的列表,指令以分号结尾。其中,指令的第一个元素是指令操作码,其余元素都是该指令的参数,例如:
OPCODE,ARG1,ARG2,ARG3,...;
列表中的每一个由逗号隔开的元素都有一个正整数的长度前缀,由点(英文句号.)分隔。这个长度表示该元素包含的 Unicode 字符数,采用 UTF-8 编码,例如:
LENGTH.VALUE
长度和字符组成一个元素,多个元素组成一条指令,多条指令可以构成一次消息传输。从客户端到服务器的指令通常是控制指令(用于连接或断开)和事件(鼠标和键盘)。从服务器到客户端的指令通常是绘图指令(缓存、裁剪、绘制图像),将客户端用作远程显示。例如,将显示大小设置为 1024x768 的完整有效指令为:
4.size,1.0,4.1024,3.768;
该指令将被解码为四个元素:"size"(size 指令的操作码),"0"(默认图层的索引),"1024"(所需宽度,像素为单位),"768"(所需高度,像素为单位)。
Guacamole 协议的结构使得它可以被流式传输,同时也可以被 JavaScript 轻松解析。Guacamole 协议可以在接收时就进行解析,且每个指令元素中的长度前缀意味着解析器无需逐字符遍历。
在开发guacamole服务端的时候,需要主动向guacd发起握手建立连接,它始于客户端发送的"select"指令,告知服务器将加载哪种远程协议,并传输连接所需参数,具体握手过程如下:(图中的客户端指Guacamole 服务端和 Guacamole 客户端整体,服务端指guacamole 代理端)
"ready"指令包含新客户端连接的 ID,标志着交互阶段的开始。这个 ID 是一个任意字符串,保证与所有其他活动连接以及所有支持的协议名称都是唯一的,实际的交互阶段会立即在"ready"指令发送后开始,此后的过程将与开发无关,是绘图和事件指令来回传递,直到连接关闭。
本地搭建基于Guacamole的H5远程连接应用
基于java的Guacamole运行参考官方例子:Writing your own Guacamole application — Apache Guacamole Manual v1.5.5
guacd服务端构建:
-
必需依赖:构建guacamole-server,需要Cairo、libjpeg(或libjpeg-turbo)、libpng和libuuid(或OSSP UUID库)。这些库在所有情况下都是必需的。没有它们,无法构建Guacamole。
(1). Cairo被libguac用于图形渲染。
系统 软件包名 Debian / Ubuntu package
libcairo2-dev
Fedora / CentOS / RHEL package
cairo-devel
(2). libjpeg-turbo被libguac用于提供JPEG支持。libjpeg也可以使用,速度可能没有那么快
Debian package
libjpeg62-turbo-dev
Ubuntu package
libjpeg-turbo8-dev
Fedora / CentOS / RHEL package
libjpeg-turbo-devel
Debian / Ubuntu package
libjpeg62-dev
Fedora / CentOS / RHEL package
libjpeg-devel
(3). libpng被libguac用于编写PNG图像,这是Guacamole协议使用的核心图像类型。在以前的Debian版本(如Debian 8 / Ubuntu 16.04)中,需要安装libpng12-dev软件包。
Debian / Ubuntu package
libpng-dev
Fedora / CentOS / RHEL package
libpng-devel
Debian / Ubuntu package(Debian 8 / Ubuntu 16.04)
libpng12-dev
(4). libtool创建了Guacamole所需的编译库。
Debian / Ubuntu package
libtool-bin
Fedora / CentOS / RHEL package
libtool
(5). libuuid被libguac用于为每个用户和连接分配唯一的内部ID。如果libuuid不可用,也可以使用OSSP UUID库:
Debian / Ubuntu package
uuid-dev
Fedora / CentOS / RHEL package
libuuid-devel
Debian / Ubuntu package
libossp-uuid-dev
Fedora / CentOS / RHEL package
uuid-devel
-
可选依赖:包括对各种远程桌面协议的支持,以及这些协议的某些附加功能。
(1). VNC支持取决于libvncclient库,该库是libVNCServer的一部分。
Debian / Ubuntu package
libvncserver-dev
Fedora / CentOS / RHEL package
libvncserver-devel
(2). RDP支持取决于最新版本的FreeRDP。需要FreeRDP 2.0.0或更高版本。
Debian / Ubuntu package
freerdp2-dev
Fedora / CentOS / RHEL package
freerdp-devel
(3). SSH支持取决于libssh2、OpenSSL和Pango。libssh2用于SSH和SFTP支持。Pango是一个文本布局库,Guacamole用它来为需要终端的协议(Kubernetes、SSH和telnet)呈现文本。
Debian / Ubuntu package
libssh2-1-dev
Fedora / CentOS / RHEL package
libssh2-devel
Debian / Ubuntu package
libpango1.0-dev
Fedora / CentOS / RHEL package
pango-devel
(4). FFmpeg提供的libavcodec、libavformat、libavutil和libswscale库用于guacenc在翻译Guacamole会话的录制时对视频流进行编码。
Debian / Ubuntu package
libavcodec-dev, libavformat-dev, libavutil-dev, libswscale-dev
Fedora / CentOS / RHEL package
ffmpeg-devel
(5). OpenSSL提供了对SSL和TLS这两种常见的加密方案,构建SSH需要。
Debian / Ubuntu package
libssl-dev
Fedora / CentOS / RHEL package
openssl-devel
-
安装流程(以下从源码构建)
官网下载安装包,解压;运行configure,确定系统上有哪些库,根据实际安装了什么来选择适当的构建组件。可以看到找到了哪些库,并确定了应该构建什么的清单。将guacd的启动脚本安装到/etc/init.d目录中。
tar -xzf guacamole-server-1.5.4.tar.gz cd guacamole-server-1.5.4/ ./configure --with-init-dir=/etc/init.d make make install ldconfig
- 安装流程(docker构建)
#官方guacd安装 docker run --name my-guacd -d -p 4822:4822 guacamole/guacd #官方guacamole服务端安装(可以替换成自己写的服务端的容器) docker run --name my-guacamole --link some-guacd:guacd -d -p 8080:8080 guacamole/guacamole
-
guacd配置文件:GUACAMOLE_HOME是Guacamole配置目录的名称,默认情况下位于/etc/guacamole。
guacamole.properties:主要的Guacamole配置文件。该文件中的属性决定了Guacamole将如何连接到guacd,并且可以配置已安装的认证扩展的行为。guacamole.properties文件是可选的,用于在默认情况下不足或为扩展提供额外的配置信息时使用。有几个标准属性。
guacd-hostname Guacamole代理守护程序(guacd)正在监听的主机。如果省略,Guacamole将假定guacd正在本地主机上监听。
guacd-port Guacamole代理守护程序(guacd)正在监听的端口。如果省略,Guacamole将假定guacd正在监听端口4822。
enable-environment-properties 如果设置为“true”,Guacamole将首先评估其环境以获取任何给定配置属性的值,然后使用在guacamole.properties中指定的值或返回到默认值。通过启用此选项,使用环境变量覆盖任何其他配置属性。
Guacamole服务端建立连接:
以下为基本配置,属性类型均为字符串类型
协议类型 | 属性 | 值 |
---|---|---|
- | 部署guacd的主机hostname(可在配置文件统一配置) | 默认为localhost |
- | 部署guacd的主机port(可在配置文件统一配置) | 默认为4822 |
SSH | hostname | 192.168.0.0 |
port | 22 | |
username | *** | |
password | ****** | |
RDP | hostname | 192.168.0.2 |
port | 3389 | |
username | Administrator | |
password | ****** | |
ignore-cert:忽略服务器返回的证书 | true | |
VNC | hostname | 192.168.0.3 |
port | 5901 | |
username | *** | |
password | ****** |
RDP和VNC的扩展配置:
协议类型 | 配置属性名 | 属性解释 | guacamole中的属性 |
---|---|---|---|
RDP | 桌面墙纸 | 是否启用桌面墙纸 | enable-wallpaper |
桌面主题 | 是否允许使用窗口和控件的主题 | enable-theming | |
字体平滑 | 如果设置为“true”,文本将以平滑的边缘呈现。默认情况下,通过RDP渲染的文本边缘是粗糙的,因为这样可以减少文本使用的颜色数量,从而减少连接所需的带宽。 | enable-font-smoothing | |
全窗口拖拽 | 如果设置为“true”,窗口的内容将随着窗口移动而显示。 | enable-full-window-drag | |
桌面合成效果 | 如果设置为“true”,将允许图形效果,如透明窗口和阴影。默认情况下,如果可用,这些效果会被禁用。 | enable-desktop-composition | |
菜单动画 | 如果设置为“true”,将允许菜单的打开和关闭动画。菜单动画默认情况下是禁用的。 | enable-menu-animations | |
位图缓存 | 在某些情况下,特别是在已知存在错误的RDP服务器实现中,有必要禁用RDP的内置位图缓存功能。 | disable-bitmap-caching | |
离屏缓存 | RDP通常会维护屏幕上当前不可见的区域的缓存,以加快这些区域在视图中出现时的检索速度。当设置为“true”时,此参数将禁用这些区域的缓存。通常只有在处理RDP服务器实现中已知的错误时才有用,并且在大多数情况下应保持启用状态。 | disable-offscreen-caching | |
VNC | 色彩深度 | 请求的颜色深度,以每像素位数表示。此参数是可选的。如果指定了,它必须是8、16、24或32中的一个。无论选择了什么值,在特定更新使用少于256种颜色时,Guacamole都会将该更新始终发送为256色PNG。 | color-depth |
光标 | 如果设置为“remote”,鼠标指针将在远程渲染,并且鼠标指针的本地位置将由一个小点来指示。远程鼠标指针会感觉比本地指针慢,但如果VNC服务器不支持将鼠标指针图像发送到客户端,则可能是必要的。 | cursor | |
交换红蓝成分 | 如果显示颜色看起来不对(蓝色看起来是橙色或红色等),可能是VNC服务器发送图像数据不正确,导致每种颜色的红色和蓝色分量被交换。如果是这种情况,请将此参数设置为“true”以解决该问题。此参数是可选的。 | swap-red-blue | |
连接vnc代理 | 存在VNC中继器充当中间人或代理,提供单个逻辑VNC连接,然后将其路由到其他地方的另一个VNC服务器。需要额外的参数来选择中继器后面的哪个VNC主机将接收连接。需要填写连接到 VNC 代理时要请求的目标主机和目标端口。 | dest-host、dest-port |