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.
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.
- Clone the GitHub repository oehrlis/guacamole
git clone https://github.com/oehrlis/guacamole.git
- Review and update the
.env
anddocker-compose.yml
file. Make sure to define at least the following environment variable either withexport
, 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
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.
Variable | Default Value | Description |
---|---|---|
HOSTNAME | hostname | Hostname of the bastion host used to create the certificate request. i.h. this name must be resolvable via DNS |
DOMAINNAME | trivadislabs.com | Domain name user for the certificate request |
admin@DOMAINNAME | A valid e-Mail address used for the certificate challange | |
GUACAMOLE_USER | avocado | Guacamole OS User |
GUACAMOLE_BASE | /home/${GUACAMOLE_USER}/guacamole | Guacamole base folder |
GUACADMIN_USER | guacadmin | Guacamole admin user |
GUACADMIN_PASSWORD | n/a | Guacamole admin password. Will be generated and stored in .env |
MYSQL_PASSWORD | n/a | MySQL database password. Will be generated and stored in .env |
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
- GitHub repository with the Guacamole setup oehrlis/guacamole
- Terraform module for a bastion host with a Guacamole desktop gateway
- Terraform registry tvdlab-bastion
- GitHub repository Trivadis/terraform-oci-tvdlab-bastion
- Apache Guacamole and its documentation
- nginx documentation
- MySQL documentation
- PreBuild images on DockerHub
- MySQL documentation