95 lines
3.9 KiB
Markdown
95 lines
3.9 KiB
Markdown
# Guacamole 1.6 Integration
|
|
|
|
## Design
|
|
|
|
The SessionGuard Guacamole extension is deliberately **not** an authentication provider in the identity sense. PocketID/header authentication stays responsible for user identity.
|
|
|
|
The extension subclasses Guacamole's authentication-provider extension point only to decorate the authenticated `UserContext` with a `TokenInjectingUserContext`. At connection time it sends the current Guacamole username plus connection identity to the SessionGuard broker and injects returned tokens.
|
|
|
|
This avoids:
|
|
|
|
- writing dynamic hostnames directly into the Guacamole PostgreSQL database;
|
|
- reimplementing PocketID authentication in SessionGuard;
|
|
- opening a management connection from Master to RDS hosts.
|
|
|
|
## Build
|
|
|
|
```bash
|
|
cd guacamole-extension
|
|
mvn -DskipTests package
|
|
```
|
|
|
|
Or use `deploy/guacamole/Dockerfile.guacamole`, which builds the JAR and copies it to the stock Guacamole extension directory.
|
|
|
|
## Required Guacamole environment
|
|
|
|
```yaml
|
|
SESSIONGUARD_MASTER_URL: http://sessionguard-master:8080
|
|
SESSIONGUARD_BROKER_API_KEY: ${SESSIONGUARD_BROKER_API_KEY}
|
|
SESSIONGUARD_BROKER_TIMEOUT_MS: "2500"
|
|
```
|
|
|
|
Use the same broker API key configured on the SessionGuard Master. The URL should preferably be an internal network URL, not the public Internet endpoint.
|
|
|
|
## Desktop connection
|
|
|
|
Configure the Guacamole RDP hostname as:
|
|
|
|
```text
|
|
${SESSIONGUARD_HOST}
|
|
```
|
|
|
|
The extension resolves the target host at connection time.
|
|
|
|
## RemoteApp
|
|
|
|
Use:
|
|
|
|
```text
|
|
hostname: ${SESSIONGUARD_HOST}
|
|
remote-app: ${SESSIONGUARD_REMOTE_APP}
|
|
remote-app-dir: ${SESSIONGUARD_REMOTE_APP_DIR}
|
|
remote-app-args: ${SESSIONGUARD_REMOTE_APP_ARGS}
|
|
```
|
|
|
|
If your Agents report short Windows computer names and your DNS requires a suffix, a Guacamole hostname such as `${SESSIONGUARD_HOST}.example.org` is valid.
|
|
|
|
Create a matching Published Resource in SessionGuard by Guacamole connection ID or name. In v0.4 the Resource can optionally enable **Agent-managed RemoteApp publication** and specify the executable path. The Master then distributes the desired alias/path to every Agent in the farm. A managed RemoteApp is not brokered to a host until the Agent reports that it is present and in sync. The broker also aligns `${SESSIONGUARD_REMOTE_APP_ARGS}` with the Windows command-line policy (deny/allow/require).
|
|
|
|
## Header-auth security boundary
|
|
|
|
Your Guacamole configuration uses a trusted header such as `X-Guacamole-User`. That is safe only if untrusted requests cannot reach Guacamole directly with an attacker-controlled copy of that header.
|
|
|
|
Recommended topology:
|
|
|
|
```text
|
|
Internet
|
|
|
|
|
Traefik + forward-auth/header scrubber
|
|
|
|
|
dedicated trusted Guacamole proxy network
|
|
|
|
|
Guacamole
|
|
+--- private backend ---> guacd
|
|
+--- private backend ---> PostgreSQL
|
|
+--- private control ---> SessionGuard Master
|
|
```
|
|
|
|
Do not rely solely on the fact that the public Traefik router strips inbound identity headers if arbitrary unrelated containers can directly connect to Guacamole's port on a shared Docker network.
|
|
|
|
## Integration with the supplied compose
|
|
|
|
Your existing PocketID → traefik-forward-auth → Guacamole chain can remain unchanged. The required additions are:
|
|
|
|
1. build Guacamole using `deploy/guacamole/Dockerfile.guacamole`;
|
|
2. add the three `SESSIONGUARD_*` variables above;
|
|
3. give Guacamole private reachability to the SessionGuard Master;
|
|
4. add SessionGuard Published Resources matching your Guacamole connections;
|
|
5. replace fixed RDP hostnames in brokered connections with `${SESSIONGUARD_HOST}`.
|
|
|
|
`deploy/guacamole/docker-compose.sessionguard.example.yml` provides a focused example rather than replacing your complete existing stack.
|
|
|
|
## Failure behavior
|
|
|
|
If the SessionGuard broker is unavailable, the extension fails the brokered connection instead of choosing an arbitrary backend. This is intentional where reconnect affinity/profile concurrency matters. Existing already-established Guacamole/RDP sessions are unaffected.
|