{ lib, pkgs, ... }: let epicenter-vm = pkgs.writeShellScriptBin "epicenter-vm" '' set -euo pipefail VM_DIR="$HOME/epicenter-vm" DISK="$VM_DIR/disk.qcow2" ISO="" while [[ $# -gt 0 ]]; do case "$1" in --iso) ISO="$2"; shift 2 ;; *) echo "Usage: epicenter-vm [--iso /path/to/file.iso]"; exit 1 ;; esac done # Create disk if it doesn't exist if [ ! -f "$DISK" ]; then mkdir -p "$VM_DIR" ${pkgs.qemu}/bin/qemu-img create -f qcow2 "$DISK" 60G fi QEMU_ARGS=( -enable-kvm -m 4G -smp 2 -drive "file=$DISK,format=qcow2,if=virtio" -bios ${pkgs.OVMF.fd}/FV/OVMF.fd -display gtk,gl=on -device virtio-vga-gl -device virtio-net-pci,netdev=net0 -netdev user,id=net0,hostfwd=tcp::2222-:22 ) # Attach ISO if provided if [ -n "$ISO" ]; then QEMU_ARGS+=(-cdrom "$ISO" -boot d) fi exec ${pkgs.qemu}/bin/qemu-system-x86_64 "''${QEMU_ARGS[@]}" ''; wrapperScript = pkgs.writeShellScriptBin "rustdesk-epicenter-wrapper" '' # Grant epicenter user access to the Wayland socket ${pkgs.acl}/bin/setfacl -m u:epicenter:x "$XDG_RUNTIME_DIR" ${pkgs.acl}/bin/setfacl -m u:epicenter:rwx "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" # Run rustdesk as epicenter user with absolute path to Wayland socket exec /run/wrappers/bin/sudo -u epicenter \ WAYLAND_DISPLAY="$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" \ XDG_RUNTIME_DIR=/run/user/1001 \ ${pkgs.rustdesk-flutter}/bin/rustdesk "$@" ''; rustdeskEpicenterDesktopItem = pkgs.makeDesktopItem { name = "rustdesk-epicenter"; desktopName = "RustDesk Epicenter"; exec = "${wrapperScript}/bin/rustdesk-epicenter-wrapper"; icon = "rustdesk"; categories = [ "Network" "RemoteAccess" ]; comment = "Remote desktop software for office user (Epicenter)"; }; in { environment.systemPackages = [ epicenter-vm rustdeskEpicenterDesktopItem ]; users.users.epicenter = { isNormalUser = true; extraGroups = [ ]; # Minimal groups }; users.groups.epicenter = {}; # Allow dominik to run rustdesk as epicenter user without password security.sudo.extraRules = [ { users = [ "dominik" ]; runAs = "epicenter"; commands = [ { command = "${pkgs.rustdesk-flutter}/bin/rustdesk"; options = [ "NOPASSWD" "SETENV" ]; } ]; } ]; home-manager.users.epicenter = { home.stateVersion = "24.05"; home.username = "epicenter"; home.homeDirectory = "/home/epicenter"; # Add rustdesk to the epicenter user's packages home.packages = with pkgs; [ rustdesk-flutter ]; # Declaratively configure RustDesk for Epicenter server home.file.".config/rustdesk/RustDesk2.toml" = { force = true; text = '' rendezvous_server = 'rustdesk.helsinki.tools:21116' nat_type = 1 serial = 0 unlock_pin = ''' trusted_devices = ''' [options] av1-test = 'N' key = '8jkD3HoWK+flkWcAMIqRnyn0jr4r9VPb+JYIbBtb+7k=' api-server = 'https://rustdesk.helsinki.tools' custom-rendezvous-server = 'rustdesk.helsinki.tools' ''; }; }; }