A simple Container based Guacamole Setup

Another food blog post? No, of course not. Guacamole in this case does not refer to the avocado-based dip, but to the Apache client less remote desktop gateway. We use this as an alternative access to the OCI based Trivadis LAB environment. We use an automatically configured Guacamole environment with Nginx reverse proxy and Let’s encrypt SSL certificates. The detailed description of this Guacamole environment is the goal of this blog post.

For the Trivadis LAB and training environment in Oracle Cloud (OCI), we typically use a bastion host to access the various resources. In training courses, it is not always possible for all participants to use SSH clients such as Putty, MobaXterm, SSH command line and so on. This is especially true when training courses are increasingly conducted virtually, as is currently the case. Participants often use their company’s IT devices for this purpose. These devices are often protected accordingly and do not allow SSH access to public IP addresses. An HTTP-based remote access gateway such as Guacamole offers a simple alternative to allow participants to access the training environment.

Structure

Apache itself already provides Guacamole as a container. A simple setup contains two containers. The guacamole container for the remote desktop gateway and the guacd container for the server-side proxy. Guacamole uses a dedicated port and is not specially protected. For the training environment, however, access should be possible via HTTPS. The use of the default ports is also desirable. Guacamole uses Tomcat with a dedicated port and is not specially protected by default. For the training environment, however, access should be possible via HTTPS. The use of the default ports is also desirable. To meet the requirements while using existing Docker images, Guacamole is run behind an Nginx reverse proxy. The SSL certificates are generated using Let’s encrypt. The following graphic shows the schematic structure of the environment.

Guacamole Setup with Nginx Reverse Proxy

A few notes on the containers:

  • nginx configured as reverse proxy. By default this container does bind to HTTP and HTTPS to allow client access.
  • certbot simple container to create the Let’s Encrypt certificates.
  • guacamole the Apache Guacamole container
  • guacd the server-side proxy server for Guacamole
  • mysql database used to store the Guacamole connection information

Quickstart

Make sure you have docker and docker-compose installed on your environment. If not yet done you can get more information in chapter Install Docker Compose in the Docker documentation.

git clone https://github.com/oehrlis/guacamole.git
  • Review and update the .env and docker-compose.yml file. Make sure to define at least the following environment variable either with export , in the .env file or directly change the values in the compose file:
    • EMAIL – Adding a valid address for certificate renewal (default none)
    • HOSTNAME – Define a hostname for the nginx server and certificate name (default: $(hostname))
    • DOMAINNAME – Define a domain name for nginx server and certificate name (default: trivadislabs.com)
    • STAGING_ENABLE – Set STAGING to 1 if you’re testing your setup to avoid hitting request limits is certification
  • Pull the required Docker images
docker pull guacamole/guacamole
docker pull guacamole/guacd
docker pull mysql/mysql-server
docker pull nginx
docker pull certbot/certbot
  • Prepare the MySQL database
cd guacamole
./bin/prepare_initdb.sh
  • Start guacamole containers
docker-compose up -d guacamole mysql guacd
  • Perform the certificate challenge. Where Nginx is first started with a self signed certificate in order to then execute the actual certificate request. Define the variables If not yet updated in the .env file
export HOSTNAME="guacamole"
export DOMAINNAME="example.org"
export EMAIL="info@example.org"
export STAGING_ENABLE=1
./bin/prepare_certs.sh
  • Start all containers
docker-compose up -d

The different passwords for the Guacamole admin, Guacamole database and MySQL root are generated when not explicitly specified. You can find them in the logs respectively in the .env file which is updated by the prepare_initdb.sh script.

As soon as your container are up and running you can access your guacamole remote desktop gateway

Login Dialog Guacamole
Example Guacamole Home Page

Automatisation

There is even a quicker way to setup the Guacamole Docker stack by using the script setup_guacamole.sh. In particular, this method is used to set up the guacamole stack in an OCI bootstrap process. By default it will use the OS user avocado (what else 😉). But the user can be customised by the variable GUACAMOLE_USER.

git clone https://github.com/oehrlis/guacamole.git
cd guacamole
export HOSTNAME="guacamole"
export DOMAINNAME="example.org"
export EMAIL="info@example.org"
export STAGING_ENABLE=1
./bin/setup_guacamole.sh

Customised Configuration

As you could see above, the installation can be customised with a few variables. These include the following variables in particular.

VariableDefault ValueDescription
HOSTNAMEhostnameHostname of the bastion host used to create the certificate request. i.h. this name must be resolvable via DNS
DOMAINNAMEtrivadislabs.comDomain name user for the certificate request
EMAILadmin@DOMAINNAMEA valid e-Mail address used for the certificate challange
GUACAMOLE_USERavocadoGuacamole OS User
GUACAMOLE_BASE/home/${GUACAMOLE_USER}/guacamoleGuacamole base folder
GUACADMIN_USERguacadminGuacamole admin user
GUACADMIN_PASSWORDn/aGuacamole admin password. Will be generated and stored in .env
MYSQL_PASSWORDn/aMySQL database password. Will be generated and stored in .env
Environment Variables

Additionally, it is possible to create the guacamole connections directly when creating the configuration. For this purpose, the SQL script 02_connections.sql in the config/mysql directory has to be adapted. For example, with an SSH connection.

INSERT INTO guacamole_connection (connection_name, protocol) 
    VALUES ('Database Server (db - 10.0.1.6)', 'ssh');
INSERT INTO guacamole_connection_parameter VALUES (2, 'hostname', '10.0.1.6');
INSERT INTO guacamole_connection_parameter VALUES (2, 'port', '22');
INSERT INTO guacamole_connection_parameter VALUES (2, 'username', 'oracle');

Of course you can also enter passwords, SSH keys etc. directly. All SQL scripts in this directory are executed when the MySQL DB is created. So further customisations are possible. More information about the configuration of Guacamole can be found in the documentation.

OCI Bastion Host

How about using this on an OCI bastion host? Nothing simpler than that. You just have to configure you VCN and bastion host in the following manner.

  • Allow incoming traffic for port 80 and 443
  • Install docker on the bastion host
  • Register the public IP of your bastion host in a DNS zone create in OCI
  • Deploy the Guacamole stack manually as explained above.

In one of my next blog posts, I will show you how to automatically deploy your bastion host with guacamole stack by using my Terraform modules module tvdlab-bastion and tvdlab-base.

Conclusion

The container-based setup for Apache Guacamole is relatively simple and adds value to accessing the Trivadis cloud-based training and lab environment. The approach described here has also been successfully used for various test and PoC environments. To make setup in OCI even easier, Terraform module tvdlab-bastion and tvdlab-base use this approach to deploy the Guacamole stack on the Bastion host directly in the bootstrap process. But more about that in an other blog post.

References