Using Portainer and Docker to Deploy Guacamole Clientless Remote Desktop Gateway - NETSEC


Learning, Sharing, Creating

Cybersecurity Memo

Sunday, June 9, 2019

Using Portainer and Docker to Deploy Guacamole Clientless Remote Desktop Gateway

Apache Guacamole is a clientless remote desktop gateway. It has been called clientless gateway because no plugins or client software are required. The utility offers a HTML5 interface that is used to start remote sessions. There is no other special client software need to be installed as long as you have a browser. The following popular protocols are supported, VNC, RDP, SSH, Telnet.


Guacamole consists of the following components:
Guacamole architecture
  • Guacamole Server (Tomcat Servlet Container)
  • Guacamole Proxy Server (guacd), establishes remote connections
  • Remote hosts – accessible via protocols above
A Guacamole server can contact multiple proxy servers. Using this, it is possible to access desktops in multiple network segments using one frontend.

In this post, I am gong to present a way to set up Guacamole server in Azure free tier cloud VM. I am using docker technology with the help from Docker Web UI Portainer, to deploy a Guacamole docker into a Linux virtual machine. 

I have a YouTube video recorded for whole process which posted at the end of this post. You can check it out after read this post. Again, the whole infrastructure is based on Azure free tier Linux machine where I installed the whole docker packages.

Before installing docker packages, lets update the repository on your Ubuntu system and upgrade packages.
sudo apt update 
sudo apt upgrade

Deploy Docker

Now install docker using the apt command below.
sudo apt install -y

netsec@Ubuntu18-EU-Small:~$ sudo apt install -y
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  bridge-utils cgroupfs-mount containerd pigz runc ubuntu-fan
Suggested packages:
  ifupdown aufs-tools debootstrap docker-doc rinse zfs-fuse | zfsutils
The following NEW packages will be installed:
  bridge-utils cgroupfs-mount containerd pigz runc ubuntu-fan
