Files
rustguac/docs/installation.md
T
Dave Kempe c7554fec1d docs: emphasise vault/openbao as a dependency, point at quickstart
The Connections UI is the main user-facing rustguac feature, and it does
not work without Vault or OpenBao. The previous docs framed this as
"recommended" or "optional Vault-backed connections", which understated
how much of rustguac depends on the secret store being there.

  - README.md gains a Requirements table listing guacd (bundled),
    vault/openbao (required for Connections), OIDC (optional), Docker
    (optional). The Features bullet now points at it.
  - docs/installation.md upgrades step 4 from "(Recommended)" to
    "(Required for connections)" with explicit "without one of these,
    the Connections UI is unavailable" wording. Includes the
    quickstart one-liner and a --local example.
  - docs/overview.md drops "optional" from the Vault-backed connections
    description and adds a follow-up paragraph pointing at the
    integrations doc and the quickstart script.
  - docs/integrations.md adds a Quickstart subsection above the manual
    walkthrough with a mode table, three example invocations, and the
    --local on-disk-unseal security caveat reiterated where it'll be
    seen by anyone reading the section.
2026-05-06 15:57:26 +10:00

9.0 KiB

Installation

Pre-built .deb packages are available from the releases page for Debian 13 (Trixie) and compatible distributions.

sudo apt install ./rustguac_*.deb

Using apt install (not dpkg -i) ensures all runtime dependencies are resolved automatically.

The package installs to /opt/rustguac and creates systemd services for both guacd and rustguac.

Post-install

  1. Create an admin API key:
/opt/rustguac/bin/rustguac --config /opt/rustguac/config.toml add-admin --name admin

Save the printed API key — it is only shown once.

  1. Configure — edit /opt/rustguac/config.toml as needed (see Configuration).

  2. Start the services:

sudo systemctl enable --now rustguac

This starts both rustguac-guacd (the protocol daemon) and rustguac (the web proxy).

  1. (Required for connections) Set up Vault or OpenBao:

The connections page is rustguac's primary user-facing feature. It stores SSH, RDP, VNC, web session, and VDI entries in HashiCorp Vault or OpenBao KV v2 — credentials never reach the browser. Without one of these, the Connections UI is unavailable and users can only run ad-hoc sessions via the Sessions page or the API.

For a single-host install the fastest path is the bundled quickstart helper, which auto-detects vault or bao and provisions everything:

# Against an existing Vault or OpenBao:
export VAULT_ADDR=https://vault.example.com:8200
export VAULT_TOKEN=hvs.xxxxxxxx
./contrib/vault-quickstart.sh

# Or install Vault locally on this box with on-disk auto-unseal:
sudo ./contrib/vault-quickstart.sh --local

See Vault / OpenBao Connections for the manual walkthrough, mTLS, multi-instance setup, and the security caveat for --local mode.

  1. (Optional) Set up encrypted drive storage:
sudo /opt/rustguac/bin/drive-setup.sh

See Drive / File Transfer for details.

  1. (Optional) Enable VDI desktop containers:

If you want to use VDI sessions (ephemeral Docker desktop containers), install Docker and grant rustguac access:

# Install Docker (if not already installed)
curl -fsSL https://get.docker.com | sh

# Allow rustguac to manage containers
sudo usermod -aG docker rustguac
sudo systemctl restart rustguac

Then add a [vdi] section to your config — see VDI Desktop Containers for full setup.

Option B: Bare-metal install script

For fresh Debian 13 systems, the install script builds everything from source:

sudo ./install.sh

This performs the following steps:

  1. Installs system packages (build tools, Xvnc, Chromium, cryptsetup, etc.)
  2. Installs the Rust toolchain (if not present)
  3. Clones and builds guacd from guacamole-server source, applying patches automatically
  4. Builds rustguac with cargo build --release
  5. Creates the rustguac system user (home: /home/rustguac)
  6. Generates a self-signed TLS certificate
  7. Installs binaries, static files, and config to /opt/rustguac
  8. Sets up systemd services

Install flags

Flag Description
--no-tls Skip TLS certificate generation, listen on HTTP port 8089
--hostname=FQDN Hostname for the TLS certificate (default: system hostname)
--deps-only Only install system packages, then exit
--no-deps Skip apt package installation

Installed layout

/opt/rustguac/
  bin/rustguac           # Main binary
  bin/drive-setup.sh     # LUKS drive setup script
  sbin/guacd             # Guacamole protocol daemon
  lib/                   # guacd shared libraries
  static/                # Web UI files
  tls/                   # TLS certificates
  data/                  # SQLite database
  recordings/            # Session recordings
  config.toml            # Configuration file
  env                    # Environment variables (VAULT_SECRET_ID, etc.)

Systemd services

