Remote desktop
Kevin Wittmer shows how to build and configure the Apache open-source project Guacamole – from zero to running-code hero.
Kevin Wittmer shows how to build and configure the Apache open-source project Guacamole from zero to running code hero, with client-free remote access.
Guacamole is a open-source software project consisting of a client and server component that work together to enable remote connectivity to server environments from a web browser. In fact, this open-source project goes back as far as 2010, having spent several years being maintained on Sourceforge, with varying periods of development and interest from the Linux community. The project reached a milestone 1.0 release at the beginning of 2019.
In its current state, Guacamole is a nicely matured open source project with high-quality code and runtime components that have a straightforward configuration model, yet it also offers a more advanced configuration and enterprise integration to bolster security and user management, for example.
Guacamole offers ready to run installation packages for distros such as Centos or Debian. However, the thrust of this article will be to illustrate fetching the source code from Github and moving through the series of steps required for local compilation, configuration and deployment of the server-side components – it’s not too difficult.
Beyond introducing you to this very nice open source project, we also want to help you to follow this project at the source code level and encourage you to continue to follow this project.
Tasty features of Guacamole
The Guacamole remote desktop solution has several interesting features, including:
Clientless footprint, as no client-side binary installs or special packages are required.
The backend consists of two major components: the proxy and the web app. The latter is hosted from a servlet-based container host.
Guacamole is open source, so you can build it yourself from the source. The source spans C, Java and Javascript (see Figure 1, page 85).
The source code is licensed under Apache License version 2.0.
There’s a comprehensive online manual and welldocumented APIS.
There’s support for VNC, RDP, SSH and Telnet remote session/protocols.
It has broad enterprise integration capabilities, including LDAP authentication, Duo two-factor authentication, TOTP two-factor authentication, CAS Authentication, Openid Connect Authentication, HTTP header authentication and RADIUS.
Ready-to-run Docker image containing the Guacamole client/server bits.
Gooey architecture of Guacamole
The Guacamole client/server architecture consists of a client-side layer implemented in HTML and Javascript. This browser frontend client layer communicates with a Java-based Servlet. The server layer is mainly represented by the Guacd proxy daemon. This supports a plug-in architecture with protocol support for RDP, VNC, SSH and Telnet (incidentally, more recent code changes include a Kubernetes protocol under development). The proxy is implemented using the C programming language. The source project organisation follows this client and server division, with HTML, Javascript and Java source maintained in the Github guacamole-client project. Meanwhile, the C-based guacd project source is maintained in the guacamole-server project.
The architecture of Guacamole relies on a simplified protocol, the Guacamole Protocol, to efficiently represent handling of remote desktop sessions. This is a textual protocol intended to be Javascript-friendly and which defines a subset of common operations used for remote desktop access.
The protocol defines an instruction format as a comma-delimited list, terminated by a semicolon. The first element of the list is the instruction opcode, followed by instruction arguments. Opcodes include commands such as select , connect , audio , video and image . Here’s a simple example to illustrate the syntax and structure of the Guacamole protocol. 6.select,3.vnc; .. 5.image,10.image/jpeg; .. 7.connect,9.localhost,4.5900,0.,0.,0.;
The Guacd daemon acts as a proxy and does the work of translating between instructions and arguments specified in the Guacamole protocol and arbitrary remote desktop protocols. The contents of the Guacamole protocol along with other browser/server
communication can be protected using HTTPS, as this is a supported configuration. Additionally, the security architecture of a Guacamole client/server installation can be further enhanced by introducing Apache, Nginx or a similar server-side component to provide reverse proxy functionality.
For the rest of this article we’ll illustrate how to compile, build and deploy Guacamole. Don’t worry about typing in the commands and arguments – we’ve provided a shell script on the LXFDVD and archive website, streamlined for Ubuntu 18.04.
Make your own guacamole
The dependencies of the Guacamole server span a few key categories including connectivity, graphics, audio, build and utility. See the table (above right) that shows these dependencies spanning several categories. Given the remote desktop functionality of Guacamole, it should come as no surprise that the leading category is connectivity. In this category, Linux library dependencies include libfreerdp-dev, libssh2-1-dev, libvncserver-dev and libtelnet-dev that provide support for RDP, SSH, VNC and Telnet protocols respectively.
For secure communications, APIS from the library libssl-dev are used. As graphics and image handling are a significant part of a remote desktop experience, several libraries including libjpeg-turbo8-dev, libpngdev and libavcodec are integrated into the server-side project implementation.
The dependencies enumerated above can be installed using apt-get or an equivalent Linux package manager. Prior to building the guacamole-server project source, you’ll need to make sure these dependencies are in the local/target environment. The next step is to fire up the git command and clone the project from Github: git clone https://github.com/apache/guacamoleserver.git cd guacamole-server
After cloning, switch to the source directory and run autoconf to generate the configure scripts used for building, installing and packaging a local build of Guacamole. The autoreconf command can also copy or install missing auxiliary files – include the local subdirectory m4 in this example – like this:
autoreconf -i -Im4
One key output file from executing autoconf as shown above is configure. This file contains build instructions for guacd, guacenc and gauclog, which are the core Guacamole binaries of the guacd proxy program or service. Key steps in this file include checking for the lib dependencies for protocols RDP, SSH, Telnet, VNC and Kubernetes (which is a new addition). The configure script will make intelligent guesses for system-dependent variables and subsequently generate the primary makefile.
sudo ./configure --with-init-dir=/etc/init.d
Running configure with the --with-init-dir argument adds ‘guacd’ as an init.d startup process. This step results in the creation of a shell script file for gauc, supporting the standard service commands getpid , start , restart and status . This enables service-level interaction, including commands such as systemctl and chkconfig. The next step is to launch the build process using the make tool. If you follow the console
build output from make, you will see CC (compilation) and CCLD (linking) commands for libguac along with libraries for SSH, RDP, VNC and Telnet. In the final CC and CCLD build stages, executables guacd, guacenc and
guaclog are generated.
With the binaries created, the final step is installation. The makefile for Guacamole includes an install configuration; simply type make install to complete this step.
make make install
The ldconfig tool will check the header and filenames of the libraries to determine which versions should have links updated. The update-rc.d command will bind
guacd as a runnable service.
sudo ldconfig && update-rc.d guacd defaults
After executing update-rc.d, guacd can run as a bootable service.
Mixing Guacamole and Java, urg!
While the source code of the proxy server part of the project are written in C, the guacamole-client project contains the web frontend components that span HTML 5, Javascript and Java.
A key dependency for local development is Tomcat, or a similar Java servlet container such as Jetty or Wildfly. To begin with the client compilation, grab the source from Github like this:
git clone https://github.com/apache/guacamole-client. git
Cloning the subdirectory installs the source tree structure including docs, extensions with the various auth types, the main and common subdirectories, the Javascript commons and the extension folders. Each of these projects contains a pom.xml file. Change directory into the client source and launch vim to inspect the top-level pom.xml.
vim pom.xml
The project object model (hence the name ‘pom’) specify modules for the guacamole Web application, the extensions API and guacamole-common – APIS for Java and Javascript. In addition, it enumerates modules for authentication for various enterprise integration scenarios, like this:
…
Following the modules element are the build steps, which appear as plug-ins below the
The high-level form of the Guacamole build specification containing plug-ins for building, binding and verify appear as:
..
..
To trigger the steps defined in the plugins section,
use mvn and specify the package argument: mvn package
The key packaged output is the Guacamole war file written to the subdirectory guacamole/target (from parent subdirectory guacamole-client). You will want to copy this war archive file to the servlet container environment: Jetty, Wildfly or in our case, Tomcat. cd guacamole/target/ cp guacamole-1.0.0.war /var/lib/tomcat8/webapps/ guacamole.war
Before launching Tomcat, we first need to complete the server-side configuration. To configure the guacd
service, you will need to create the subdirectory guacamole below the /etc subdirectory and then create the guacamole.properties file.
mkdir /etc/guacamole
You can use vim to create the properties file.
vim guacamole.properties
The guacamole.properties file supports several properties including these key ones:
The host name and port that guacd listens on. The Java-centric lib subdirectory for web apps. The location of the user-mapping file, used as the default authentication model.
Properties to enable/configure authentication backed by a database. Schema support includes MYSQL, Postgres, and SQL Server.
The host name can be localhost , with port 4822 listed as the default port to which guacd listens. Of course, in an enterprise environment you might decide to run guacd in a different environment than the servlet container hosting the Guacamole web app. libdirectory points to the Java-centric guacamole subdirectory – for example, /var/lib/tomcat8/ webapps/guacamole/web-inf/classes. The path for the user-mapping file is by convention /etc/guacamole.
Guacamole is green…
Below is an example of the guacamole.properties file. In this example, the config specification enumerates hostname, port, lib path to the class files, authentication provider and the file-based user mapping in XML form – this is associated to the default or basic authentication provider.
#hostname and port of guacamole proxy guacd-hostname: localhost guacd-port: 4822
#Location to read extra .jar’s from lib-directory: /var/lib/tomcat8/webapps/guacamole/ Web-inf/classes #Authentications provider class auth-provider: net.sourceforge.guacamole.net.basic. Basicfileauthenticationprovider
# properties used by Basicfileauthenticationprovider basic-user-mapping: /etc/guacamole/user-mapping. xml
In addition to the properties file, the file guacd.conf (also residing in /etc/guacamole/) contains additional configuration for the guacd proxy. This includes runtime properties such as log level. We’ll create the file to specify a non-default log level:
sudo vim guacd.conf
To enable debug logging of guacd, specify the following in the [daemon] section:
[daemon] log_level = debug
With the guacd configuration complete, and having previously registered guacd with the local service management facilities, we are now ready to fire up the Guacamole proxy as follows.
sudo service guacd start cd /var/log tail -f syslog
After starting the Guacamole proxy, move to /var/ log and tail the syslog file where the guacd process appends log messages. Later you can follow the messaging from this log file as you interact with the frontend web UI and begin to get a sense of the translation of UI interactions into lower-level primitives represented in the Guacamole protocol. These are eventually converted to remote session protocolspecific commands. Configure to taste To run Guacamole with the default user-authentication model, we use a file called user-mapping.xml in /etc/guacamole. If you completed the previous configuration, this subdirectory already exists. Let’s use vim to create this XML file.
vim user-mapping.xml
After launching vim, define the skeleton XML content like this:
…
Note you have the option to specify a hashed password rather than maintaining the password in clear text. To use this more secure form, hash the password with md5sum and copy the output value as a string specifying the password, along with the XML attribute encoding=”md5” . To define the remote connection, use
the connection element. The sub-elements are
protocol along with the host name and port number. The core syntax and structure is:
10.x.y.z port-number
An example connection of SSH is shown here. In this case, the protocol element specifies SSH.
70.33.208.51 22
This next example illustrates RDP that includes
param elements for security, certificate handling and colour depth.
10.93.199.13 3389 nla true 16
This last example illustrates a VNC connection specification.
10.93.199.15 5901
password
User authentication can be also be configured at the database level, rather than as a static XML file. The source subdirectory guacamole-client/extensions/ guacamole-auth-jdbc/modules includes DB support for MYSQL, Postgres SQL and SQL Server. Details of database configuration for user authentication are beyond the scope of this article, but you can gain a better sense of the user model by studying the schema found in one of the supported providers – for example the MYSQL schema which is in the subdirectory modules/guacamole-auth-jdbc-mysql/schema.
Guacamole proxy and web app
To fire up Guacamole, let us launch guacd and tomcat as services:
sudo service guacd start && service tomcat8 start
In case you jumped ahead and have done this already, you can also restart the services by using the following syntax.
sudo service guacd restart && service tomcat8 restart
As noted earlier, it is can be quite helpful to tail the log files as you interact with the Guacamole user interface. You can then cross-reference log messages with the source code downloaded in earlier steps.
cd /var/log tail -f syslog
As a reminder, log messaging from the guacd proxy appears in syslog, while log messaging from the web app appears in the Tomcat catalane.out file. In the case of guacamole-client, you can use the open-source Logback framework to redirect and/or define additional log destinations.
cd /var/lib/tomcat8/logs tail -f catalina.out
Enjoying your Guacamole
To access Guacamole, fire up a Web browser and navigate to the IP address or host name of the host environment from where you built the source code. Include the default port of 8080 along with the path /guacamole/ – if you changed the port and/or path of your host container, you will need to adjust the URL accordingly. The format should take the form: http://10.x.y.z:8080/guacamole/#/
The initial screen is a web login where you enter credentials, either maintained in the user-mapping.xml
configuration file or – the better option – as the user credentials maintained in a backend database system such as MYSQL.
After a successful login you will be presented with the initial view listing all connections, along with one or more thumbnails of recent remote desktop sessions. A UI filter option is also available; for example you can enter Red Hat to narrow the list of servers shown (in this case, to show Red Hat servers only, of course). To access a server, click it to launch a remote session.
There is a user menu with settings where you can set language, default input mode and default mouse emulation mode (see the box on page 84 for more about these). Once a remote session is established, following successful user authentication from that target host/environment, the remote desktop session will provide an experience very close to a native RDP or VNC connection. Depending on the target environment, you might want to make some additional adjustments to screen resolution, however.
That’s all the free Guacamole we can dish out in this first look at building it from source and deploying it on your own systems. In the next instalment, we’ll delve further into Docker support, enterprise integration and new Kubernetes capabilities.