24 Commits

Author SHA1 Message Date
Lindsay Harvey c469443851 contrib(vdi): PulseAudio and x264 image examples (#139)
Contributed by @vk2amv (Lindsay). Adds two example VDI container images under contrib/: one with PulseAudio audio, one with PulseAudio + x264/GFX. Contrib-only, no impact on shipping code.

Thanks Lindsay.
2026-05-27 20:48:28 +10:00
Lindsay Harvey d2a63e0e33 contrib(xrdp): LMDE 7 support, Cinnamon option, audio loader (#130)
Contributed by @vk2amv (Lindsay). Adds Linux Mint Debian Edition 7 detection to the GFX/H.264 setup script, picks the right Debian source codename when LMDE reports its own, replaces the broken upstream PulseAudio sources helper with an inline equivalent that handles both distros, adds Cinnamon as a desktop option, and adds Microsoft Edge installer plus audio diagnostics and a per-session audio loader script.

contrib-only change; no impact on running rustguac deployments.

Thanks Lindsay.
2026-05-18 19:39:14 +10:00
Dave Kempe d1adea5bea contrib: vault/openbao quickstart helper
Single shell script in contrib/ that takes a fresh box from "no Vault" to
"rustguac-ready Vault" without copy-pasting the integrations.md walkthrough.

Three modes:

  bootstrap (default)  Provision an existing Vault using $VAULT_ADDR and
                       $VAULT_TOKEN. Just creates the policy, AppRole, and
                       prints the rustguac config snippet.

  --dev                Spawn `<cli> server -dev` first (in-memory, root
                       token = "root"), then bootstrap it. For demos and
                       throwaway local development.

  --local              Install Vault or OpenBao as a systemd service on
                       this host with file-backed storage and on-disk
                       auto-unseal via an ExecStartPost helper. The unseal
                       key sits at <config_dir>/unseal-key (0400 root:root)
                       and a SECURITY.txt is written next to it spelling
                       out the convenience-over-security trade. Single-host
                       boxes only; for anything else use cloud-KMS unseal.

Auto-detects vault vs bao and picks the right filesystem layout, system
user, and service name for each (vault: /etc/vault.d, vault.service,
vault:vault; openbao: /etc/openbao, openbao.service, openbao:openbao).
Both flavors use the same HCL config grammar so the rest of the script is
shared.

Idempotent: re-running detects existing user, mount, policy, AppRole,
init bundle, and systemd unit. Drop-in is used if a unit already exists
(apt-installed vault) instead of clobbering it.

The script does NOT install the binary itself - it errors cleanly if
vault/bao isn't in PATH and tells the operator to install one.
2026-05-06 15:57:26 +10:00
Dave Kempe 542474dc3a v1.6.6 polish: OIDC error clarity, xrdp TLS perms, aurora default, reverse-proxy docs
### OIDC discovery error wrap

src/oidc.rs now reshapes the openidconnect crate's "unexpected issuer
URI `X` (expected `Y`)" validation error into something an operator
can act on without having to reason about which side is the config
and which is the provider. For the overwhelmingly common
trailing-slash case the message collapses to a single actionable
line; for the rarer case where the two URIs differ materially (wrong
tenant, copy-pasted authorise URL, Keycloak path change), it falls
back to a config/provider/fix three-liner. Raw Debug output is
preserved for any non-mismatch discovery failure. Works for any
OIDC provider, not just JumpCloud.

### xrdp TLS key permissions (contrib/setup-xrdp-gfx.sh)

After rebuilding xrdp from sid, the `adduser xrdp ssl-cert` step
from the Debian postinst doesn't always re-apply cleanly, leaving
the xrdp user unable to read /etc/xrdp/key.pem. xrdp then falls
back to "classic RDP security" and FreeRDP drops the connection
with a MAC checksum error. New Step 9 in Phase 3 explicitly adds
xrdp to ssl-cert and normalises the key's ownership/mode. Step
list in the help text renumbered to match.

### Aurora default when [theme] is absent

src/main.rs resolved the theme via ThemeConfig::resolve() only when
config.theme was Some(..), and otherwise fell through to a hardcoded
("dark", builtin_presets()[0].1.clone()) pair. That meant aurora
only kicked in when a [theme] section was present in config.toml,
even an empty one. ThemeConfig now derives Default (all fields
Option<String>, so zero-cost), and main.rs resolves via
config.theme.clone().unwrap_or_default().resolve() so absent and
empty [theme] behave identically. Regression test added.

### docs/reverse-proxies.md

New doc covering nginx, Caddy, Apache, and Traefik with per-proxy
configs and the %2F-decoding gotcha that causes 404s on nested
subfolder paths when a proxy normalises the URI before forwarding.
The issue was surfaced by @mauroparente in #105 — thanks for the
repro and the nginx config that made the root cause obvious.
deployment-guide.md Step 3 and integrations.md HAProxy section
both link to the new doc.
2026-04-25 15:40:08 +10:00
Dave Kempe bf19574a0d Update docs: VDI architecture in CLAUDE.md, test image README
- CLAUDE.md: VDI session type, Docker architecture, VdiDriver trait,
  container lifecycle, config options, test image reference
- contrib/vdi-test-image/README.md: build, usage, image requirements
- Fix: RDP was missing from session types description
2026-04-05 08:07:07 +10:00
Dave Kempe 501bd14a0d VDI Docker driver: ephemeral container desktops
Add 5th session type (Vdi) that spawns Docker containers with xrdp
and connects via RDP through guacd. Containers persist after disconnect
for configurable idle timeout, allowing reconnection to same desktop.

- VdiDriver trait (dyn-compatible) for downstream extensibility
- DockerDriver: bollard API, deterministic container naming per user,
  start/reuse/stop lifecycle, TCP+settle readiness polling
- Background reaper removes idle containers after timeout
- Address book: container_image, cpu/mem limits, env vars fields
- Config: [vdi] section with enabled, docker_socket, limits, timeouts
- Test image: contrib/vdi-test-image (Debian trixie + xrdp + xfce4)
2026-04-05 06:28:03 +10:00
Dave Kempe 74863326cb setup-xrdp-gfx.sh: install firefox-esr and chromium with desktop 2026-03-30 20:22:07 +11:00
Dave Kempe 3c6616fb78 setup-xrdp-gfx.sh: verify/create autostart for xrdp audio module 2026-03-30 19:10:47 +11:00
Dave Kempe 140be13389 setup-xrdp-gfx.sh: add --help with option docs and phase overview 2026-03-30 19:00:32 +11:00
Dave Kempe a8be5360f2 setup-xrdp-gfx.sh: split --diagnose into user/root sections 2026-03-30 18:59:44 +11:00
Dave Kempe fef0a270d2 setup-xrdp-gfx.sh: add --diagnose flag for troubleshooting 2026-03-30 18:58:27 +11:00
Dave Kempe a39b55f162 setup-xrdp-gfx.sh: switch PipeWire-pulse to real PulseAudio for xrdp audio 2026-03-30 16:39:06 +11:00
Dave Kempe 1c6793bc4e Merge audio build into setup-xrdp-gfx.sh (Phase 1, before sid)
Audio module must be built while system is pure trixie — sid's newer
libglvnd/libsystemd/libxcb break PulseAudio build dependencies.

Single script now does: desktop + build tools + audio → sid xrdp rebuild → remove sid → configure.
2026-03-30 16:03:05 +11:00
Dave Kempe c4ff48f512 Rewrite setup-xrdp-gfx.sh: desktop+build first, sid temporary, remove after
Phase 1: Install desktop + build-essential from pure trixie
Phase 2: Add sid temporarily, rebuild xrdp with x264, remove sid
Phase 3: Configure xrdp (Xorg, gfx.toml, startwm.sh)

Prevents sid packages from contaminating the dependency resolver.
2026-03-30 14:13:02 +11:00
Dave Kempe 01329d5e3d setup-xrdp-gfx.sh: add MATE desktop, make it default over XFCE 2026-03-30 14:01:29 +11:00
Dave Kempe 22e07d3b94 setup-xrdp-gfx.sh: apt -f install after dpkg to resolve missing deps 2026-03-30 11:46:17 +11:00
Dave Kempe 8f43566157 setup-xrdp-gfx.sh: install build-essential before sid to avoid gcc conflict 2026-03-30 11:31:10 +11:00
Dave Kempe 9accad307c setup-xrdp-gfx.sh: fix version selection (sort -V, -t unstable for source) 2026-03-29 14:22:18 +11:00
Dave Kempe 286bf5e753 setup-xrdp-gfx.sh: DEBIAN_FRONTEND=noninteractive for desktop install 2026-03-29 14:16:00 +11:00
Dave Kempe 7818bb3a9c setup-xrdp-gfx.sh: add --desktop flag (xfce/kde/gnome/none) 2026-03-29 14:14:58 +11:00
Dave Kempe bcea96baad Fix setup-xrdp-gfx.sh: add deb-src for sid (needed by apt-get source) 2026-03-29 14:04:41 +11:00
Dave Kempe 799cdefd57 v1.0.0: H.264 passthrough, per-entry toggle, Docker fix
H.264 passthrough for RDP via guac_display worker integration:
- Raw H.264 NAL units from xrdp x264 pass through to browser
  WebCodecs VideoDecoder, bypassing server-side decode/re-encode
- Frame queue preserves all H.264 frames across deferred flushes
- Per-entry toggle in address book (enable_h264 field)
- Keyframe gate ensures decoder initializes correctly
- Per-connection callback (no static global concurrency bug)
- Queue capped at 120 frames to prevent unbounded growth

guacd patch (004-h264-display-worker):
- display-priv.h: h264 frame queue on guac_display_layer
- display-plan.c: flush h264 queue during plan_apply, skip IMG ops
- display-layer.c: set_h264 API with queue append and cap
- rdpgfx.c: SurfaceCommand wrapper saves NAL before GDI handler
- settings.c/h: enable-h264 connection parameter, conditional GfxH264

Other changes:
- Docker: fix FreeRDP plugin path for drive/audio channels (#87)
- contrib/setup-xrdp-gfx.sh: full xrdp x264 rebuild from Debian sid
- docs/rdp-video-performance.md: H.264 passthrough documentation
- Address book UI: H.264 checkbox with dependency descriptions
2026-03-28 21:52:28 +11:00
Dave Kempe d2dbfe3b2e Add Windows RDP performance tuning script (contrib) 2026-03-24 20:52:51 +11:00
Dave Kempe 3bf1762d87 v0.9.0: RDP audio, GFX pipeline, video performance
Audio:
- RDP audio output now works through guacamole. Advertise audio/L16
  and audio/L8 mimetypes in the guacd handshake, and explicitly set
  disable-audio=false. Fixed mimetype mismatch that silently prevented
  guacd from creating audio streams.
- Browser AudioContext auto-resumed on user interaction (click/keydown)
  to comply with autoplay policy.

Video performance:
- Per-entry GFX pipeline toggle (enable_gfx) — enables RemoteFX codec
- Per-entry desktop composition toggle (enable_desktop_composition)
- Per-entry force lossless toggle (force_lossless) — PNG-only mode
- WebSocket proxy buffer increased from 8KB to 64KB
- Video Performance section in address book UI for RDP entries

Documentation:
- RDP Video Performance guide with Windows server tuning (AVC444,
  60fps, GPU encoding) and Linux xrdp setup (Debian 13)
- contrib/setup-xrdp-gfx.sh — automated GFX/H.264 setup for xrdp
- contrib/setup-xrdp-audio.sh — automated PulseAudio module build
2026-03-24 20:25:05 +11:00