mirror of
https://github.com/sol1/rustguac.git
synced 2026-09-10 09:35:45 +00:00
2187cfc1e4
- Vault TLS: replace hardcoded danger_accept_invalid_certs(true) with configurable tls_skip_verify option (default: false) - Share tokens: use constant-time SHA-256 hash comparison to prevent timing side-channel attacks - OIDC pending states: add 10-minute TTL, evict stale entries on each login to prevent unbounded HashMap growth - Recording path traversal: add canonical path validation as defense- in-depth alongside existing string checks - Frontend XSS: escape all user-controlled data (filenames, paths) in innerHTML via escapeHtml/escapeAttr in client.html and recordings.html Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
193 lines
8.6 KiB
TOML
193 lines
8.6 KiB
TOML
# rustguac — example configuration
|
||
#
|
||
# All settings are optional and have sensible defaults.
|
||
# Copy this file to config.toml and adjust as needed.
|
||
#
|
||
# Usage:
|
||
# rustguac --config config.toml serve
|
||
|
||
# ─── Server ───────────────────────────────────────────────────────────────────
|
||
|
||
# Address and port to listen on.
|
||
# Default: "127.0.0.1:8089" (loopback only — safe for development).
|
||
# For production behind a reverse proxy, use "127.0.0.1:8089".
|
||
# To listen on all interfaces: "0.0.0.0:443" (with TLS) or "0.0.0.0:8089".
|
||
listen_addr = "127.0.0.1:8089"
|
||
|
||
# Address of the guacd daemon (Guacamole protocol server).
|
||
# Default: "127.0.0.1:4822"
|
||
guacd_addr = "127.0.0.1:4822"
|
||
|
||
# Directory for session recording files (.guac format).
|
||
# Default: "./recordings"
|
||
recording_path = "./recordings"
|
||
|
||
# Directory containing static web files (HTML, JS, CSS).
|
||
# Default: "./static"
|
||
static_path = "./static"
|
||
|
||
# Path to the SQLite database (admins, OIDC users, auth sessions).
|
||
# Default: "./rustguac.db"
|
||
db_path = "./rustguac.db"
|
||
|
||
# Title shown in the browser tab and page header.
|
||
# Default: "rustguac"
|
||
site_title = "rustguac"
|
||
|
||
# ─── Session Timeouts ─────────────────────────────────────────────────────────
|
||
|
||
# Seconds before a pending session expires (no WebSocket connection yet).
|
||
# Default: 60
|
||
session_pending_timeout_secs = 60
|
||
|
||
# Maximum duration for active sessions in seconds.
|
||
# Sessions running longer than this are automatically terminated.
|
||
# Default: 28800 (8 hours). Set to 0 to disable.
|
||
session_max_duration_secs = 28800
|
||
|
||
# OIDC auth session TTL in seconds. After this period, users must
|
||
# re-authenticate via their identity provider.
|
||
# Default: 86400 (24 hours)
|
||
# auth_session_ttl_secs = 86400
|
||
|
||
# ─── Browser Sessions (Xvnc + Chromium) ──────────────────────────────────────
|
||
|
||
# Path to the Xvnc binary (from tigervnc-standalone-server).
|
||
# Default: "Xvnc"
|
||
xvnc_path = "Xvnc"
|
||
|
||
# Path to the Chromium binary.
|
||
# Default: "chromium"
|
||
chromium_path = "chromium"
|
||
|
||
# X display number range for Xvnc instances.
|
||
# Each web browser session gets its own display (:100 = port 6100, etc.).
|
||
# Default: 100–199 (up to 100 concurrent web sessions).
|
||
display_range_start = 100
|
||
display_range_end = 199
|
||
|
||
# ─── Connection Allowlists (CIDR) ────────────────────────────────────────────
|
||
#
|
||
# Control which hosts sessions can connect to. Each is a list of CIDR ranges.
|
||
# Hostnames are resolved and checked against the allowlist.
|
||
# Default for all three: ["127.0.0.0/8", "::1/128"] (localhost only).
|
||
|
||
# SSH session targets
|
||
ssh_allowed_networks = ["127.0.0.0/8", "::1/128", "10.0.0.0/8", "192.168.0.0/16"]
|
||
|
||
# RDP session targets
|
||
rdp_allowed_networks = ["127.0.0.0/8", "::1/128", "10.0.0.0/8", "192.168.0.0/16"]
|
||
|
||
# Web browser session URL hosts
|
||
# Use ["0.0.0.0/0", "::/0"] to allow any host.
|
||
web_allowed_networks = ["127.0.0.0/8", "::1/128"]
|
||
|
||
# ─── Trusted Proxies ────────────────────────────────────────────────────────
|
||
#
|
||
# CIDRs of reverse proxies whose X-Forwarded-For header should be trusted.
|
||
# When a connection comes from a trusted proxy, the first IP in
|
||
# X-Forwarded-For is used as the client IP in audit logs and rate limiting.
|
||
# Default: [] (empty — always use socket address)
|
||
|
||
# trusted_proxies = ["127.0.0.0/8", "::1/128"]
|
||
|
||
# ─── TLS ──────────────────────────────────────────────────────────────────────
|
||
#
|
||
# Enables HTTPS for clients and optionally TLS for the guacd connection.
|
||
# Omit the entire [tls] section to run plain HTTP (for development or
|
||
# when behind a TLS-terminating reverse proxy).
|
||
#
|
||
# Generate a self-signed cert:
|
||
# rustguac generate-cert --hostname your-hostname.example.com --out-dir ./tls
|
||
|
||
# [tls]
|
||
# # HTTPS certificate and private key
|
||
# cert_path = "/opt/rustguac/tls/cert.pem"
|
||
# key_path = "/opt/rustguac/tls/key.pem"
|
||
#
|
||
# # Trust this certificate for the guacd TLS connection (optional).
|
||
# # When set, rustguac connects to guacd over TLS.
|
||
# # The same self-signed cert can serve both purposes.
|
||
# # Omit for plain TCP to guacd.
|
||
# guacd_cert_path = "/opt/rustguac/tls/cert.pem"
|
||
|
||
# ─── OIDC (Single Sign-On) ───────────────────────────────────────────────────
|
||
#
|
||
# Enables OpenID Connect authentication. Works with any OIDC provider:
|
||
# Authentik, Keycloak, Okta, Azure AD, Google, etc.
|
||
#
|
||
# The client_secret can also be set via the OIDC_CLIENT_SECRET environment
|
||
# variable, which takes precedence over this config file. Recommended for
|
||
# production (Docker secrets, systemd EnvironmentFile, etc.).
|
||
#
|
||
# When OIDC is configured, the web UI shows a login button. API key auth
|
||
# continues to work alongside OIDC.
|
||
|
||
# [oidc]
|
||
# issuer_url = "https://authentik.example.com/application/o/rustguac/"
|
||
# client_id = "your-client-id"
|
||
# client_secret = "your-client-secret" # or set OIDC_CLIENT_SECRET env var
|
||
# redirect_uri = "https://your-host/auth/callback"
|
||
#
|
||
# # Role assigned to new users on first login.
|
||
# # Options: "admin", "poweruser", "operator", "viewer"
|
||
# # Default: "operator"
|
||
# default_role = "operator"
|
||
#
|
||
# # OIDC claim name containing group memberships (default: "groups").
|
||
# groups_claim = "groups"
|
||
#
|
||
# # Extra OIDC scopes to request beyond openid/email/profile.
|
||
# extra_scopes = ["groups"]
|
||
|
||
# ─── Vault / Address Book ──────────────────────────────────────────────────
|
||
#
|
||
# Enables the Vault-backed address book. Connection entries (SSH, RDP, Web)
|
||
# are stored in HashiVault or OpenBao KV v2. Credentials never reach the
|
||
# browser — the server reads them from Vault and creates sessions directly.
|
||
#
|
||
# Authentication uses AppRole. The secret_id is provided via the
|
||
# VAULT_SECRET_ID environment variable.
|
||
#
|
||
# Vault KV v2 path structure:
|
||
# <base_path>/shared/<folder>/<entry> — shared across instances
|
||
# <base_path>/instance/<name>/<folder>/<entry> — instance-specific
|
||
# <folder>/.config — folder metadata (allowed_groups, description)
|
||
|
||
# [vault]
|
||
# addr = "https://vault.example.com:8200"
|
||
# mount = "secret" # KV v2 mount (default: "secret")
|
||
# base_path = "rustguac" # base path under mount (default: "rustguac")
|
||
# role_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||
# # namespace = "my-ns" # optional, Vault Enterprise / OpenBao namespaces
|
||
# # instance_name = "prod-1" # optional, enables instance-scoped entries
|
||
# # tls_skip_verify = false # skip TLS cert verification (dev only, default: false)
|
||
|
||
# ─── Drive / File Transfer ──────────────────────────────────────────────────
|
||
#
|
||
# Enables file transfer for RDP (drive redirection) and SSH (SFTP) sessions.
|
||
#
|
||
# RDP: A per-session directory under drive_path is mounted as a virtual drive
|
||
# visible in the remote Windows session (e.g. "Shared Drive" in Explorer).
|
||
# SSH: SFTP file transfer directly between browser and target SSH server.
|
||
# No files stored on the rustguac server for SSH sessions.
|
||
#
|
||
# SECURITY: For RDP drive storage, use the LUKS options below to encrypt the
|
||
# drive_path volume. The encryption key is stored in Vault and the volume is
|
||
# only unlocked while rustguac is running.
|
||
|
||
# [drive]
|
||
# enabled = true
|
||
# drive_path = "/mnt/rustguac-drives" # mount point / base dir for per-session storage
|
||
# drive_name = "Shared Drive" # name shown in remote RDP session
|
||
# allow_download = true # allow downloading files from remote
|
||
# allow_upload = true # allow uploading files to remote
|
||
# cleanup_on_close = true # delete session drive dir on session end
|
||
# retention_secs = 0 # delay before cleanup (0 = immediate)
|
||
#
|
||
# # LUKS encryption (optional, requires Vault)
|
||
# # The install script can set this up interactively.
|
||
# luks_device = "/opt/rustguac/drives.luks" # LUKS container file
|
||
# luks_name = "rustguac-drives" # device-mapper name
|
||
# luks_key_path = "rustguac/luks-key" # Vault KV path for encryption key
|