OCI Labs

Tenancy Setup

  • VCN:VCN-ACADEMY 10.10.0.0/16
  • Subnets: 
    • academy-edge: 10.10.4.0/24 – public internet
    • academy-guacamole: 10.10.3.0/24 – guacamole tiers (guacd, mysql, guacamole) -private
    • academy-services: 10.10.2.0/24 fileshare mount targets – private
    • student-<class>: 10.10.101.0/24 Student pool of servers – private
  • Git Repository : git@github-hahlabs:hahlabs/guacamole.git
    1. Create docker network
      $docker network create guac-net
    2.  run guacd container
      $docker run --name guac-guacd \
            --network guac-net \
             -d guacamole/guacd
    3. run MySQL container
      $ mkdir initdb
      $ docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --mysql > ./initdb/initdb.sql
      $ docker run --name guac-mysql \
         --network guac-net \
         -e MYSQL_ROOT_PASSWORD=my-secret-pw \
         -e MYSQL_DATABASE=guacamoledb \
         -e MYSQL_USER=guacamole \
         -e MYSQL_PASSWORD=guacamolePASS \
         -v /home/opc/guacamole/initdb:/docker-entrypoint-initdb.d \
         -d mysql:oraclelinux8
    4. run guacamole container
      $ docker inspect \
      -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}'  container_name_or_id
      $ docker run --name guac-guacamole \
      --network guac-net \
      -e GUACD_HOSTNAME= GUAC-GUACD-IP \
      -e GUACD_PORT=4822 \
      -e MYSQL_HOSTNAME= GUAC-MYSQL_IP \
      -e MYSQL_PORT=3306 \
      -e MYSQL_DATABASE=guacamoledb \
      -e MYSQL_USER=guacamole \
      -e MYSQL_PASSWORD=guacamolePASS \
      -e MYSQL_SSL_MODE=disabled \
      -d -p 8080:8080 guacamole/guacamole
    5. Open port 8080
      $ sudo firewall-cmd --permanent --zone=public --add-port=8080/tcp
      $ sudo systemctl reload firewalld
    6. Access http://host:8080/guacamole  (guacadmin/guacadmin)

Guacamole Docker Compose

compose.yaml

# import .env file from volt {key=value}
# Generate ./initdb.sql : $ mkdir initdb && docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --mysql > ./initdb/initdb.sql

# networks
# create a network 'guacamole_net' in mode 'bridged'
networks:
  guac-net:
    driver: bridge
  haproxy_net:
    external: true

# services
services:
  # guacd
  guacd:
    container_name: guac-guacd
    image: guacamole/guacd
    networks:
    - guac-net
    restart: always

  # mysql
  mysql:
    container_name: guac-mysql
    environment:
      MYSQL_ROOT_PASSWORD: '${MYSQL_ROOT_PASSWORD}'
      MYSQL_DATABASE: '${MYSQL_DATABASE}'
      MYSQL_USER: '${MYSQL_USER}'
      MYSQL_PASSWORD: '${MYSQL_PASSWORD}'
    healthcheck:
      test: ["CMD", "mysqladmin", "-u${MYSQL_USER}", "-p${MYSQL_PASSWORD}", "ping"]
      interval: 5s
      timeout: 5s
      retries: 5
    image: mysql:oraclelinux8
    networks:
    - guac-net
    restart: always
    volumes:
    - ./initdb:/docker-entrypoint-initdb.d

  # guacamole
  guacamole:
    container_name: guac-guacamole
  depends_on:
    guacd:
      condition: service_started
    mysql:
      condition: service_healthy
    environment:
      GUACD_HOSTNAME: guacd
      MYSQL_HOSTNAME: mysql
      MYSQL_DATABASE: '${MYSQL_DATABASE}'
      MYSQL_USER: '${MYSQL_USER}'
      MYSQL_PASSWORD: '${MYSQL_PASSWORD}'
      MYSQL_SSL_MODE: disabled
    image: guacamole/guacamole
    ports:
    - "8080:8080"
    links:
    - guacd
    networks:
    - guac-net
    restart: always

Run docker compose

$ . mysql-params
$ docker compose up -d 

Open firewall ports

# firewall-cmd --permanent --zone=public --add-port=8080/tcp
# systemctl reload firewalld

Test connection

on local browser http://:8080/guacamole/# <– should see Guacamole Login screen

Default Login : guacadmin/guacadmin

  • Guacamole Connections: Settings::Connections

    Connections Edit

    • Hostname: the internal DNS or IP of the VNC Server use FQDNS name; use $(hostname).$(hostname -d) on target system
    • Port: 590n
    • Username: is the user started the vncserver
    • Password: the vncpassword for the user

    guacamole connection

     

  • Connection Parameters:

    connect vncviewer

  • Docker container
$ docker exec -it guac-guacamole bash
GUACAMOLE_HOME=/home/guacamole/.guacamole <-- default

guacamole.properties <- env parameter passed during docker run

Start services

$ docker compose up -d
Test from another terminal
$ docker-all-guacamole.sh <-- restart all docker services
$ docker-xxxx.sh <-- restart mysql, quacd, guacamole
$ docker-ip.sh $1 <-- get the host ip for guac- [mysql | quacd | guacamole] 

Guacamole now listens on port http://localhost:8080 <– not secure accessible from localhost

NOTE: Once the services all up and running, you must login to mysql database from the container just make 
$ docker exec -it guac-mysql bash
$ mysql -u guacamole -p <-- supply password then exit
$ curl http://localhost:8080/guacamole/#  <-- Should return html page 

