Chapter 2. Installing Guacamole

Packages from your distribution

Guacamole is included in the repositories of several Linux distributions. If your distribution provides Guacamole packages for you, this is the preferred method of installing Guacamole. If your distribution does not provide Guacamole packages, or the packages provided are too old, you can build Guacamole from source fairly easily.

Important

Be aware that Guacamole is a remote desktop gateway, and cannot access your desktop's display without a remote desktop server of some kind to connect to. Guacamole does not contain its own VNC or RDP server, and these installation procedures will not walk you through the installation of a VNC or RDP server.

Your distribution of choice will provide documentation for setting up VNC, as will the documentation provided by those that created the VNC server you wish to use. If you are going to use RDP to connect to Windows computers, Microsoft (and many others on the internet) provides documentation describing how to set up remote desktop.

Installing Guacamole from your distribution's guacamole package will typically install the web application and the proxy guacd, along with support for VNC (libguac-client-vnc). If you want support for RDP or SSH, you will need to install those packages as well.

After the Guacamole packages are installed, the web application may still need to be deployed to your servlet container. Some packages, like the Debian package called guacamole-tomcat, will do this for you, but if your distribution provides no such package, you will have to deploy Guacamole yourself.

Debian and Ubuntu

The Debian repositories contain packages for all of Guacamole's components, and Ubuntu has inherited those packages (being Debian-based).

There is also a PPA which contains the most recent stable build of Guacamole while updates to the official Debian and Ubuntu repositories are pending. If you don't want to wait for the main repositories to update, users of Ubuntu can just add the PPA and install the packages from there:

$ sudo add-apt-repository ppa:guacamole/stable
[sudo] password for user: 
You are about to add the following PPA to your system:
 The most recent stable release of Guacamole and its components. The packages
here use the same packaging as the downstream Debian and Ubuntu packages, but
are updated more frequently, usually while the corresponding downstream
packages are under official review.
 More info: https://launchpad.net/~guacamole/+archive/stable
Press [ENTER] to continue or ctrl-c to cancel adding it

gpg: keyring `/tmp/tmpc7ipgi/secring.gpg' created
gpg: keyring `/tmp/tmpc7ipgi/pubring.gpg' created
gpg: requesting key 106BB296 from hkp server keyserver.ubuntu.com
gpg: /tmp/tmpc7ipgi/trustdb.gpg: trustdb created
gpg: key 106BB296: public key "Launchpad PPA for Guacamole" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
OK
$ 

For users of Debian or any flavor of Ubuntu, installing Guacamole is as simple as installing the guacamole-tomcat package, and then editing the /etc/guacamole/user-mapping.xml file to add some connections. The guacamole-tomcat package will install Tomcat and automatically create the necessary symbolic links to deploy Guacamole. If you don't want to use Tomcat, or you want to deploy Guacamole manually, you can install the guacamole package instead, and follow the deployment instructions provided in this chapter.

# apt-get install guacamole-tomcat
# 

If you install the guacamole-tomcat package, you will be prompted for whether you wish to restart Tomcat automatically. Tomcat must be restarted after Guacamole is installed or upgraded. If you don't want to do this, or you want to do this manually, choose "No" (the default). Choosing "Yes" will restart Tomcat for this and future installs of Guacamole.

Important

The Debian and Ubuntu packages will set up guacd such that it runs as its own reduced-privilege guacd user, for the sake of security. Similarly, the user-mapping.xml file will only be readable by users in the guacamole-web group, as it will potentially contain sensitive information like passwords in plain text.

The guacamole-tomcat package will automatically put the tomcat6 user in the guacamole-web group, but if you are installing Tomcat manually or using another servlet container, you must ensure your servlet container's user is a member of the guacamole-web group. If you do not do this, your servlet container will not be able to read user-mapping.xml, and all attempts to login to Guacamole will fail.

By default, VNC support will be installed as a dependency of the guacamole package. If you want SSH or RDP support, you will need to install libguac-client-ssh0 or libguac-client-rdp0 manually:

# apt-get install libguac-client-ssh0 libguac-client-rdp0
# 

Recent versions of Debian and Ubuntu have a recent-enough version of FreeRDP and include libguac-client-rdp0, but if you're using an older version of Debian (such as Debian 6.0 a.k.a. "squeeze"), you will have to either do without RDP support or install FreeRDP and guacamole-server manually, without using your distribution's packages.

