Three pieces of v1.6.0 work that happened together and are easier to
review as one save point.
Rename: Address Book → Connections
- static/addressbook.html renamed to static/connections.html
- Nav links, page titles, empty states, onboarding, and prose updated
across all 8 static pages (connections, admin, docs, index,
recordings, reports, sessions, tokens).
- README, CLAUDE.md, and every file under docs/ updated.
- src/main.rs: connections.html added to the branded-page map and
route list; /addressbook.html returns a 308 permanent redirect so
existing bookmarks keep working.
- Backend API paths, Rust types, and Vault storage paths are
deliberately unchanged — internal only.
Folder allowed_groups picker
- New SQLite table `seen_groups` tracks OIDC groups observed in any
user login; OIDC callback upserts after extracting groups.
- `GET /api/auth/known-groups` (admin-only) returns the union of
group_role_mappings and seen_groups.
- `GET /api/addressbook/folders/{scope}/{folder}/config` adds the
missing endpoint the frontend was already calling — existing
allowed_groups now prefill the edit-folder modal.
- Folder modal swaps the free-text comma-separated input for a chip
picker with a themed combobox dropdown: autocomplete over known
groups, keyboard nav, "+ add custom" row for unlisted groups.
Active session visibility (GitHub #102)
- `GET /api/sessions` scopes to the caller's own sessions by default;
`?all=true` lets admins opt in (used by the Sessions page).
- `GET /api/sessions/{id}` and the thumbnail GET/PUT endpoints are
now owner-or-admin, returning 404 for other callers so session
existence isn't leaked.
- Connections' Active Sessions strip is now always owner-scoped —
admins still manage everyone via the Sessions page.
8.6 KiB
Installation
Option A: Debian package (recommended)
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
- 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.
-
Configure — edit
/opt/rustguac/config.tomlas needed (see Configuration). -
Start the services:
sudo systemctl enable --now rustguac
This starts both rustguac-guacd (the protocol daemon) and rustguac (the web proxy).
- (Recommended) Set up the connections with Vault / OpenBao:
The connections is rustguac's primary way to manage connections. It stores SSH, RDP, VNC, and web session entries in HashiCorp Vault or OpenBao KV v2. Credentials are stored server-side and never sent to the browser.
Without Vault, rustguac can still create ad-hoc sessions via the API, but the connections UI (the main user-facing feature) will not be available.
See Vault / OpenBao Connections for full setup instructions, including Vault policy, AppRole configuration, and the [vault] config section.
- (Optional) Set up encrypted drive storage:
sudo /opt/rustguac/bin/drive-setup.sh
See Drive / File Transfer for details.
- (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:
- Installs system packages (build tools, Xvnc, Chromium, cryptsetup, etc.)
- Installs the Rust toolchain (if not present)
- Clones and builds guacd from guacamole-server source, applying patches automatically
- Builds rustguac with
cargo build --release - Creates the
rustguacsystem user (home:/home/rustguac) - Generates a self-signed TLS certificate
- Installs binaries, static files, and config to
/opt/rustguac - 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:
- Copy the default config from the image:
docker run --rm --entrypoint cat sol1/rustguac:latest /opt/rustguac/config.toml.default > config.toml
- Edit
config.tomlas 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"]
- Mount it in your Docker Compose file or
docker runcommand (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:
- Autoconf
-Werrorvs deprecated FreeRDP headers — FreeRDP 3.15 deprecatescodecs_free(), breaking compile tests - Deprecated function pointer API — replaces
->input->MouseEvent()etc. with safe FreeRDP 3.x functions - NULL pointer dereference — FreeRDP 3.x fires PubSub events before
guac_rdp_dispis allocated - Struct layout mismatch — channel source files missing
config.hsee wrong field offsets when SSH support is enabled