Connect using VNC Viewer, open firefox browser http://localhost:8080/guacamole

Default admin user guacadmin/guacadmin

Servers

  • Student-00:

    subnet student-class. The student operation labs, access to the Shared folder to download materials
Setup (Desktop GUI, VNCServer , firewall)
  • GUAC-SERVER:

    subnet academy-guacamole Installs and operateds guac-guacd, guac-mysql, and guac-guacamole
Setup (Docker rootless, Guacamole 3x Containers, Firewall)
  • GUAC-PROXY:

    subnet academy-edge . Front end tier, accepting client request, works as reverse proxy/load balancer, SSL offloading
Setup (Docker rootless, HAProxy, firewall)

Self Signed Certificate

  • Install OpenSSH
$sudo dnf install openssh openssh-server
  • Generate private key and certificate signing request
# Generate a unique private key (KEY)
$openssl genrsa -out mydomain.key 2048

# Generating a Certificate Signing Request (CSR)
sudo openssl req -new -key alpha-guacamole.key -out alpha-guacamole.csr

# Creating a Self-Signed Certificate (CRT)
$openssl x509 -req -days 365 -in alpha-guacamole.csr -signkey alpha-guacamole.key -out alpha-guacamole.crt

# Append KEY and CRT to mydomain.pem
$bash -c 'cat alpha-guacamole.key alpha-guacamole.crt >> /etc/ssl/private/alpha-guacamole.pem'

# Specify PEM in haproxy config
sudo vim /etc/haproxy/haproxy.cfg
listen haproxy
  bind 0.0.0.0:443 ssl crt /etc/ssl/private/alpha-guacamole.pem

Configuring Guacamole Connections

  • on target system: disable or enable ports on firewalld
    # systemctl stop firewalld
  • login as guacadmin/guacadmin ex. https://XX.YY/ZZ.00-traefik.me/guacamole/# or VNC Viewer to Guacamole Server http://localhost/guacamole/#
  • Change password and create admin user / re login
  • Go to user profile (top – right corner) -> settings
  • On the Connections tab, create a new connection and organize it
  • (Optional) Choose Name as the Target system user name
  • HAProxy Github project
  • <IP>.traefik.me : resolves to IP, format 00-00-00-00 ex. 10-1-1-252.traefik.me
  • keep-alive (one connection multiple requests), pipelining mode (multiple requests before response), Multiplexed (Multiple parallel streams)
  • Configuration file (ordered, line series of tokens, designate sections (global, defaults, frontend, backend, listen)
  • Setup HAProxy Load Balancer

    $ git clone git@github-hahlabs:hahlabs/haproxy.git

    haproxy.cfg

    global
    global
      stats socket /var/run/api.sock user haproxy group haproxy mode 660 level admin                                                                                                                                                              expose-fd listeners
      log stdout format raw local0 info
      maxconn 50000
    
    resolvers docker_resolver
      nameserver dns 127.0.0.11:53
    
    defaults
      mode http
      timeout client 10s
      timeout connect 5s
      timeout server 10s
      timeout http-request 10s
      default-server init-addr none
      log global
    
    frontend stats
      bind *:8404
      stats enable
      stats uri /
      stats refresh 10s
    
    frontend guac-proxy
      mode http
      bind :80
      bind :443 ssl crt /usr/local/etc/haproxy/certs/guac-haproxy.pem
      use_backend guacamole-server
    backend guacamole-server
      server guacamole hah-guacamole.sub06072238460.vcnrac19c.oraclevcn.com:8080 che                                                                                                                                                             ck inter 10s resolvers docker_resolver <--$hostname.($hostname -d)
    

    composer.yaml

    networks:
      haproxy-net:
        name: haproxy-net
        driver: bridge
    services:
      guac-haproxy:
        container_name: guac-proxy
        image: haproxytech/haproxy-alpine
        ports:
        - 80:80
        - 443:443
        - 8084:8404
        volumes:
        - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
        - ./certs.traefik.me/guac-haproxy.pem:/usr/local/etc/haproxy/certs/guac-haproxy.pem
        networks:
        - haproxy-net
        restart: always
    

    Configure SSL & haproxy.cfg

    $ ./get-traefik-cert.sh  <-- will generate guac-haproxy.pem file and haproxy.cfg

    Open firewall ports & privileged ports

    # ./open-ports.sh <-- opens 80,443
    { On Oracle OCI Console, Enable ports from Security Lists of the public subnet}
    $ systemctl --user restart docker
    

    Start HAProxy

    $ docker compose up -d 

    Access HAProxy

    https://00-00-00-00.traefik.me/guacamole/#

Configuring Guacamole users

  • Change guacadmin user password, guacadmin->Settings->Preferences
  • Add new user guacadmin->Settings->Users::New User
    • Choose username student1
    • Choose one connection <– allows user to automatically connect to that connection

Now Guacamole student1 user is mapped to Target system user1 user, once student1 log in to Guacamole, it will connect automatically to user1 connection

Guacamole User Mapping
Guacamole Connections user mapping

Troubleshooting

Enable Ping (Echo) Protocol

in Security List, Add entry ingress TCP <IP> Protocol ICMP Type 8

Increase User concurrent sessions Limit

File : /etc/security/limits.conf
student0 hard maxlogins 1
@students hard maxlogins 1

If you like what you see, please share it.

About the author

Leave A Reply

For the love of learning, We welcome inquiries and design courses for you!

Courses run on demand, custom designed, Please send us a note and one of our team members will reach out to you.