Once installed, both Tomcat and guacd will start automatically and on boot.

Fedora, RHEL, and CentOS

Fedora has an excellent Guacamole package, guacamole, which will automatically install deploy Guacamole to Tomcat. It does not depend on guacd, however, and you thus must install the guacd package manually alongside guacamole:

# yum install guacamole guacd
# 

Depending on which protocols you require support for, you will need to install one of the libguac-client-* packages to provide support for those protocols. Most users will want at least libguac-client-vnc. If you want SSH support, or access to RDP servers, you will need to install libguac-client-ssh or libguac-client-rdp respectively.

# yum install libguac-client-vnc libguac-client-ssh libguac-client-rdp
# 

Neither RHEL nor CentOS include Guacamole packages in their main repositories, however Fedora maintains a repository called EPEL which contains binaries compatible with both RHEL and CentOS. The EPEL repository contains the Guacamole packages described above. If you wish to install Guacamole on RHEL or CentOS, you should either add the EPEL repository and install from that, or build Guacamole from source.

Once everything is installed, you will still need to configure guacd and Tomcat to start automatically on boot (assuming this is what you want):

# chkconfig tomcat6 on
Note: forwarding request to 'systemctl enable tomcat6.service'
ln -s '/usr/lib/systemd/system/tomcat6.service'
    '/etc/systemd/system/multi-user.target.wants/tomcat6.service'
# chkconfig guacd on
#

If you don't want Tomcat and guacd to start automatically, you can start them manually instead:

# service tomcat6 start
Redirecting to /bin/systemctl start tomcat6.service
# service guacd start
Starting guacd: SUCCESS
guacd[6229]: INFO:  Guacamole proxy daemon (guacd) version 0.7.0
guacd[6229]: INFO:  Unable to bind socket to host ::1, port 4822: Address family not supported by
protocol
guacd[6229]: INFO:  Successfully bound socket to host 127.0.0.1, port 4822
guacd[6229]: INFO:  Exiting and passing control to PID 6230
guacd[6230]: INFO:  Exiting and passing control to PID 6231
#

At this point, all you need to do is edit the /etc/guacamole/user-mapping.xml file to add some connections. You do not need to restart Tomcat after editing this file; it will be reloaded automatically by Guacamole.

Other distributions

If you distribution isn't listed above, there is still a chance your distribution provides Guacamole packages. A search for "guacamole" in your distribution's package manage should answer that question quickly. If no package is provided, your only option is to build Guacamole from source.

Building Guacamole from source is not hard. In most cases, all you need to do is download the latest source for guacamole-server, and the latest guacamole.war from the Guacamole project website, build guacamole-server, and then deploy guacamole.war.

