Step-by-step Apache Guacamole Installation.

Recently, I decided to test Apache Guacamole and document the installation process.

Guacamole is an open-source software that enables remote access to desktops and servers via a web browser.

The easiest option I found was using Docker. Here’s the link to the official documentation.

The steps below were performed on a Debian system.

Install Docker

Docker documentation

Adding the Docker repository:

1
2
3
4
5
6
7
8
9
10
11
12
13
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

Installing Docker packages:

1
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Verify the installation by running:

1
 docker -v

Add the current user to the Docker group to avoid using sudo with commands:

1
sudo usermod -aG docker $USER

For this installation, I’m using the latest images, but for production use, it is recommended to use a specific version tag to avoid compatibility issues during upgrades or migrations.

Check out the available images on DockerHub Guacamole

1
2
3
docker pull guacamole/guacd
docker pull guacamole/guacamole
docker pull mariadb

Verify the downloaded images with the docker:

1
 docker images

Docker Images

Now, let’s initialize the database with the command:

1
docker run --rm guacamole/guacamole:latest /opt/guacamole/bin/initdb.sh --mysql > initdb.sql

InitDbSql

Create an .env file to store the access credentials:

1
nano .env
1
2
3
4
MYSQL_ROOT_PASSWORD=SuperSecretP@sswr0rd!@#$%^&*
MYSQL_DATABASE=guacamole_db
MYSQL_USER=guacamole_user
MYSQL_PASSWORD=SecretP@sswr0rd!@#$%^&*

Env

Create the docker-compose.yml file:

1
nano docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: "3"
services:
  guacdb:
    container_name: guacamoledb
    image: mariadb:latest
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    volumes:
      - "./db-data:/var/lib/mysql"
volumes:
  db-data:

docker_compose

Start the database with:

1
docker compose up -d

For systems with docker-compose installed instead of the plugin, use docker-compose up -d.

mariadb_up

Next, copy the initdb.sql file into the container:

1
docker cp initdb.sql guacamoledb:/initdb.sql

Within the container, install MySQL client and initialize the database:

1
docker exec -it guacamoledb bash
1
2
3
apt-get update && apt-get install -y default-mysql-client
cat /initdb.sql | mysql -u root -p guacamole_db
exit

dbinit

Shut down the database container:

1
docker compose down

db_down

As a best practice, back up the database initialization file:

1
mv docker-compose.yml docker-compose.yml.bak

docker-compose-backup

Create a new docker-compose.yml with all necessary configurations:

1
nano docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
version: "3"
services:
  guacdb:
    container_name: guacamoledb
    image: mariadb:latest
    restart: unless-stopped
    user: mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    volumes:
      - "./db-data:/var/lib/mysql"
  guacd:
    container_name: guacd
    image: guacamole/guacd:latest
    restart: unless-stopped
  guacamole:
    container_name: guacamole
    image: guacamole/guacamole:latest
    restart: unless-stopped
    ports:
      - 8080:8080
    environment:
      GUACD_HOSTNAME: "guacd"
      MYSQL_HOSTNAME: "guacdb"
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      TOTP_ENABLED: "true"
    depends_on:
      - guacdb
      - guacd
volumes:
  db-data:

Start the Guacamole service:

1
docker compose up -d

guacamoelup

Accessing Guacamole

Devemos acessar usando http://localhost:8080/guacamole

Tip

Guacamole is not directly accessible from the root. Add /guacamole to the address.

login_guacamole

Danger

The default credentials are guacadmin/guacadmin

Warning

In our docker-compose, we enabled TOTP. This requires an app like Authy, 2FAS, or Google Authenticator for login. To disable this, remove the line TOTP_ENABLED: "true".

totp

Allow inbound traffic on port 8080:

1
2
3
4
sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
sudo apt-get install iptables-persistent
sudo netfilter-persistent save
sudo iptables -L

Reference:




    Enjoy Reading This Article?

    Here are some more articles you might like to read next:

  • CyberDefenders Qradar101 Write up.
  • Script for enabling Windows Audit and Sysmon.
  • FnStegoCrypt - Encrypted Data in Images
  • Exposing Local Applications with FNLocalCloud.
  • Detection CVE-2024-35250
  • FIRST Fortaleza 2023.