From b5fc81fe0112b9bc2a175e39f5275d9782d3b08a Mon Sep 17 00:00:00 2001 From: Stefan Kempinger Date: Thu, 2 Apr 2026 19:50:10 +0200 Subject: [PATCH 1/2] better cage setup --- lnf/configuration.nix | 228 ++++++++++++++---------------------------- 1 file changed, 73 insertions(+), 155 deletions(-) diff --git a/lnf/configuration.nix b/lnf/configuration.nix index c36232f..6e822f5 100644 --- a/lnf/configuration.nix +++ b/lnf/configuration.nix @@ -1,6 +1,3 @@ -# Edit this configuration file to define what should be installed on -# your system. Help is available in the configuration.nix(5) man page -# and in the NixOS manual (accessible by running 'nixos-help'). { config, pkgs, ... }: { imports = [ @@ -10,32 +7,32 @@ boot.loader.grub.enable = true; boot.loader.grub.device = "/dev/vda"; boot.loader.grub.useOSProber = true; - + services.xserver.videoDrivers = [ "modesetting" ]; hardware.graphics = { enable = true; extraPackages = with pkgs; [ # Required for modern Intel GPUs (Xe iGPU and ARC) - intel-media-driver # VA-API (iHD) userspace - vpl-gpu-rt # oneVPL (QSV) runtime + intel-media-driver # VA-API (iHD) userspace + vpl-gpu-rt # oneVPL (QSV) runtime # Optional (compute / tooling): - intel-compute-runtime # OpenCL (NEO) + Level Zero for Arc/Xe + intel-compute-runtime # OpenCL (NEO) + Level Zero for Arc/Xe # NOTE: 'intel-ocl' also exists as a legacy package; not recommended for Arc/Xe. # libvdpau-va-gl # Only if you must run VDPAU-only apps ]; }; - environment.sessionVariables = { - LIBVA_DRIVER_NAME = "iHD"; # Prefer the modern iHD backend - # VDPAU_DRIVER = "va_gl"; # Only if using libvdpau-va-gl - }; - - # May help if FFmpeg/VAAPI/QSV init fails (esp. on Arc with i915): hardware.enableRedistributableFirmware = true; boot.kernelParams = [ "i915.enable_guc=3" ]; + environment.sessionVariables = { + LIBVA_DRIVER_NAME = "iHD"; + QT_QPA_PLATFORM = "wayland"; + WLR_NO_HARDWARE_CURSORS = "1"; + }; + networking.hostName = "nixos-lnf"; networking.wireless.enable = true; networking.networkmanager.enable = true; @@ -65,7 +62,11 @@ users.users.user = { isNormalUser = true; description = "user"; - extraGroups = [ "networkmanager" "wheel" "video" ]; + extraGroups = [ + "networkmanager" + "wheel" + "video" + ]; packages = with pkgs; [ ]; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINGHadFhDCUU/ta3p1FQgpm7NExHkyHNrJbNJP6np5w9 kempinger@ins.jku.at" @@ -79,6 +80,18 @@ ]; }; + security.sudo.extraRules = [ + { + users = [ "user" ]; + commands = [ + { + command = "/run/current-system/sw/bin/systemctl restart cage-tty1.service"; + options = [ "NOPASSWD" ]; + } + ]; + } + ]; + nixpkgs.config.allowUnfree = true; environment.systemPackages = with pkgs; [ @@ -89,154 +102,57 @@ kmsxx libinput vlc - jq - sway ffmpeg python3 - - (pkgs.writeScriptBin "run-on-output" '' - #!/usr/bin/env bash - # Usage: run-on-output - # Example: run-on-output 1 firefox --kiosk https://example.com - # run-on-output 2 vlc --fullscreen /path/to/video.mp4 - - set -euo pipefail - - if [[ $# -lt 2 ]]; then - echo "Usage: run-on-output " >&2 - exit 1 - fi - - IDX="$1" - shift - - MYUID=$(id -u) - SOCK=$(ls /run/user/"$MYUID"/sway-ipc.* 2>/dev/null | head -n1) - if [[ -z "$SOCK" ]]; then - echo "Error: no sway IPC socket found for uid $MYUID" >&2 - exit 1 - fi - export SWAYSOCK="$SOCK" - - # Inherit Wayland env from the running sway instance - export WAYLAND_DISPLAY=$(${pkgs.sway}/bin/swaymsg -t get_version -r \ - | ${pkgs.jq}/bin/jq -r '.loaded_config_file' 2>/dev/null \ - | xargs -I{} sh -c 'echo "wayland-1"' 2>/dev/null || echo "wayland-1") - export XDG_RUNTIME_DIR="/run/user/$MYUID" - - OUT=$(${pkgs.sway}/bin/swaymsg -t get_outputs -r \ - | ${pkgs.jq}/bin/jq -r ".[$((IDX-1))].name") - - if [[ "$OUT" == "null" || -z "$OUT" ]]; then - echo "Error: no output found at index $IDX" >&2 - ${pkgs.sway}/bin/swaymsg -t get_outputs -r \ - | ${pkgs.jq}/bin/jq -r '.[].name' | nl -v1 -ba >&2 - exit 1 - fi - - echo "Launching on output $IDX ($OUT): $*" - - # Workspace management only — no exec via swaymsg - ${pkgs.sway}/bin/swaymsg "[workspace=$IDX] kill" 2>/dev/null || true - sleep 0.3 - ${pkgs.sway}/bin/swaymsg "workspace $IDX; move workspace to output $OUT" - - # Launch directly — inherits full PATH and Wayland env from this shell - nohup "$@" >> /tmp/run-on-output-$IDX.log 2>&1 & - - echo "Launched PID $! on workspace $IDX ($OUT)" - '') + jq + bash + + (pkgs.writeScriptBin "kiosk-run" '' + #!/usr/bin/env bash + set -euo pipefail + + if [[ $# -lt 1 ]]; then + echo "Usage: kiosk-run " >&2 + exit 1 + fi + + echo "Setting command: $*" + echo "$*" > /etc/cage/current-cmd + + echo "Restarting cage..." + sudo systemctl kill cage-tty1.service + sudo systemctl start cage-tty1.service + + echo "Done." + '') ]; - + programs.firefox.enable = true; - # ── Sway: multi-monitor Wayland compositor ───────────────────────────────── - programs.sway = { - enable = true; - wrapperFeatures.gtk = true; + # writable by the kiosk user at runtime + environment.etc."cage/current-cmd" = { + mode = "0777"; + text = "ls -al"; }; - # Script that runs inside the sway session. - # It detects every active output, pins a numbered workspace to each, - # then launches one VLC per workspace (→ per monitor). - environment.etc."sway/kiosk-start.sh" = { - mode = "0755"; - text = '' - #!/usr/bin/env bash - exec >> /tmp/kiosk-start.log 2>&1 - echo "[$(date)] kiosk-start.sh running" - sleep 2 # give sway more time to settle - - readarray -t outputs < <( - ${pkgs.sway}/bin/swaymsg -t get_outputs \ - | ${pkgs.jq}/bin/jq -r '.[] | select(.active) | .name' - ) - - echo "[$(date)] Found outputs: ''${outputs[*]}" - - # for i in "''${!outputs[@]}"; do - # ws=$(( i + 1 )) - # output="''${outputs[$i]}" - # echo "[$(date)] Launching VLC on output $output (workspace $ws)" - - # ${pkgs.sway}/bin/swaymsg "workspace $ws output $output" - # ${pkgs.sway}/bin/swaymsg "workspace $ws" - # ${pkgs.sway}/bin/swaymsg "exec ${pkgs.firefox}/bin/firefox" - # sleep 0.5 - # done - - echo "[$(date)] Done" - - ''; - }; - - # # Minimal sway config for the kiosk session - # environment.etc."sway/kiosk.conf".text = '' - # output * bg #000000 solid_color - # default_border none - # hide_edge_borders both - - # input * { - # xkb_layout de - # } - - # for_window [app_id="vlc"] fullscreen enable, inhibit_idle open - # for_window [class="vlc"] fullscreen enable, inhibit_idle open - # for_window [title="VLC.*"] fullscreen enable, inhibit_idle open - - # exec /etc/sway/kiosk-start.sh - # ''; - - # Minimal sway config for the kiosk session - environment.etc."sway/kiosk.conf".text = '' - output * bg #000000 solid_color - default_border none - hide_edge_borders both - - input * { - xkb_layout de - } - - exec /etc/sway/kiosk-start.sh - ''; - - environment.sessionVariables = { - QT_QPA_PLATFORM = "wayland"; - WLR_NO_HARDWARE_CURSORS = "1"; - }; - - # ── greetd: replaces cage, autologins user and starts sway ───────────────── - services.greetd = { - enable = true; - settings = { - default_session = { - command = "${pkgs.sway}/bin/sway --config /etc/sway/kiosk.conf"; - user = "user"; - }; + systemd.services.cage-tty1 = { + serviceConfig = { + Restart = "always"; + RestartSec = "1s"; + TimeoutStopSec = "1"; + TimeoutAbortSec = "5"; + KillSignal = "SIGKILL"; }; }; - # ── SSH ───────────────────────────────────────────────────────────────────── + services.cage = { + enable = true; + user = "user"; + program = "/etc/cage/current-cmd"; + }; + + services.getty.loginProgram = "${pkgs.coreutils}/bin/true"; + services.openssh = { enable = true; settings = { @@ -246,7 +162,9 @@ }; }; - nix.settings.experimental-features = [ "nix-command" "flakes" ]; - + nix.settings.experimental-features = [ + "nix-command" + "flakes" + ]; system.stateVersion = "25.11"; -} \ No newline at end of file +} From c0077acfa9393b83258646d41c8b227b3fe7f3bf Mon Sep 17 00:00:00 2001 From: Stefan Kempinger Date: Fri, 10 Apr 2026 12:40:05 +0200 Subject: [PATCH 2/2] Enable Vaultwarden on the server, ydotool on the laptop, update flake.lock --- flake.lock | 24 ++++++++++++------------ heimserver/configuration.nix | 29 +++++++++++++++++++++++++++++ kemptop/configuration.nix | 2 ++ 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/flake.lock b/flake.lock index 7c85334..8b9a8b6 100644 --- a/flake.lock +++ b/flake.lock @@ -65,11 +65,11 @@ ] }, "locked": { - "lastModified": 1774858933, - "narHash": "sha256-rgHUoE4QhOvK3Rcl9cbuIVdjPjFjfhcTm/uPs8Y7+2w=", + "lastModified": 1775815947, + "narHash": "sha256-zKmhefgqP+mlTwfSIJaI1Dw8IePnc17WwzrzRQ6JQ6Q=", "owner": "nix-community", "repo": "lanzaboote", - "rev": "45338aab3013924c75305f5cb3543b9cda993183", + "rev": "a5f5623a443d37deede6bce12c31ba03caecadcd", "type": "github" }, "original": { @@ -80,11 +80,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1774933469, - "narHash": "sha256-OrnCQeUO2bqaWUl0lkDWyGWjKsOhtCyd7JSfTedQNUE=", + "lastModified": 1775490113, + "narHash": "sha256-2ZBhDNZZwYkRmefK5XLOusCJHnoeKkoN95hoSGgMxWM=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "f4c4c2c0c923d7811ac2a63ccc154767e4195337", + "rev": "c775c2772ba56e906cbeb4e0b2db19079ef11ff7", "type": "github" }, "original": { @@ -95,11 +95,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1774709303, - "narHash": "sha256-D3Q07BbIA2KnTcSXIqqu9P586uWxN74zNoCH3h2ESHg=", + "lastModified": 1775710090, + "narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "8110df5ad7abf5d4c0f6fb0f8f978390e77f9685", + "rev": "4c1018dae018162ec878d42fec712642d214fdfa", "type": "github" }, "original": { @@ -147,11 +147,11 @@ ] }, "locked": { - "lastModified": 1775013181, - "narHash": "sha256-zPrt6oNM1r/RO5bWYaZ3hthfG9vzkr6kQdoqDd5x4Qw=", + "lastModified": 1775790837, + "narHash": "sha256-RAHjn8sjgfF3D17BaV8iv69o3P+L9aCuE36PFwzoqHU=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "e8046c1d9ccadd497c2344d8fa49dab62f22f7be", + "rev": "c913e0b9525311f103b7e1463ebb0f28c6865d8d", "type": "github" }, "original": { diff --git a/heimserver/configuration.nix b/heimserver/configuration.nix index fc1e848..97fd636 100644 --- a/heimserver/configuration.nix +++ b/heimserver/configuration.nix @@ -87,6 +87,7 @@ 8087 # paperless frontend 8090 # mail 8091 # mail jmap + 8092 # vaultwarden 8080 # homepage ]; firewall.allowedUDPPorts = [ @@ -905,6 +906,34 @@ enable = true; capacity = 50; }; + + services.vaultwarden = { + enable = true; + backupDir = "/backup/vaultwarden"; + # in order to avoid having ADMIN_TOKEN in the nix store it can be also set with the help of an environment file + # be aware that this file must be created by hand (or via secrets management like sops) + environmentFile = "/root/vaultwarden.env"; + config = { + # Refer to https://github.com/dani-garcia/vaultwarden/blob/main/.env.template + DOMAIN = "https://bitwarden.kempinger.at"; + SIGNUPS_ALLOWED = false; + + ROCKET_ADDRESS = "127.0.0.1"; + ROCKET_PORT = 8092; + ROCKET_LOG = "critical"; + + # This example assumes a mailserver running on localhost, + # thus without transport encryption. + # If you use an external mail server, follow: + # https://github.com/dani-garcia/vaultwarden/wiki/SMTP-configuration + SMTP_HOST = "127.0.0.1"; + SMTP_PORT = 25; + SMTP_SSL = false; + + SMTP_FROM = "admin@bitwarden.kempinger.at"; + SMTP_FROM_NAME = "kempinger.at Bitwarden server"; + }; + }; nixpkgs.config.allowUnfree = true; diff --git a/kemptop/configuration.nix b/kemptop/configuration.nix index a2bba22..d1035da 100644 --- a/kemptop/configuration.nix +++ b/kemptop/configuration.nix @@ -100,6 +100,7 @@ "wireshark" "networkmanager" "libvirtd" + "ydotool" ]; }; @@ -237,6 +238,7 @@ #security.pam.services.swaylock = {}; #programs.waybar.enable = true; # top bar + programs.ydotool.enable= true; programs.firefox.enable = true; programs.wireshark.enable = true; programs.wireshark.package = pkgs.wireshark;