0 upgraded, 7 newly installed, 0 to remove and 0 not upgraded.
Need to get 52.2 MB of archives.
After this operation, 257 MB of additional disk space will be used.
Get:1 bionic/universe amd64 pigz amd64 2.4-1 [57.4 kB]
Get:2 bionic/main amd64 bridge-utils amd64 1.5-15ubuntu1 [30.1 kB]
Get:3 bionic/universe amd64 cgroupfs-mount all 1.4 [6320 B]
Get:4 bionic-updates/universe amd64 runc amd64 1.0.0~rc7+git20190403.029124da-0ubuntu1~18.04.1 [1902 kB]
Get:5 bionic-updates/universe amd64 containerd amd64 1.2.6-0ubuntu1~18.04.1 [19.4 MB]
Get:6 bionic-updates/universe amd64 amd64 18.09.5-0ubuntu1~18.04.2 [30.7 MB]
Get:7 bionic/main amd64 ubuntu-fan all 0.12.10 [34.7 kB]
Fetched 52.2 MB in 3s (15.7 MB/s)
Preconfiguring packages ...
Selecting previously unselected package pigz.
(Reading database ... 80108 files and directories currently installed.)
Preparing to unpack .../0-pigz_2.4-1_amd64.deb ...
Unpacking pigz (2.4-1) ...
Selecting previously unselected package bridge-utils.
Preparing to unpack .../1-bridge-utils_1.5-15ubuntu1_amd64.deb ...
Unpacking bridge-utils (1.5-15ubuntu1) ...
Selecting previously unselected package cgroupfs-mount.
Preparing to unpack .../2-cgroupfs-mount_1.4_all.deb ...
Unpacking cgroupfs-mount (1.4) ...
Selecting previously unselected package runc.
Preparing to unpack .../3-runc_1.0.0~rc7+git20190403.029124da-0ubuntu1~18.04.1_amd64.deb ...
Unpacking runc (1.0.0~rc7+git20190403.029124da-0ubuntu1~18.04.1) ...
Selecting previously unselected package containerd.
Preparing to unpack .../4-containerd_1.2.6-0ubuntu1~18.04.1_amd64.deb ...
Unpacking containerd (1.2.6-0ubuntu1~18.04.1) ...
Selecting previously unselected package
Preparing to unpack .../5-docker.io_18.09.5-0ubuntu1~18.04.2_amd64.deb ...
Unpacking (18.09.5-0ubuntu1~18.04.2) ...
Selecting previously unselected package ubuntu-fan.
Preparing to unpack .../6-ubuntu-fan_0.12.10_all.deb ...
Unpacking ubuntu-fan (0.12.10) ...
Setting up runc (1.0.0~rc7+git20190403.029124da-0ubuntu1~18.04.1) ...
Processing triggers for ureadahead (0.100.0-21) ...
Setting up cgroupfs-mount (1.4) ...
Setting up containerd (1.2.6-0ubuntu1~18.04.1) ...
Created symlink /etc/systemd/system/ 鈫/lib/systemd/system/containerd.service.
Setting up bridge-utils (1.5-15ubuntu1) ...
Setting up ubuntu-fan (0.12.10) ...
Created symlink /etc/systemd/system/ 鈫/lib/systemd/system/ubuntu-fan.service.
Processing triggers for systemd (237-3ubuntu10.21) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Setting up pigz (2.4-1) ...
Setting up (18.09.5-0ubuntu1~18.04.2) ...
Adding group `docker' (GID 115) ...
Created symlink /etc/systemd/system/ 鈫/lib/systemd/system/docker.socket.
Processing triggers for ureadahead (0.100.0-21) ...
Processing triggers for systemd (237-3ubuntu10.21) ...

After the installation is complete, start docker service and enable it to launch everytime at system boot.
sudo systemctl start docker
sudo systemctl enable docker
Docker installed on ubuntu 18.04 server, check it using the command below.
docker version

netsec@Ubuntu18-EU-Small:~$ docker version
 Version:           18.09.5
 API version:       1.39
 Go version:        go1.10.4
 Git commit:        e8ff056
 Built:             Thu May  9 23:11:19 2019
 OS/Arch:           linux/amd64
 Experimental:      false
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.39/version: dial unix /var/run/docker.sock: connect: permission denied

Deploy Portainer

Before installing Portainer, download the Portainer image from the DockerHub using the docker pull command below.
sudo docker pull portainer/portainer
Create a dedication volume for portainer data.
docker volume create portainer_data

Now run Portainer using the simple docker command below.
sudo docker run -d -p 9000:9000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
Portainer is now running as a container, check it using the docker ps command.
sudo docker ps

netsec@Ubuntu18-EU-Small:~$ sudo docker pull portainer/portainer
Using default tag: latest
latest: Pulling from portainer/portainer
d1e017099d17: Pull complete 
fac26901c311: Pull complete 
Digest: sha256:cc226d8a06b6d5e24b44a4f10d0d1fd701741e84a852adc6d40bef9424a000ec
Status: Downloaded newer image for portainer/portainer:latest
netsec@Ubuntu18-EU-Small:~$ sudo docker volume create portainer_data
netsec@Ubuntu18-EU-Small:~$ sudo docker run -d -p 9000:9000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
netsec@Ubuntu18-EU-Small:~$ sudo docker ps
CONTAINER ID        IMAGE                 COMMAND             CREATED              STATUS              PORTS                    NAMES
836861e9d94f        portainer/portainer   "/portainer"        About a minute ago   Up About a minute>9000/tcp   portainer

Please make sure your cloud inbound port rules allowing tcp 9000 in.

Now you can access your portainer with your VM's public ip:9000. More details please refer to my previous post:

Deploy Guacamole Container through Portainer

Standard steps, using image oznu/guacamole which pull from Docker hub.

Since I am going to use port 80 for Guacamole, I mapped host port 80 to container's 8080. By default, Guacamole docker has set up port 8080 for web connection.

It will take 3-4 minutes to get deployment job done. Please be patient. The image is 1.2 GB.

Log in to Guacamole Web Gui

After container deployed, you can try to log in to web GUI through your browser. Default username and password is guacadmin. If it does not work, restart your Guacamole docker. I met this problem for somehow, but rebooting docker made it worked for me.

Create a new SSH connection

All configuration is basic. Choose right protocol, hostname which is ip address, port is tcp 22. 

Guacamole Web SSH Log In

Create a new RDP connection

Here is the YouTube Video - Using Portainer deploy Apache Guacamole;


  • Apache Guacamole™

No comments:

Post a Comment