Service Description
rustguac-guacd guacd protocol daemon (TLS, loopback only)
rustguac rustguac web proxy (depends on guacd)

Both services run as the rustguac user and restart on failure.

The rustguac service loads environment variables from /opt/rustguac/env via systemd's EnvironmentFile directive. Use this for secrets like VAULT_SECRET_ID and OIDC_CLIENT_SECRET.

Option C: Docker

Pre-built images are available on Docker Hub:

docker pull sol1/rustguac:latest
docker run -d -p 8089:8089 sol1/rustguac:latest

To build from source instead:

docker build -t rustguac .
docker run -d -p 8089:8089 rustguac

The Docker image:

  • Uses a multi-stage build (Debian 13 trixie-slim runtime)
  • Builds guacd from source with patches applied
  • Generates a self-signed TLS certificate at build time
  • Enables TLS between rustguac and guacd by default
  • Exposes HTTP on port 8089 (put a reverse proxy in front for HTTPS)

API key setup

On first run (when no database exists), the container automatically generates an admin API key and prints it to the logs:

docker logs rustguac

Save the printed key — it is only shown once. To generate additional keys later:

docker exec rustguac /opt/rustguac/bin/rustguac \
    --config /opt/rustguac/config.toml add-admin --name my-admin

Customizing the configuration

To persist config changes across container restarts, bind-mount a local config.toml into the container:

  1. Copy the default config from the image:
docker run --rm --entrypoint cat sol1/rustguac:latest /opt/rustguac/config.toml.default > config.toml
  1. Edit config.toml as needed (see Configuration):
# Example: allow SSH to private networks
ssh_allowed_networks = ["127.0.0.0/8", "::1/128", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]
  1. Mount it in your Docker Compose file or docker run command (see below).

If no config file is mounted, the container uses a built-in default on first start.

Docker Compose example

services:
  rustguac:
    image: sol1/rustguac:latest
    ports:
      - "8089:8089"
    volumes:
      - ./config.toml:/opt/rustguac/config.toml
      - rustguac-data:/opt/rustguac/data
      - rustguac-recordings:/opt/rustguac/recordings
    environment:
      - RUST_LOG=info

volumes:
  rustguac-data:
  rustguac-recordings:

Option D: RPM package (build from source)

Pre-built RPM packages are not currently provided. An RPM spec file (rustguac.spec) and build script (build-rpm.sh) are included for Red Hat / Fedora / Rocky Linux based systems. You will need FreeRDP 3.x development headers installed.

# Install build dependencies (example for Rocky/RHEL 9)
sudo dnf install -y epel-release
sudo dnf config-manager --set-enabled crb
sudo dnf install -y gcc gcc-c++ make git autoconf automake libtool \
    freerdp-devel cairo-devel libjpeg-turbo-devel libpng-devel libwebp-devel \
    libssh2-devel openssl-devel libvncserver-devel pango-devel \
    pulseaudio-libs-devel rpm-build

# Build the RPM
bash build-rpm.sh
sudo rpm -i rustguac-*.rpm

RPM builds are untested — contributions and feedback are welcome.

Option E: Development

# Clone guacamole-server alongside rustguac
git clone https://github.com/apache/guacamole-server.git ../guacamole-server

# Install build deps, build guacd, build + run rustguac
./dev.sh deps
./dev.sh build-guacd
./dev.sh start

For development with TLS:

./dev.sh generate-cert

cat > config.local.toml <<EOF
[tls]
cert_path = "cert.pem"
key_path = "key.pem"
guacd_cert_path = "cert.pem"
EOF

./dev.sh start

System dependencies

For bare-metal installs, rustguac requires:

  • Rust toolchain (1.75+)
  • guacd (built from guacamole-server source)
  • Xvnc (tigervnc-standalone-server) — for web browser sessions
  • Chromium — for web browser sessions
  • cryptsetup — for LUKS encrypted drive storage
  • Build libraries for guacd: libcairo2, libjpeg, libpng, libwebp, libssh2, libssl, libvncserver, libpango, libpulse, ffmpeg, freerdp3

See install.sh for the full package list.

guacamole-server patches

guacd requires patches to build and run correctly with FreeRDP 3.15+ as shipped in Debian 13. These patches are in the patches/ directory and are applied automatically by all build scripts.

The patches fix:

  1. Autoconf -Werror vs deprecated FreeRDP headers — FreeRDP 3.15 deprecates codecs_free(), breaking compile tests
  2. Deprecated function pointer API — replaces ->input->MouseEvent() etc. with safe FreeRDP 3.x functions
  3. NULL pointer dereference — FreeRDP 3.x fires PubSub events before guac_rdp_disp is allocated
  4. Struct layout mismatch — channel source files missing config.h see wrong field offsets when SSH support is enabled