The method for installing Guacamole is fairly constant across platforms, and the instructions given here should apply almost universally (and in the case that they don't, you probably already know what you need to do).

Building Guacamole from source

Building the components of Guacamole from source is not difficult, providing you have the necessary tools installed already. The source for the entirety of Guacamole is available from the Guacamole project web site in convenient source archives, each named after the component they contain. Each archive also contains a file named README which lists detailed instructions for building and installing.

Guacamole is separated into two pieces: guacamole-server, which provides the guacd proxy and related libraries, and guacamole-client, which provides the client to be served by your servlet container. In most cases, the only source you will need to build is guacamole-server, and downloading the latest guacamole.war from the project website will be sufficient to provide the client. Building guacamole-client is really only necessary when you wish to modify the source or when you want to try the latest unreleased changes.

To compile the C components, you will need a C compiler (such as gcc) and the libraries that each component depends on. Note that many Linux distribution separates library packages into binary and "development" packages; you will need to install the development packages. These will usually end in a "-dev" or "-devel" suffix.

guacamole-server

guacamole-server contains all the native, server-side components required by Guacamole to connect to remote desktops. It provides a common C library, libguac, which all other native components depend on, as well as separate libraries for each supported protocol, and a proxy daemon, guacd, the heart of Guacamole.

guacd is the proxy daemon that runs on your Guacamole server, accepting connections from the Guacamole web application on behalf of remote users. It effectively translates between common remote desktop protocols like VNC or RDP by dynamically loading protocol support plugins. Building guacd creates an executable called guacd which can be run manually or, if you wish, automatically when your computer starts up.

In order to build guacamole-server, you will need Cairo, a graphics library, and libpng, the official PNG library. These libraries are strictly required in all cases. Guacamole cannot be built without them. The other dependencies of guacamole-server are optional. Which libraries you will need to install depends on what support you need.

Guacamole currently supports VNC, RDP, and SSH. Each protocol corresponds to a separate library that will be built with guacamole-server if you have its corresponding optional dependencies. VNC support depends on the libvncclient library, which is part of libVNCServer, RDP support depends on a recent version of FreeRDP - 1.0 or higher, and SSH support depends on libssh and Pango, a font rendering and text layout library.

Optional features of these protocols will be enabled if you have other libraries installed.

Library nameRequired?Features
CairoYes.

Cairo is used by libguac for graphics rendering. Guacamole cannot function without Cairo installed.

libpngYes.

libpng is used by libguac to write PNG images, the core image type used by the Guacamole protocol. Guacamole cannot function without libpng.

FreeRDPOnly for RDP.

FreeRDP is required for RDP support. If you do not wish to build RDP support, this library is not needed.

PangoOnly for SSH.

Pango is a text layout library which Guacamole's SSH support uses to render text. If you do not wish to build SSH support, this library is not needed.

libssh2Only for SSH.

libssh2 is required for SSH support. If you do not wish to build SSH support, this library is not needed.

libVNCServerOnly for VNC.

libVNCServer provides libvncclient which is required for VNC support. If you do not wish to build VNC support, this library is not needed.

libpulseNo.

libpulse provides support for PulseAudio, which is used by Guacamole's VNC support to provide experimental audio. If you are not going to be using the experimental audio support for VNC, you do not need this library.

libsslFor SSH and for SSL connections to guacd.

libssl provides support for SSL and TLS - two common encryption schemes that make up the majority of encrypted web traffic.

If you have libssl installed, guacd will be built with SSL support, allowing communication between the web application and guacd to be encrypted. This library is also required for SSH support for the sake of manipulating public/private keys.

Without SSL support, there will be no option to encrypt communication to guacd, and support for SSH cannot be built.

libvorbisNo.

libvorbis provides support for Ogg Vorbis - a free and open standard for sound compression. If installed, libguac will be built with support for Ogg Vorbis, and protocols supporting audio will use Ogg Vorbis compression when possible.

Otherwise, sound will only be encoded as WAV (uncompressed), and will only be available if your browser also supports WAV.

You can obtain a copy of the guacamole-server source from the Guacamole project web site if you want the latest released code. These releases are stable snapshots of the latest code which have undergone enough testing that the Guacamole team considers them fit for public consumption. Source downloaded from the project web site will take the form of a .tar.gz archive which you can extract from the command line:

$ tar -xzf guacamole-server-0.9.0.tar.gz
$ cd guacamole-server-0.9.0/
$

If you want the absolute latest code, and don't care that the code hasn't been as rigorously tested as the code in stable releases, you can also clone the Guacamole team's git repository on GitHub:

$ git clone git://github.com/glyptodon/guacamole-server.git
Cloning into 'guacamole-server'...
remote: Counting objects: 6769, done.
remote: Compressing objects: 100% (2244/2244), done.
remote: Total 6769 (delta 3058), reused 6718 (delta 3008)
Receiving objects: 100% (6769/6769), 2.32 MiB | 777 KiB/s, done.
Resolving deltas: 100% (3058/3058), done.
$

Once the guacamole-server source has been downloaded and extracted, you need to run configure. This is a shell script automatically generated by GNU Autotools, a popular build system used by the Guacamole project for guacamole-server. Running configure will determine which libraries are available on your system and will select the appropriate components for building depending on what you actually have installed.

Important

Source downloaded directly from git will not contain this configure script, as autogenerated code is not included in the project's repositories. If you downloaded the code from the project's git repositories directly, you will need to generate configure manually:

$ cd guacamole-server/
$ autoreconf -fi
$

Doing this requires GNU Autotools to be installed.

Source archives downloaded from the project website contain the configure script and all other necessary build files, and thus do not require GNU Autotools to be installed on the build machine.

Once you run configure, you can see what a listing of what libraries were found and what it has determined should be built:

$ ./configure --with-init-dir=/etc/init.d
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
...

------------------------------------------------
guacamole-server version 0.9.0
------------------------------------------------

   Library status:

     freerdp ............. yes
     pango ............... yes
     libssh2 ............. yes
     libssl .............. yes
     libVNCServer ........ yes
     libvorbis ........... yes
     libpulse ............ yes

   Protocol support:

      RDP ....... yes
      SSH ....... yes
      VNC ....... yes

   Init scripts: /etc/init.d

Type "make" to compile guacamole-server.

$

The --with-init-dir=/etc/init.d shown above prepares the build to install a startup script for guacd into the /etc/init.d directory, such that we can later easily configure guacd to start automatically on boot. If you do not wish guacd to start automatically at boot, leave off the --with-init-dir option. If the directory containing your distribution's startup scripts differs from the common /etc/init.d, replace /etc/init.d with the proper directory here. You may need to consult your distribution's documentation, or do a little digging in /etc, to determine the proper location.

Here, configure has found everything, including all optional libraries, and will build all protocol support, even support for Ogg Vorbis sound in RDP. If you are missing some libraries, some of the "yes" answers above will read "no". If a library which is strictly required is missing, the script will fail outright, and you will need to install the missing dependency. If, after running configure, you find support for something you wanted is missing, simply install the corresponding dependencies and run configure again.

Important

SSH support requires that fonts are installed in order to function - output from the terminal cannot be rendered otherwise. Support for SSH will build just fine if fonts are not installed, but it will fail to connect when used:

Aug 23 14:09:45 my-server guacd[5606]: Unable to get font "monospace"

If SSH connections are not working and you see such a message in syslog, install fonts and try again.

Once configure is finished, just type "make", and it will guacamole-server will compile:

$ make
Making all in src/libguac
make[1]: Entering directory `/home/zhz/guacamole/guacamole-server/src/libguac'
...
make[1]: Leaving directory `/home/zhz/guacamole/guacamole-server/src/protocols/vnc'
make[1]: Entering directory `/home/zhz/guacamole/guacamole-server'
make[1]: Nothing to be done for `all-am'.
make[1]: Leaving directory `/home/zhz/guacamole/guacamole-server'
$

Quite a bit of output will scroll up the screen as all the components are compiled. Once everything finishes, all you have left to do is type "make install" to install the components that were built, and then "ldconfig" to update your system's cache of installed libraries:

# make install
Making install in src/libguac
make[1]: Entering directory `/home/zhz/guacamole/guacamole-server/src/libguac'
make[2]: Entering directory `/home/zhz/guacamole/guacamole-server/src/libguac'
...
----------------------------------------------------------------------
Libraries have been installed in:
   /usr/local/lib

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,-rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/home/zhz/guacamole/guacamole-server/src/protocols/vnc'
make[1]: Leaving directory `/home/zhz/guacamole/guacamole-server/src/protocols/vnc'
make[1]: Entering directory `/home/zhz/guacamole/guacamole-server'
make[2]: Entering directory `/home/zhz/guacamole/guacamole-server'
make[2]: Nothing to be done for `install-exec-am'.
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/home/zhz/guacamole/guacamole-server'
make[1]: Leaving directory `/home/zhz/guacamole/guacamole-server'
# ldconfig
#   

At this point, everything is installed, but guacd is not running. You will need to run guacd in order to use Guacamole once the client components are installed as well.

Beware that even after installing guacd and its startup script, you will likely still have to activate the service for it to start automatically. Doing this varies by distribution, but each distribution will have documentation describing how to do so.

guacamole-client

guacamole-client contains all Java and Maven components of Guacamole (guacamole, guacamole-common, guacamole-ext, and guacamole-common-js). These components ultimately make up the web application that will serve the HTML5 Guacamole client to users that connect to your server. This web application will connect to guacd, part of guacamole-server, on behalf of connected users in order to serve them any remote desktop they are authorized to access.

Normally, you don't need to build guacamole-client manually, as it is written in Java and is cross-platform. The easiest way to obtain the latest version of guacamole-client is to simply download the latest guacamole.war (the compiled form of guacamole-client) from the Guacamole project web site.

To compile guacamole-client, all you need is Apache Maven and a copy of the Java JDK. Most, if not all, Linux distributions will provide packages for these.

You can obtain a copy of the guacamole-client source from the Guacamole project web site if you want the latest released code. These releases are stable snapshots of the latest code which have undergone enough testing that the Guacamole team considers them fit for public consumption. Source downloaded from the project web site will take the form of a .tar.gz archive which you can extract from the command line:

$ tar -xzf guacamole-client-0.9.0.tar.gz
$ cd guacamole-client-0.9.0/
$

As with guacamole-server, if you want the absolute latest code, and don't care that the code hasn't been as rigorously tested as the code in stable releases, you can also clone the Guacamole team's git repository on GitHub:

$ git clone git://github.com/glyptodon/guacamole-client.git
Cloning into 'guacamole-client'...
remote: Counting objects: 12788, done.
remote: Compressing objects: 100% (4183/4183), done.
remote: Total 12788 (delta 3942), reused 12667 (delta 3822)
Receiving objects: 100% (12788/12788), 3.23 MiB | 799 KiB/s, done.
Resolving deltas: 100% (3942/3942), done.
$

Unlike guacamole-server, even if you grab the code from the git repositories, you won't need to run anything before building. There are no scripts that need to be generated before building - all Maven needs is the pom.xml file provided with the source.

To build guacamole-client, just run "mvn package". This will invoke Maven to automatically build and package all components, producing a single .war file, which contains the entire web application:

$ mvn package
[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   guacamole-common
[INFO]   guacamole-ext
[INFO]   guacamole-common-js
[INFO]   guacamole
[INFO]   guacamole-client
...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] guacamole-common ...................................... SUCCESS [4.467s]
[INFO] guacamole-ext ......................................... SUCCESS [1.479s]
[INFO] guacamole-common-js ................................... SUCCESS [3.680s]
[INFO] guacamole ............................................. SUCCESS [3.729s]
[INFO] guacamole-client ...................................... SUCCESS [0.008s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13 seconds
[INFO] Finished at: Mon Jul 08 00:44:42 PDT 2013
[INFO] Final Memory: 43M/354M
[INFO] ------------------------------------------------------------------------
$

Once the Guacamole web application is built, there will be a .war file in the guacamole/target/ subdirectory of the current directory (the directory you were in when you ran mvn). This .war file contains the entirety of the Guacamole web application, including all dependencies. Installing Guacamole means copying this .war file into the directory required by your servlet container.

You will probably have to do this as the root user:

# cp guacamole/target/guacamole-0.9.0.war /var/lib/tomcat6/webapps/guacamole.war
#

The Guacamole web application also depends on a configuration file, guacamole.properties, to tell it the type of authentication to use and how to connect to guacd. A functional example guacamole.properties is contained in the doc/ subdirectory; you can simply copy this somewhere (like /etc/guacamole) and then create a symbolic link to in a directory called .guacamole within the home directory of your servlet container. The home directory of your servlet container will be the home directory of the user that the servlet container runs as.

# mkdir /etc/guacamole
# mkdir /usr/share/tomcat6/.guacamole
# cp guacamole/doc/example/guacamole.properties /etc/guacamole/guacamole.properties
# ln -s /etc/guacamole/guacamole.properties /usr/share/tomcat6/.guacamole/
#           

You will need to edit guacamole.properties to be sure that all the settings are valid for your installation.

If you are using the default authentication method, you will also need to install the user-mapping.xml file. This file describes the users that should be allowed to log into Guacamole, as well as their passwords, and all corresponding remote desktop connections they should have access to.

An example user-mapping.xml file is provided in the doc/ subdirectory. You can simply copy this file to a reasonable location (like /etc/guacamole/user-mapping.xml) and then edit guacamole.properties to specify the correct location of this file.

You will need to edit user-mapping.xml to add and remove users, as well as to remove the "default" users included as examples.

Deploying Guacamole

Typically, deploying Guacamole is a one-time process, and needs to be done only when Guacamole is initially installed. If done correctly, future upgrades to Guacamole will be automatically deployed.

There are two critical files involved in the deployment of Guacamole: guacamole.war, which is the file containing the web application, and guacamole.properties, the main configuration file for Guacamole. The recommend way to set up Guacamole involves placing these files in standard locations, and then creating symbolic links to them so that Tomcat can find them.

Ultimately, the guacamole.war file, or a symbolic link to it, must be found by your servlet container within the directory it uses for .war files, and the guacamole.properties file must be within the .guacamole directory in the home directory of the user your servlet container runs as. Legacy installations will have guacamole.properties placed in the classpath of the servlet container, but this is officially deprecated, and will be unsupported in future releases.

We recommend placing guacamole.properties and any other configuration files in /etc/guacamole, and guacamole.war in /var/lib/guacamole. You will likely have to create each of these directories manually, as root.

With these files in place, you can create symbolic links in the places Tomcat and Guacamole require them, such that future upgrades will only involve placing the new files in standard locations. The standard locations involved are the Tomcat "webapps" directory (below, /var/lib/tomcat6/webapps, but your installation may be different), and the ".guacamole" directory, which must be manually created within the Tomcat user's home directory.

# ln -s /var/lib/guacamole/guacamole.war /var/lib/tomcat6/webapps
# ln -s /etc/guacamole/guacamole.properties /usr/share/tomcat6/.guacamole/
#

If you are using a different servlet container or Tomcat is installed in a different location, you will need to replace the directories above with the corresponding directories of your install.

Once Guacamole has been deployed, Tomcat must be restarted (as guacamole.properties will only be read on servlet container start) and the guacd daemon must be started if it isn't running already. After restarting Tomcat and starting guacd, Guacamole is successfully installed and running.

The command to restart Tomcat and guacd will vary by distribution. Typically, you can do this by running the corresponding init scripts with the "restart" option:

# /etc/init.d/tomcat6 restart
Stopping Tomcat... OK
Starting Tomcat... OK
# /etc/init.d/guacd start
Starting guacd: SUCCESS
guacd[6229]: INFO:  Guacamole proxy daemon (guacd) version 0.7.0
guacd[6229]: INFO:  Unable to bind socket to host ::1, port 4822: Address family not supported by
protocol
guacd[6229]: INFO:  Successfully bound socket to host 127.0.0.1, port 4822
guacd[6229]: INFO:  Exiting and passing control to PID 6230
guacd[6230]: INFO:  Exiting and passing control to PID 6231
#

If you want Guacamole to start on boot, you will need to configure the tomcat6 and guacd services to run automatically. Your distribution will provide documentation for doing this.

Using Apache as a frontend (mod_proxy)

Many users end up serving Guacamole through Apache using mod_proxy, a module which allows Apache to be used as a reverse proxy for other servers, such as a servlet container like Tomcat. The need to do this can range from simply wanting to use port 80, to sharing an SSL certificate with your web server, to security and load balancing.

By default, servlet containers like Tomcat listen on port 8080, which is not the standard HTTP port (port 80). If you are using Linux (or another UNIX system), only the root user can run programs which listen on ports less than 1024, including port 80, and reducing the number of programs that run with root privileges is always a good idea.

If you have an SSL certificate, it may make sense to use Apache for SSL processing and save Tomcat from having to do this itself, which may not be as efficient. Again, this also makes sense from the perspective of security, as it reduces the number of users that require read access to identifying certificates.

While load balancing won't be covered here, if you are expecting large numbers of users, balancing the load on Tomcat across multiple Tomcat instances is a common solution.

Important

Beware that, like the rest of this manual, we assume here that you are using Tomcat. If you are using a different servlet container, the same principles apply, and the Apache configuration examples will still be valid, with the notable exception of AJP, which may not be supported by your servlet container.

Using AJP

AJP is the Apache JServ Protocol - a protocol specifically designed for proxy communication between a web server like Apache and Tomcat. The AJP protocol is intended to be faster than HTTP when it comes to proxying web traffic, and it implements features that allow load balancing between multiple servlet containers.

Configuring Tomcat for AJP

To allow AJP connections to Tomcat, you must add a connector to Tomcat's conf/server.xml. There may already be an example connector in your server.xml, in which case all you need to do is uncomment it, editing the port number as desired:

<Connector port="8009" protocol="AJP/1.3"
    URIEncoding="UTF-8"
    redirectPort="8443" />

Tomcat must be restarted after the connector is added.

The URIEncoding="UTF-8" attribute above ensures that connection names, user names, etc. which contain non-latin characters are properly received. If you will be creating connections that have Cyrillic, Chinese, Japanese, etc. characters in the names or parameter values, you should be sure to set this attribute.

Forwarding HTTP requests over AJP

Once the connector is open, and Tomcat is listening on the port specified, you can edit your Apache configuration, adding a location which will proxy the Guacamole web application served via AJP by Tomcat:

<Location /guacamole/>
    Order allow,deny
    Allow from all
    ProxyPass ajp://HOSTNAME:8009/guacamole/ max=20 flushpackets=on
    ProxyPassReverse http://HOSTNAME/guacamole/
</Location>

The most important thing in this entire section is the option flushpackets=on. Most proxies, including mod_proxy, will buffer all data sent over the connection, waiting until the connection is closed before sending that data to the client. As Guacamole's tunnel will stream data to the client over an open connection, buffering this stream breaks Guacamole's communication.

If the option flushpackets=on is not specified, Guacamole will not work.

Note also the protocol of the URL specified in the ProxyPassReverse directive. The protocol MUST match the protocol that will be used to connect to to Apache. The example above specifies http, but if you are using HTTPS then the URL specified here will have to reflect this.

Using HTTP

If you don't wish to use AJP, the default HTTP connector (or any HTTP connector) can be used without any noticeable performance hit.

Configuring Tomcat for HTTP

Tomcat is most likely already configured to listen for HTTP connections on port 8080 as this is the default. In the case that the default HTTP connector has been disabled or removed, you need to add a connector entry to conf/server.xml:

<Connector port="8080" protocol="HTTP/1.1" 
           connectionTimeout="20000"
           URIEncoding="UTF-8"
           redirectPort="8443" />

Important

If you want to edit or add this connector just to change the port used by Tomcat to port 80, you should consider simply proxying the original port through Apache instead. On Linux and UNIX systems, a process must be running with root privileges to listen on any port under 1024, including port 80. Proxying Tomcat through Apache means Tomcat can run as a reduced-privilege user, while Apache can bear the burden of root privileges. Further, as Apache is a native application, it can make system calls to safely drop root privileges once the port is open; a Java application like Tomcat cannot do this.

As with AJP, be sure to specify the URIEncoding="UTF-8" attribute as above to ensure that connection names, user names, etc. are properly received. If you will be creating connections that have Cyrillic, Chinese, Japanese, etc. characters in the names or parameter values, this attribute is required.

Forwarding HTTP requests over HTTP

The configuration necessary to proxy HTTP requests is similar to the configuration required for proxying requests through AJP. In fact, it is completely identical except for the differing protocol names in the URIs given to the proxy directives:

<Location /guacamole/>
    Order allow,deny
    Allow from all
    ProxyPass http://HOSTNAME:8080/guacamole/ max=20 flushpackets=on
    ProxyPassReverse http://HOSTNAME:8080/guacamole/
</Location>

Again, take note of the option flushpackets=on. This option is absolutely critical as mod_proxy will otherwise buffer all data sent over the connection, rendering Guacamole unusable.

If the option flushpackets=on is not specified, Guacamole will not work.

Disable logging of tunnel requests

The Guacamole HTTP tunnel works by transferring a continuous stream of data over multiple short-lived streams, each associated with a separate HTTP request. Each HTTP request will be logged by Apache if you don not explicitly disable logging of those requests.

Apache provides a means of matching URL patterns and setting environment variables based on whether the URL matches. Logging can then be restricted to requests which lack this environment variable:

SetEnvIf Request_URI "^/guacamole/tunnel" dontlog
CustomLog  /var/log/apache2/guac.log common env=!dontlog

There is little value in a log file filled with identical tunnel requests.

Note that if you are serving Guacamole under a path different from /guacamole/, you will need to change the value of Request_URI above accordingly.

Proxying under a different path

If you wish to serve Guacamole through Apache under a different path than it is served under Tomcat, the configuration required for Apache will be slightly different than the examples above due to cookies.

When a user logs in to Guacamole, a new session is created, and that session is associated with a cookie sent to the user after they successfully log in. This cookie is specific to the absolute path of the web application (/guacamole). If the path being used for Guacamole under Apache differs from that used by Tomcat, the path in the cookie needs to be modified. Thankfully, mod_proxy has a directive for this: ProxyPassReverseCookiePath.

<Location /new-path/>
    Order allow,deny
    Allow from all
    ProxyPass ajp://HOSTNAME:8009/guacamole/ max=20 flushpackets=on
    ProxyPassReverse http://HOSTNAME/guacamole/
    ProxyPassReverseCookiePath /guacamole/ /new-path/
</Location>

The configuration shown above is similar to the configuration shown for generic AJP proxying, except that the additional ProxyPassReverseCookiePath directive is given, instructing mod_proxy to update the cookie path, changing /guacamole/ to /new-path/, the same path specified when the location was declared.

Be careful when specifying the URL in the ProxyPassReverse directive. The protocol of the URL MUST match the protocol that will be used to connect to to Apache, even if it differs from the protocol being used to connect to Tomcat.