# roles/thin-client/apps/rustdesk.nix # # RustDesk client (Hilfe annehmen) + daemon (unattended support). # Q13 decisions: Beides (Client+Daemon), Self-hosted Server, Pre-Shared Key # via agenix, Wayland portal pre-authorized, Permanent password via agenix. {config, lib, pkgs, ...}: let inherit (lib) mkIf mkOption types; cfg = config.az.tc; hostname = config.networking.hostName; in { options.az.tc.rustdesk = { serverHost = mkOption { type = types.str; default = "rustdesk.az-group.local"; # TODO: real host description = "Self-hosted RustDesk hbbs/hbbr endpoint (via NetBird)."; }; serverPort = mkOption { type = types.int; default = 21116; }; }; config = mkIf cfg.enable { environment = { systemPackages = with pkgs; [rustdesk]; etc = { # /etc/rustdesk/RustDesk.toml — daemon config. Pre-shared key and # server endpoints go here. Permanent password is in a separate # agenix secret and written to a path RustDesk reads. "rustdesk/RustDesk.toml".text = '' [options] custom-rendezvous-server = ${config.az.tc.rustdesk.serverHost} relay-server = ${config.az.tc.rustdesk.serverHost} api-server = https://${config.az.tc.rustdesk.serverHost} key = file:/run/agenix/rustdesk-psk verification-method = fixed-password permanent-password-file = /run/agenix/${hostname}-rustdesk-password enable-wayland-screen-share = true allow-auto-disconnect = false ''; # Wayland portal pre-authorization for RustDesk — KDE-specific # xdg portal config so the "screen capture" prompt is pre-approved. "xdg-desktop-portal/kde-screen-share.conf".text = '' [allowed] rustdesk=true ''; }; }; # Systemd service: RustDesk daemon (runs as root for unattended). systemd.services.rustdesk = { description = "RustDesk unattended support daemon"; wantedBy = ["multi-user.target"]; after = ["network-online.target" "age-identity.service"]; wants = ["network-online.target" "age-identity.service"]; serviceConfig = { Type = "simple"; ExecStart = "${pkgs.rustdesk}/bin/rustdesk --service"; Restart = "always"; RestartSec = "5s"; User = "root"; }; }; # Shared pre-shared key (one for all thin clients) age.secrets."rustdesk-psk" = { file = ../../secrets/rustdesk-psk.age; mode = "0400"; owner = "root"; }; # Per-host permanent password age.secrets."${hostname}-rustdesk-password" = { file = ../../secrets/${hostname}-rustdesk-password.age; mode = "0400"; owner = "root"; }; }; }