Last active
June 12, 2025 04:48
-
-
Save vttc08/3b866ff4f71ede8d9bb409e58376402e to your computer and use it in GitHub Desktop.
Apache guacamole configuration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Credit https://github.com/boschkundendienst/guacamole-docker-compose | |
services: | |
# guacd | |
guacd: | |
container_name: guacd | |
image: guacamole/guacd | |
restart: unless-stopped | |
environment: | |
TZ: America/Vancouver | |
networks: | |
- guacamole_network | |
volumes: | |
- guacamole_recording:/record:rw | |
# postgres | |
postgres: | |
container_name: guacdb | |
env_file: | |
- ~/docker/guacamole/.env | |
environment: | |
PGDATA: /var/lib/postgresql/data/guacamole | |
POSTGRES_DB: guacamole_db | |
POSTGRES_USER: guacamole_user | |
TZ: America/Vancouver | |
# POSTGRES_PASSWORD from .env file | |
networks: | |
- guacamole_network | |
image: postgres:15.2-alpine | |
restart: unless-stopped | |
volumes: | |
- ~/docker/guacamole/init:/docker-entrypoint-initdb.d:z | |
- guacdb_postgres:/var/lib/postgresql/data:Z | |
# guacamole | |
guacamole: | |
container_name: guacamole | |
group_add: | |
- "1000" | |
depends_on: | |
- guacd | |
- postgres | |
env_file: | |
- ~/docker/guacamole/.env | |
- ~/docker/authentication/auth.env | |
networks: | |
- guacamole_network | |
- public | |
environment: | |
GUACD_HOSTNAME: guacd | |
POSTGRES_DATABASE: guacamole_db | |
POSTGRES_HOSTNAME: guacdb | |
# POSTGERES_PASSWORD from .env file | |
POSTGRES_USER: guacamole_user | |
RECORDING_SEARCH_PATH: /record | |
WEBAPP_CONTEXT: /remote | |
EXTENSION_PRIORITY: '*, openid' | |
OPENID_AUTHORIZATION_ENDPOINT: 'https://auth.${DOMAIN_NAME}/api/oidc/authorization?state=${GUACAMOLE_STATE}' | |
OPENID_JWKS_ENDPOINT: 'https://auth.${DOMAIN_NAME}/jwks.json' | |
OPENID_ISSUER: 'https://auth.${DOMAIN_NAME}' | |
OPENID_CLIENT_ID: 'guacamole' | |
OPENID_REDIRECT_URI: 'https://${DOMAIN_NAME}/remote' | |
OPENID_USERNAME_CLAIM_TYPE: preferred_username | |
OPENID_GROUPS_CLAIM_TYPE: groups | |
OPENID_SCOPE: openid profile groups email | |
TZ: America/Vancouver | |
image: guacamole/guacamole | |
volumes: | |
- guacamole_recording:/record:rw | |
ports: | |
- 8022:8080/tcp | |
restart: unless-stopped | |
volumes: | |
guacdb_postgres: | |
name: guacdb_postgres | |
driver: local | |
guacamole_recording: | |
name: guacamole_recording | |
driver: local | |
networks: | |
guacamole_network: | |
name: guacamole_network | |
driver: bridge | |
public: | |
name: public | |
external: true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Import the SQL files | |
python3 generate_sql.py | |
docker exec -i guacdb psql -U guacamole_user -d guacamole_db < guac_sharing_profiles_dynamic.sql | |
docker exec -i guacdb psql -U guacamole_user -d guacamole_db < guac_sync_dynamic.sql |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This file will generate SQL file based on SSH config which can be written to guacamole postgres | |
#!/usr/bin/env python3 | |
import os | |
from pathlib import Path | |
ssh_config_path = Path.home() / ".ssh" / "config" | |
if not ssh_config_path.exists(): | |
raise FileNotFoundError(f"SSH config not found at {ssh_config_path}") | |
with open(ssh_config_path) as f: | |
ssh_config = f.read() | |
entries = [] | |
entry = {} | |
home = str(Path.home()) | |
for line in ssh_config.strip().splitlines(): | |
line = line.strip() | |
if line.startswith("Host "): | |
if entry: | |
entries.append(entry) | |
entry = {} | |
entry["connection_name"] = line.split()[1] | |
elif line.startswith("HostName"): | |
entry["hostname"] = line.split()[1] | |
elif line.startswith("User"): | |
entry["username"] = line.split()[1] | |
elif line.startswith("IdentityFile"): | |
path = line.split()[1].replace("~", home) | |
entry["identityfile"] = path | |
if entry: | |
entries.append(entry) | |
default_params = { | |
"timezone": "America/Vancouver", | |
"enable-sftp": "true", | |
"create-typescript-path": "true", | |
"typescript-path": "${HISTORY_PATH}/${HISTORY_UUID}", | |
"create-recording-path": "true", | |
"recording-path": "${HISTORY_PATH}/${HISTORY_UUID}", | |
"terminal-type": "xterm-256color", | |
"command": "export GUAC=1 && bash", | |
"port": "22" | |
} | |
sql_statements = [] | |
for entry in entries: | |
name = entry.get("connection_name") | |
host = entry.get("hostname") | |
user = entry.get("username") | |
key_path = entry.get("identityfile") | |
if not all([name, host, user, key_path]): | |
continue | |
if not os.path.exists(key_path): | |
print(f"[!] Skipping {name} — key file missing: {key_path}") | |
continue | |
with open(key_path) as f: | |
private_key = f.read() | |
merged = default_params.copy() | |
merged["hostname"] = host | |
merged["username"] = user | |
merged["private-key"] = private_key | |
merged["sftp-root-directory"] = f"/home/{user}" | |
sql_statements.append(f"-- {name} ({host})") | |
sql_statements.append(f""" | |
DO $$ | |
DECLARE cid INT; | |
BEGIN | |
SELECT connection_id INTO cid FROM guacamole_connection WHERE connection_name = '{name}'; | |
IF cid IS NULL THEN | |
INSERT INTO guacamole_connection (connection_name, protocol) | |
VALUES ('{name}', 'ssh') RETURNING connection_id INTO cid; | |
ELSE | |
DELETE FROM guacamole_connection_parameter WHERE connection_id = cid; | |
END IF; | |
""") | |
for param, value in merged.items(): | |
escaped = value.replace("'", "''") | |
sql_statements.append( | |
f" INSERT INTO guacamole_connection_parameter (connection_id, parameter_name, parameter_value) " | |
f"VALUES (cid, '{param}', '{escaped}');" | |
) | |
sql_statements.append("END $$;\n") | |
# Save output | |
output_file = "guac_sync_dynamic.sql" | |
with open(output_file, "w") as f: | |
f.write("\n".join(sql_statements)) | |
print(f"✅ SQL written to {output_file}") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- this SQL script apply read only and default sharing policy on each connection | |
DO $$ | |
DECLARE | |
conn_id INT; | |
spid INT := 1000; | |
BEGIN | |
FOR conn_id IN SELECT DISTINCT connection_id FROM guacamole_connection LOOP | |
-- sharing | |
INSERT INTO guacamole_sharing_profile (sharing_profile_id, sharing_profile_name, primary_connection_id) | |
VALUES (spid, 'sharing', conn_id); | |
INSERT INTO guacamole_sharing_profile_parameter (sharing_profile_id, parameter_name, parameter_value) | |
VALUES (spid, 'read-only', 'false'); | |
spid := spid + 1; | |
-- readonly sharing | |
INSERT INTO guacamole_sharing_profile (sharing_profile_id, sharing_profile_name, primary_connection_id) | |
VALUES (spid, 'readonly sharing', conn_id); | |
INSERT INTO guacamole_sharing_profile_parameter (sharing_profile_id, parameter_name, parameter_value) | |
VALUES (spid, 'read-only', 'true'); | |
spid := spid + 1; | |
END LOOP; | |
END | |
$$ LANGUAGE plpgsql; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# check if docker is running | |
if ! (docker ps >/dev/null 2>&1) | |
then | |
echo "docker daemon not running, will exit here!" | |
exit | |
fi | |
echo "Preparing folder init and creating ./init/initdb.sql" | |
mkdir ./init >/dev/null 2>&1 | |
chmod -R +x ./init | |
docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgresql > ./init/initdb.sql | |
echo "done" | |
echo "Preparing folder record and set permissions" | |
mkdir ./record >/dev/null 2>&1 | |
chmod -R 777 ./record | |
docker run --rm -v guacamole_recording:/path busybox sh -c 'touch /path && chmod a+w /path' | |
echo "done" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment