Add steam headless apps with security docs and verification guide
This commit is contained in:
@@ -0,0 +1,78 @@
|
|||||||
|
# Steam Headless
|
||||||
|
|
||||||
|
Steam Headless kör en webbaserad Linux-desktop med Steam i container, baserat på LinuxServer image `lscr.io/linuxserver/steam`.
|
||||||
|
|
||||||
|
Imagepinning i denna app:
|
||||||
|
|
||||||
|
- Compose använder immutable referens: `lscr.io/linuxserver/steam:version-f4f48542@sha256:d7b9fbf302e05ae79248d1171fe9751b354f8397eafa1e13a3df0aa6a75de0b4`
|
||||||
|
- `latest` finns i registryt men används inte i repo enligt policy.
|
||||||
|
- Vid verifieringstillfället pekade `latest` på samma release (`version-f4f48542`).
|
||||||
|
|
||||||
|
## Syfte
|
||||||
|
|
||||||
|
- Ge enkel Steam-access via webbläsare i ZimaOS.
|
||||||
|
- Hålla v1 med minsta möjliga privilegier.
|
||||||
|
- Förbereda en separat senare fas för Moonlight-fokuserad streaming.
|
||||||
|
|
||||||
|
## Portar
|
||||||
|
|
||||||
|
- `3000/tcp` (HTTP desktop): `${STEAM_HTTP_PORT:-3000}`
|
||||||
|
- `3001/tcp` (HTTPS desktop): `${STEAM_HTTPS_PORT:-3001}`
|
||||||
|
|
||||||
|
## Volymer
|
||||||
|
|
||||||
|
- `/DATA/AppData/$AppID/config -> /config`
|
||||||
|
|
||||||
|
All Steam-data (profil, cache, installerade spel) lagras under appens egna AppData-sökväg.
|
||||||
|
|
||||||
|
## Privilegier och säkerhet
|
||||||
|
|
||||||
|
Aktiva säkerhetsinställningar i denna app:
|
||||||
|
|
||||||
|
- `security_opt: ["seccomp:unconfined", "no-new-privileges:true"]`
|
||||||
|
- `cap_drop: ["ALL"]`
|
||||||
|
- Ingen `privileged: true`
|
||||||
|
- Ingen `network_mode: host`
|
||||||
|
- Ingen mount av `/var/run/docker.sock`
|
||||||
|
|
||||||
|
Motivering:
|
||||||
|
|
||||||
|
- LinuxServer Steam använder sandbox/bubblewrap-mönster som normalt kräver `seccomp:unconfined` för att spel/launcher ska fungera stabilt.
|
||||||
|
- `no-new-privileges:true` och `cap_drop: ["ALL"]` används för att kompensera med lägsta möjliga capability-yta i övrigt.
|
||||||
|
|
||||||
|
Kända tradeoffs:
|
||||||
|
|
||||||
|
- På vissa Debian/Ubuntu-hostar kan även `apparmor:unconfined` behövas. Detta är inte default här av least-privilege-skäl.
|
||||||
|
- Browser-vägen (KasmVNC) är enkel men ger inte samma latens/gamepad-egenskaper som Moonlight.
|
||||||
|
|
||||||
|
## Säkerhetsavvikelser
|
||||||
|
|
||||||
|
Denna app använder en avvikelse från strikt seccomp-default:
|
||||||
|
|
||||||
|
- `seccomp:unconfined`
|
||||||
|
|
||||||
|
Varför det behövs:
|
||||||
|
|
||||||
|
- För kompatibilitet med LinuxServer Steam runtime och dess sandboxade processer.
|
||||||
|
|
||||||
|
Alternativ som utvärderats:
|
||||||
|
|
||||||
|
- Standard seccomp-profil: blockar delar av förväntad processmodell för Steam/spel.
|
||||||
|
- Full `privileged: true`: avvisat på grund av större attackyta.
|
||||||
|
|
||||||
|
Risker:
|
||||||
|
|
||||||
|
- Minskad syscall-filtrering jämfört med default seccomp-profil.
|
||||||
|
- Om container komprometteras finns större möjlighet att anropa kernel-funktioner än med strikt seccomp.
|
||||||
|
|
||||||
|
Riskreducering:
|
||||||
|
|
||||||
|
- Inga host-network eller docker-socket mounts.
|
||||||
|
- Capability-surface minimerad med `cap_drop: ["ALL"]`.
|
||||||
|
- Isolerad data-path under `/DATA/AppData/$AppID/...`.
|
||||||
|
|
||||||
|
## Driftnoteringar
|
||||||
|
|
||||||
|
- För GPU-acceleration kan extra device-mounts krävas beroende på host och drivrutiner.
|
||||||
|
- Om HTTPS används på `3001` kan webbläsaren visa certifikatvarning vid första anslutning.
|
||||||
|
- Rekommenderad nästa fas: separat Moonlight/Sunshine-spår som opt-in, med egen riskprofil.
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
name: steam-headless
|
||||||
|
|
||||||
|
services:
|
||||||
|
steam:
|
||||||
|
image: lscr.io/linuxserver/steam:version-f4f48542@sha256:d7b9fbf302e05ae79248d1171fe9751b354f8397eafa1e13a3df0aa6a75de0b4
|
||||||
|
container_name: steam-headless
|
||||||
|
restart: unless-stopped
|
||||||
|
shm_size: "1gb"
|
||||||
|
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
|
PUID: ${PUID}
|
||||||
|
PGID: ${PGID}
|
||||||
|
STEAM_HTTP_PORT: ${STEAM_HTTP_PORT:-3000}
|
||||||
|
STEAM_HTTPS_PORT: ${STEAM_HTTPS_PORT:-3001}
|
||||||
|
|
||||||
|
ports:
|
||||||
|
- target: 3000
|
||||||
|
published: ${STEAM_HTTP_PORT:-3000}
|
||||||
|
protocol: tcp
|
||||||
|
- target: 3001
|
||||||
|
published: ${STEAM_HTTPS_PORT:-3001}
|
||||||
|
protocol: tcp
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- type: bind
|
||||||
|
source: /DATA/AppData/$AppID/config
|
||||||
|
target: /config
|
||||||
|
|
||||||
|
# Required by LinuxServer Steam for bubblewrap/game namespaces.
|
||||||
|
security_opt:
|
||||||
|
- seccomp:unconfined
|
||||||
|
- no-new-privileges:true
|
||||||
|
|
||||||
|
# Keep capability surface minimal unless a specific game requires otherwise.
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
|
||||||
|
x-casaos:
|
||||||
|
envs:
|
||||||
|
- container: TZ
|
||||||
|
description:
|
||||||
|
en_us: Timezone, for example Europe/Stockholm
|
||||||
|
- container: PUID
|
||||||
|
description:
|
||||||
|
en_us: User ID for filesystem permissions
|
||||||
|
- container: PGID
|
||||||
|
description:
|
||||||
|
en_us: Group ID for filesystem permissions
|
||||||
|
ports:
|
||||||
|
- container: "3000"
|
||||||
|
description:
|
||||||
|
en_us: Steam desktop GUI over HTTP
|
||||||
|
- container: "3001"
|
||||||
|
description:
|
||||||
|
en_us: Steam desktop GUI over HTTPS
|
||||||
|
volumes:
|
||||||
|
- container: /config
|
||||||
|
description:
|
||||||
|
en_us: Steam home, configuration, and game files
|
||||||
|
|
||||||
|
x-casaos:
|
||||||
|
architectures:
|
||||||
|
- amd64
|
||||||
|
main: steam
|
||||||
|
category: Games
|
||||||
|
author: Zima Apps Team
|
||||||
|
developer: linuxserver.io
|
||||||
|
icon: https://cdn.simpleicons.org/steam
|
||||||
|
tagline:
|
||||||
|
en_us: Browser-based Steam desktop container for ZimaOS
|
||||||
|
description:
|
||||||
|
en_us: >-
|
||||||
|
Runs LinuxServer Steam as a web-accessible desktop session.
|
||||||
|
Optimized for amd64 and least-privilege defaults, with optional future
|
||||||
|
Moonlight-focused expansion in a later phase.
|
||||||
|
title:
|
||||||
|
en_us: Steam Headless
|
||||||
|
index: /
|
||||||
|
port_map: ${STEAM_HTTPS_PORT:-3001}
|
||||||
|
scheme: https
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
# Moonlight Runtime Checklist
|
||||||
|
|
||||||
|
Strikt checklista för att aktivera `steam-moonlight`-profilen säkert.
|
||||||
|
|
||||||
|
## Preflight (måste vara grönt)
|
||||||
|
|
||||||
|
1. Bekräfta att du medvetet accepterar högriskprofil (`network_mode: host`, extra capabilities, device passthrough).
|
||||||
|
2. Sätt starkt lösenord i `SUNSHINE_PASS` (inte `change-me`, inte återanvänt).
|
||||||
|
3. Verifiera GPU-device mapping:
|
||||||
|
- `GPU_CARD_DEVICE` pekar på korrekt `/dev/dri/card*`
|
||||||
|
- `GPU_RENDER_DEVICE` pekar på korrekt `/dev/dri/renderD*`
|
||||||
|
4. Verifiera att hosten har:
|
||||||
|
- `/dev/fuse`
|
||||||
|
- `/dev/uinput`
|
||||||
|
- korrekt `/dev/dri/*`
|
||||||
|
5. Bekräfta att Sunshine-portar inte exponeras publikt mot internet.
|
||||||
|
6. Verifiera att volymerna är under `/DATA/AppData/$AppID/...`.
|
||||||
|
7. Verifiera compose-rendering:
|
||||||
|
- `docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight config`
|
||||||
|
|
||||||
|
## Startsekvens
|
||||||
|
|
||||||
|
1. Starta endast Moonlight-profilen:
|
||||||
|
- `docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight up -d steam-moonlight`
|
||||||
|
2. Kontrollera containerstatus:
|
||||||
|
- `docker compose -f Apps/steam-moonlight/docker-compose.yaml ps`
|
||||||
|
3. Kontrollera initiala logs:
|
||||||
|
- `docker logs --tail=200 steam-moonlight-profile`
|
||||||
|
|
||||||
|
## Post-start verifiering
|
||||||
|
|
||||||
|
1. Verifiera att Sunshine kräver autentisering.
|
||||||
|
2. Verifiera att streaming fungerar från avsedd klient (LAN/VPN).
|
||||||
|
3. Verifiera controller-input utan att aktivera fler capabilities än definierat.
|
||||||
|
4. Verifiera att inga oväntade portar exponeras.
|
||||||
|
5. Verifiera att defaultprofil fortfarande kan köras separat vid rollback.
|
||||||
|
|
||||||
|
## Driftregler
|
||||||
|
|
||||||
|
1. Kör inte Moonlight-profilen permanent om den inte används.
|
||||||
|
2. Roterar `SUNSHINE_PASS` regelbundet och alltid efter incident.
|
||||||
|
3. Uppdatera image-pin via digest i kontrollerade change windows.
|
||||||
|
4. Undvik ad-hoc ändringar av capabilities eller device mounts.
|
||||||
|
|
||||||
|
## Snabb rollback
|
||||||
|
|
||||||
|
1. Stoppa Moonlight-profil:
|
||||||
|
- `docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight stop steam-moonlight`
|
||||||
|
2. Kör defaultprofil:
|
||||||
|
- `docker compose -f Apps/steam-moonlight/docker-compose.yaml up -d steam`
|
||||||
|
3. Bekräfta återställd låg-risk drift via logs och funktionstest.
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
# Steam Moonlight (Scaffold)
|
||||||
|
|
||||||
|
Detta är en scaffold för hybridspåret (browser + Moonlight) baserat på `josh5/steam-headless`.
|
||||||
|
|
||||||
|
Kompletterande säkerhetsdokument:
|
||||||
|
|
||||||
|
- `SECURITY.md`
|
||||||
|
- `MOONLIGHT-RUNTIME-CHECKLIST.md`
|
||||||
|
|
||||||
|
## Syfte
|
||||||
|
|
||||||
|
- Ge en låg-risk default för browserbaserad Steam-desktop.
|
||||||
|
- Ge en separat opt-in-profil för Moonlight/Sunshine.
|
||||||
|
- Isolera högriskinställningar till en explicit profil (`moonlight`).
|
||||||
|
|
||||||
|
## Imagepinning
|
||||||
|
|
||||||
|
- Compose använder immutable referens:
|
||||||
|
- `josh5/steam-headless:debian-0.2.0@sha256:540366bee31297c5679a5006a84dbca039ca62aaab695852b51b5f62dffd2c14`
|
||||||
|
- Repon kräver att `latest` inte används i compose.
|
||||||
|
|
||||||
|
## Profiler
|
||||||
|
|
||||||
|
- `steam` (default): browser-first, lägre risk, ingen host network.
|
||||||
|
- `steam-moonlight` (`profiles: ["moonlight"]`): aktiverar Sunshine + controller/GPU passthrough med högre privilegier.
|
||||||
|
|
||||||
|
## Körning
|
||||||
|
|
||||||
|
- Default (rekommenderad start):
|
||||||
|
- `docker compose -f Apps/steam-moonlight/docker-compose.yaml up -d steam`
|
||||||
|
- Moonlight (opt-in):
|
||||||
|
- `docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight up -d steam-moonlight`
|
||||||
|
- Innan Moonlight aktiveras:
|
||||||
|
- byt `SUNSHINE_PASS` till ett starkt lösenord,
|
||||||
|
- verifiera `GPU_CARD_DEVICE` och `GPU_RENDER_DEVICE` för rätt GPU.
|
||||||
|
|
||||||
|
## Portar
|
||||||
|
|
||||||
|
- Defaultprofil (`steam`):
|
||||||
|
- `${STEAM_WEB_PORT:-8083}/tcp` för webdesktop.
|
||||||
|
|
||||||
|
Moonlightprofilen använder `network_mode: host` och tar därför nätverk direkt från host.
|
||||||
|
|
||||||
|
## Volymer
|
||||||
|
|
||||||
|
- Defaultprofil:
|
||||||
|
- `/DATA/AppData/$AppID/home -> /home/default`
|
||||||
|
- `/DATA/AppData/$AppID/games -> /mnt/games`
|
||||||
|
- Moonlightprofil:
|
||||||
|
- `/DATA/AppData/$AppID/moonlight-home -> /home/default`
|
||||||
|
- `/DATA/AppData/$AppID/moonlight-games -> /mnt/games`
|
||||||
|
|
||||||
|
## Privilegier och säkerhet
|
||||||
|
|
||||||
|
Gemensamt:
|
||||||
|
|
||||||
|
- `no-new-privileges:true`
|
||||||
|
|
||||||
|
Defaultprofil (`steam`, lägre risk):
|
||||||
|
|
||||||
|
- `cap_drop: ["ALL"]`
|
||||||
|
- Ingen `network_mode: host`
|
||||||
|
- Inga device mounts
|
||||||
|
- Ingen Sunshine-aktivering som default
|
||||||
|
|
||||||
|
Moonlightprofil (högrisk):
|
||||||
|
|
||||||
|
- `ipc: host`
|
||||||
|
- `security_opt: ["seccomp:unconfined", "apparmor:unconfined", "no-new-privileges:true"]`
|
||||||
|
- `cap_drop: ["ALL"]` + `cap_add: [NET_ADMIN, SYS_ADMIN, SYS_NICE]`
|
||||||
|
- `network_mode: host`
|
||||||
|
- Device mounts: `/dev/fuse`, `/dev/uinput`, `/dev/dri/*`
|
||||||
|
- `device_cgroup_rules: ['c 13:* rmw']`
|
||||||
|
|
||||||
|
## Säkerhetsavvikelser
|
||||||
|
|
||||||
|
Denna app innehåller avsiktliga avvikelser, primärt i `moonlight`-profilen.
|
||||||
|
|
||||||
|
Varför det behövs:
|
||||||
|
|
||||||
|
- Moonlight/Sunshine och fysisk controller-input kräver i praktiken host-nära åtkomst i denna containerfamilj.
|
||||||
|
|
||||||
|
Alternativ som utvärderats:
|
||||||
|
|
||||||
|
- Browser-only (`steam` default): lägre risk men sämre latens/gamepad.
|
||||||
|
- Full `privileged: true`: avvisat i scaffolden för att begränsa attackytan.
|
||||||
|
|
||||||
|
Risker:
|
||||||
|
|
||||||
|
- Host network minskar nätverksisolering.
|
||||||
|
- Extra capabilities och device-passthrough ökar konsekvensen vid containerkompromettering.
|
||||||
|
|
||||||
|
Riskreducering:
|
||||||
|
|
||||||
|
- Högrisk är opt-in via profil, inte default.
|
||||||
|
- Ingen docker socket-mount används.
|
||||||
|
- Persistent data är begränsad till `/DATA/AppData/$AppID/...`.
|
||||||
|
- Defaultprofilen droppar alla Linux capabilities.
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Scaffolden är avsedd för kontrollerad vidareutveckling och verifiering, inte som slutlig hardened release.
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# Roadmap
|
||||||
|
|
||||||
|
## Current State (2026-03-18)
|
||||||
|
|
||||||
|
- Browser-first service (`steam`) är testbar med låg-risk baseline.
|
||||||
|
- Moonlight service (`steam-moonlight`) finns som opt-in scaffold med dokumenterade risker.
|
||||||
|
- Operativa säkerhetskrav finns i `SECURITY.md` och `MOONLIGHT-RUNTIME-CHECKLIST.md`.
|
||||||
|
|
||||||
|
## Next Milestone: Moonlight Test-Ready (Fail-Closed)
|
||||||
|
|
||||||
|
Mål: Moonlight-profilen ska vägra starta vid osäker konfiguration.
|
||||||
|
|
||||||
|
1. Enforce credentials
|
||||||
|
- Blockera start om `SUNSHINE_PASS` är tomt eller default (`change-me`).
|
||||||
|
- Blockera start om `SUNSHINE_USER` är tomt.
|
||||||
|
|
||||||
|
2. Enforce GPU/device prerequisites
|
||||||
|
- Blockera start om `GPU_CARD_DEVICE` eller `GPU_RENDER_DEVICE` saknas på host.
|
||||||
|
- Blockera start om `/dev/fuse` eller `/dev/uinput` saknas.
|
||||||
|
|
||||||
|
3. Enforce network safety baseline
|
||||||
|
- Tydlig varning + explicit opt-in env för internet-exponering.
|
||||||
|
- Defaultantagande: LAN/VPN-only drift.
|
||||||
|
|
||||||
|
4. Preflight command and runbook
|
||||||
|
- Lägg till en verifierbar preflight-sekvens som måste passera före `up`.
|
||||||
|
- Uppdatera checklistan med pass/fail-kriterier.
|
||||||
|
|
||||||
|
## Hardening Milestone
|
||||||
|
|
||||||
|
1. Secrets hygiene
|
||||||
|
- Dokumentera rotationsintervall för Sunshine-credentials.
|
||||||
|
- Säkerställ att exempel aldrig innehåller riktiga credentials.
|
||||||
|
|
||||||
|
2. Capability minimization
|
||||||
|
- Verifiera om någon `cap_add` kan tas bort utan funktionsförlust.
|
||||||
|
- Dokumentera minsta uppsättning capabilities per use-case.
|
||||||
|
|
||||||
|
3. Upgrade discipline
|
||||||
|
- Definiera rutin för image-pin uppdatering (`tag + digest`) och rollback.
|
||||||
|
|
||||||
|
## Release Criteria (Moonlight)
|
||||||
|
|
||||||
|
För att kalla Moonlight-profilen releaseklar ska följande vara uppfyllt:
|
||||||
|
|
||||||
|
1. Fail-closed enforcement implementerat och verifierat.
|
||||||
|
2. Positiv test av Moonlight streaming med korrekt auth.
|
||||||
|
3. Negativ test: start blockeras vid osäkra defaults/missing devices.
|
||||||
|
4. `./scripts/validate-appstore.sh --enforce-risk-docs` passerar.
|
||||||
|
5. README + security docs uppdaterade med slutlig driftmodell.
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
# Security Model
|
||||||
|
|
||||||
|
Detta dokument beskriver säkerhetsmodellen för `steam-moonlight` och hur risker begränsas mellan default- och Moonlight-profil.
|
||||||
|
|
||||||
|
## Mål
|
||||||
|
|
||||||
|
- Hålla default-profilen (`steam`) så nära least-privilege som möjligt.
|
||||||
|
- Göra Moonlight-profil (`steam-moonlight`) explicit opt-in med tydlig riskaccept.
|
||||||
|
- Hålla state/data begränsad till `/DATA/AppData/$AppID/...`.
|
||||||
|
|
||||||
|
## Tillitsgränser
|
||||||
|
|
||||||
|
- Host OS och Docker daemon är högsta trust-zon.
|
||||||
|
- Containern är lägre trust-zon.
|
||||||
|
- Moonlight-klienter och LAN-trafik är extern yta.
|
||||||
|
|
||||||
|
## Threat Model
|
||||||
|
|
||||||
|
Primära hot:
|
||||||
|
|
||||||
|
- Kontoövertagande via svagt `SUNSHINE_PASS`.
|
||||||
|
- Lateral movement via `network_mode: host` (Moonlight-profil).
|
||||||
|
- Ökad impact vid containerkompromiss p.g.a. extra capabilities och device passthrough.
|
||||||
|
- Dataförlust vid felaktig mount-path.
|
||||||
|
|
||||||
|
## Säkerhetskontroller
|
||||||
|
|
||||||
|
Gemensamt:
|
||||||
|
|
||||||
|
- Immutable image pin (`tag + digest`).
|
||||||
|
- Ingen docker socket mount.
|
||||||
|
- Ingen `privileged: true`.
|
||||||
|
- Data paths begränsade till `/DATA/AppData/$AppID/...`.
|
||||||
|
|
||||||
|
Defaultprofil (`steam`):
|
||||||
|
|
||||||
|
- `cap_drop: ["ALL"]`
|
||||||
|
- `no-new-privileges:true`
|
||||||
|
- Ingen `host` network
|
||||||
|
- Inga device mounts
|
||||||
|
- Sunshine avstängd som default (`ENABLE_SUNSHINE=false`)
|
||||||
|
|
||||||
|
Moonlightprofil (`steam-moonlight`):
|
||||||
|
|
||||||
|
- Högriskkontroller isolerade till `profiles: ["moonlight"]`
|
||||||
|
- `cap_drop: ["ALL"]` + minsta kända `cap_add`
|
||||||
|
- Explicit device lista (`/dev/fuse`, `/dev/uinput`, `/dev/dri/*`)
|
||||||
|
- `seccomp:unconfined` och `apparmor:unconfined` endast i Moonlight-profilen
|
||||||
|
|
||||||
|
## Fail-Closed Regler
|
||||||
|
|
||||||
|
- Moonlight ska inte startas om `SUNSHINE_PASS` är default eller tomt.
|
||||||
|
- Moonlight ska inte startas om GPU-device mapping saknas eller är fel.
|
||||||
|
- Vid osäkerhet, kör endast defaultprofilen (`steam`).
|
||||||
|
|
||||||
|
## Operativa krav
|
||||||
|
|
||||||
|
- Exponera inte Sunshine admin/UI mot internet.
|
||||||
|
- Begränsa åtkomst till LAN/VPN och pålitliga klienter.
|
||||||
|
- Rota image-pins kontrollerat och verifiera digest före uppdatering.
|
||||||
|
- Följ checklistan i `MOONLIGHT-RUNTIME-CHECKLIST.md` före varje aktivering.
|
||||||
|
|
||||||
|
## Incidentrespons (minimum)
|
||||||
|
|
||||||
|
Vid misstänkt kompromiss:
|
||||||
|
|
||||||
|
1. Stoppa Moonlight-profilen direkt.
|
||||||
|
2. Roterar `SUNSHINE_PASS` och övriga credentials.
|
||||||
|
3. Granska hostens nätverksexponering och Docker logs.
|
||||||
|
4. Byt image till känd god pin och starta om endast defaultprofil.
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
name: steam-moonlight
|
||||||
|
|
||||||
|
x-steam-common: &steam-common
|
||||||
|
image: josh5/steam-headless:debian-0.2.0@sha256:540366bee31297c5679a5006a84dbca039ca62aaab695852b51b5f62dffd2c14
|
||||||
|
restart: unless-stopped
|
||||||
|
shm_size: ${SHM_SIZE:-2G}
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
|
PUID: ${PUID}
|
||||||
|
PGID: ${PGID}
|
||||||
|
UMASK: ${UMASK:-000}
|
||||||
|
USER_PASSWORD: ${USER_PASSWORD:-change-me}
|
||||||
|
MODE: ${MODE:-primary}
|
||||||
|
WEB_UI_MODE: ${WEB_UI_MODE:-vnc}
|
||||||
|
PORT_NOVNC_WEB: ${STEAM_WEB_PORT:-8083}
|
||||||
|
ENABLE_STEAM: ${ENABLE_STEAM:-true}
|
||||||
|
STEAM_ARGS: ${STEAM_ARGS:--silent}
|
||||||
|
ENABLE_SUNSHINE: ${ENABLE_SUNSHINE:-false}
|
||||||
|
SUNSHINE_USER: ${SUNSHINE_USER:-admin}
|
||||||
|
SUNSHINE_PASS: ${SUNSHINE_PASS:-change-me}
|
||||||
|
|
||||||
|
services:
|
||||||
|
steam:
|
||||||
|
<<: *steam-common
|
||||||
|
container_name: steam-moonlight
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
ports:
|
||||||
|
- target: 8083
|
||||||
|
published: ${STEAM_WEB_PORT:-8083}
|
||||||
|
protocol: tcp
|
||||||
|
volumes:
|
||||||
|
- type: bind
|
||||||
|
source: /DATA/AppData/$AppID/home
|
||||||
|
target: /home/default
|
||||||
|
- type: bind
|
||||||
|
source: /DATA/AppData/$AppID/games
|
||||||
|
target: /mnt/games
|
||||||
|
x-casaos:
|
||||||
|
envs:
|
||||||
|
- container: TZ
|
||||||
|
description:
|
||||||
|
en_us: Timezone, for example Europe/Stockholm
|
||||||
|
- container: PUID
|
||||||
|
description:
|
||||||
|
en_us: User ID for filesystem permissions
|
||||||
|
- container: PGID
|
||||||
|
description:
|
||||||
|
en_us: Group ID for filesystem permissions
|
||||||
|
- container: STEAM_WEB_PORT
|
||||||
|
description:
|
||||||
|
en_us: Browser desktop port
|
||||||
|
ports:
|
||||||
|
- container: "8083"
|
||||||
|
description:
|
||||||
|
en_us: Steam desktop over web browser
|
||||||
|
volumes:
|
||||||
|
- container: /home/default
|
||||||
|
description:
|
||||||
|
en_us: Persistent user home and runtime state
|
||||||
|
- container: /mnt/games
|
||||||
|
description:
|
||||||
|
en_us: Persistent Steam game library
|
||||||
|
|
||||||
|
steam-moonlight:
|
||||||
|
<<: *steam-common
|
||||||
|
container_name: steam-moonlight-profile
|
||||||
|
profiles: ["moonlight"]
|
||||||
|
network_mode: host
|
||||||
|
ipc: host
|
||||||
|
security_opt:
|
||||||
|
- seccomp:unconfined
|
||||||
|
- apparmor:unconfined
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
cap_add:
|
||||||
|
- NET_ADMIN
|
||||||
|
- SYS_ADMIN
|
||||||
|
- SYS_NICE
|
||||||
|
devices:
|
||||||
|
- /dev/fuse
|
||||||
|
- /dev/uinput
|
||||||
|
- ${GPU_CARD_DEVICE:-/dev/dri/card0}
|
||||||
|
- ${GPU_RENDER_DEVICE:-/dev/dri/renderD128}
|
||||||
|
device_cgroup_rules:
|
||||||
|
- 'c 13:* rmw'
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
|
PUID: ${PUID}
|
||||||
|
PGID: ${PGID}
|
||||||
|
UMASK: ${UMASK:-000}
|
||||||
|
USER_PASSWORD: ${USER_PASSWORD:-change-me}
|
||||||
|
MODE: ${MODE:-primary}
|
||||||
|
WEB_UI_MODE: ${WEB_UI_MODE:-vnc}
|
||||||
|
PORT_NOVNC_WEB: ${STEAM_WEB_PORT:-8083}
|
||||||
|
ENABLE_STEAM: ${ENABLE_STEAM:-true}
|
||||||
|
STEAM_ARGS: ${STEAM_ARGS:--silent}
|
||||||
|
ENABLE_SUNSHINE: "true"
|
||||||
|
SUNSHINE_USER: ${SUNSHINE_USER:-admin}
|
||||||
|
SUNSHINE_PASS: ${SUNSHINE_PASS:-change-me}
|
||||||
|
volumes:
|
||||||
|
- type: bind
|
||||||
|
source: /DATA/AppData/$AppID/moonlight-home
|
||||||
|
target: /home/default
|
||||||
|
- type: bind
|
||||||
|
source: /DATA/AppData/$AppID/moonlight-games
|
||||||
|
target: /mnt/games
|
||||||
|
|
||||||
|
x-casaos:
|
||||||
|
architectures:
|
||||||
|
- amd64
|
||||||
|
main: steam
|
||||||
|
category: Games
|
||||||
|
author: Zima Apps Team
|
||||||
|
developer: Steam-Headless community
|
||||||
|
icon: https://cdn.simpleicons.org/steam
|
||||||
|
tagline:
|
||||||
|
en_us: Steam web desktop with optional Moonlight profile
|
||||||
|
description:
|
||||||
|
en_us: >-
|
||||||
|
Browser-first Steam container with an explicit moonlight profile for higher
|
||||||
|
compatibility and controller support. The moonlight profile is opt-in and
|
||||||
|
carries additional security risk.
|
||||||
|
title:
|
||||||
|
en_us: Steam Moonlight (Scaffold)
|
||||||
|
index: /
|
||||||
|
port_map: ${STEAM_WEB_PORT:-8083}
|
||||||
|
scheme: http
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
# How To Verify
|
||||||
|
|
||||||
|
Detta dokument verifierar båda Steam-apparna i repo:
|
||||||
|
|
||||||
|
- `Apps/steam-headless`
|
||||||
|
- `Apps/steam-moonlight`
|
||||||
|
|
||||||
|
## 1) Repo-validering
|
||||||
|
|
||||||
|
Kör från repo-roten:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/validate-appstore.sh --enforce-risk-docs
|
||||||
|
```
|
||||||
|
|
||||||
|
Förväntat: `Validation OK` eller `Validation OK with ... warning(s)`.
|
||||||
|
|
||||||
|
## 2) Verifiera steam-headless (browser-first)
|
||||||
|
|
||||||
|
Rendera compose:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f Apps/steam-headless/docker-compose.yaml config
|
||||||
|
```
|
||||||
|
|
||||||
|
Starta:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f Apps/steam-headless/docker-compose.yaml up -d steam
|
||||||
|
```
|
||||||
|
|
||||||
|
Kontroller:
|
||||||
|
|
||||||
|
1. `docker compose -f Apps/steam-headless/docker-compose.yaml ps` visar `steam` som running.
|
||||||
|
2. Web UI nås på `${STEAM_HTTP_PORT:-3000}` eller `${STEAM_HTTPS_PORT:-3001}`.
|
||||||
|
3. Inga extra högriskflaggor används (`privileged`, `host network`, `docker.sock`).
|
||||||
|
|
||||||
|
Stoppa:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f Apps/steam-headless/docker-compose.yaml down
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3) Verifiera steam-moonlight defaultprofil
|
||||||
|
|
||||||
|
Rendera compose (default):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f Apps/steam-moonlight/docker-compose.yaml config
|
||||||
|
```
|
||||||
|
|
||||||
|
Starta default service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f Apps/steam-moonlight/docker-compose.yaml up -d steam
|
||||||
|
```
|
||||||
|
|
||||||
|
Kontroller:
|
||||||
|
|
||||||
|
1. `steam` är running.
|
||||||
|
2. Webdesktop nås på `${STEAM_WEB_PORT:-8083}`.
|
||||||
|
3. Defaultprofilen kör med låg-risk baseline (`cap_drop: ALL`, ingen `host network`).
|
||||||
|
|
||||||
|
Stoppa:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f Apps/steam-moonlight/docker-compose.yaml down
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4) Verifiera steam-moonlight moonlight-profil (opt-in)
|
||||||
|
|
||||||
|
Preflight:
|
||||||
|
|
||||||
|
1. Sätt starkt `SUNSHINE_PASS`.
|
||||||
|
2. Verifiera GPU devices (`GPU_CARD_DEVICE`, `GPU_RENDER_DEVICE`).
|
||||||
|
3. Verifiera `/dev/fuse` och `/dev/uinput` på host.
|
||||||
|
|
||||||
|
Rendera moonlight-profil:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight config
|
||||||
|
```
|
||||||
|
|
||||||
|
Starta:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight up -d steam-moonlight
|
||||||
|
```
|
||||||
|
|
||||||
|
Kontroller:
|
||||||
|
|
||||||
|
1. `steam-moonlight` är running.
|
||||||
|
2. Sunshine kräver autentisering.
|
||||||
|
3. Moonlight-klient kan ansluta från LAN/VPN.
|
||||||
|
4. Ingen oavsiktlig internetexponering av Sunshine-portar.
|
||||||
|
|
||||||
|
Stoppa/rollback:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight down
|
||||||
|
```
|
||||||
|
|
||||||
|
Vid problem, återgå till defaultprofil:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f Apps/steam-moonlight/docker-compose.yaml up -d steam
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user