summary refs log tree commit diff
path: root/nixos/modules/services/wayland/cage.nix
diff options
context:
space:
mode:
authorMatthew Bauer <mjbauer95@gmail.com>2020-02-19 14:43:48 -0500
committerFlorian Klink <flokli@flokli.de>2020-03-02 13:43:20 -0800
commite0e4d591cc4ed4ff14c3f5bffb96d99b971ae639 (patch)
tree05f815f8ce66023cd46e1399450f11e692d08f92 /nixos/modules/services/wayland/cage.nix
parentc6c200f1185630be562a3d8bb9449a2d8f08589c (diff)
downloadnixpkgs-e0e4d591cc4ed4ff14c3f5bffb96d99b971ae639.tar
nixpkgs-e0e4d591cc4ed4ff14c3f5bffb96d99b971ae639.tar.gz
nixpkgs-e0e4d591cc4ed4ff14c3f5bffb96d99b971ae639.tar.bz2
nixpkgs-e0e4d591cc4ed4ff14c3f5bffb96d99b971ae639.tar.lz
nixpkgs-e0e4d591cc4ed4ff14c3f5bffb96d99b971ae639.tar.xz
nixpkgs-e0e4d591cc4ed4ff14c3f5bffb96d99b971ae639.tar.zst
nixpkgs-e0e4d591cc4ed4ff14c3f5bffb96d99b971ae639.zip
nixos/cage: init
Add a cage module to nixos. This can be used to make kiosk-style
systems that boot directly to a single application. The user (demo by
default) is automatically logged in by this service and the
program (xterm by default) is automatically started.

This is useful for some embedded, single-user systems where we want
automatic booting. To keep the system secure, the user should have
limited privileges.

Based on the service provided in the Cage wiki here:

https://github.com/Hjdskes/cage/wiki/Starting-Cage-on-boot-with-systemd

Co-Authored-By: Florian Klink <flokli@flokli.de>
Diffstat (limited to 'nixos/modules/services/wayland/cage.nix')
-rw-r--r--nixos/modules/services/wayland/cage.nix99
1 files changed, 99 insertions, 0 deletions
diff --git a/nixos/modules/services/wayland/cage.nix b/nixos/modules/services/wayland/cage.nix
new file mode 100644
index 00000000000..cac5c042ec1
--- /dev/null
+++ b/nixos/modules/services/wayland/cage.nix
@@ -0,0 +1,99 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.services.cage;
+in {
+  options.services.cage.enable = mkEnableOption "cage kiosk service";
+
+  options.services.cage.user = mkOption {
+    type = types.str;
+    default = "demo";
+    description = ''
+      User to log-in as.
+    '';
+  };
+
+  options.services.cage.extraArguments = mkOption {
+    type = types.listOf types.str;
+    default = [];
+    defaultText = "[]";
+    description = "Additional command line arguments to pass to Cage.";
+    example = ["-d"];
+  };
+
+  options.services.cage.program = mkOption {
+    type = types.path;
+    default = "${pkgs.xterm}/bin/xterm";
+    description = ''
+      Program to run in cage.
+    '';
+  };
+
+  config = mkIf cfg.enable {
+
+    # The service is partially based off of the one provided in the
+    # cage wiki at
+    # https://github.com/Hjdskes/cage/wiki/Starting-Cage-on-boot-with-systemd.
+    systemd.services."cage-tty1" = {
+      enable = true;
+      after = [
+        "systemd-user-sessions.service"
+        "plymouth-start.service"
+        "plymouth-quit.service"
+        "systemd-logind.service"
+        "getty@tty1.service"
+      ];
+      before = [ "graphical.target" ];
+      wants = [ "dbus.socket" "systemd-logind.service" "plymouth-quit.service"];
+      wantedBy = [ "graphical.target" ];
+      conflicts = [ "getty@tty1.service" ];
+
+      restartIfChanged = false;
+      serviceConfig = {
+        ExecStart = ''
+          ${pkgs.cage}/bin/cage \
+            ${escapeShellArgs cfg.extraArguments} \
+            -- ${cfg.program}
+        '';
+        User = cfg.user;
+
+        ConditionPathExists = "/dev/tty1";
+        IgnoreSIGPIPE = "no";
+
+        # Log this user with utmp, letting it show up with commands 'w' and
+        # 'who'. This is needed since we replace (a)getty.
+        UtmpIdentifier = "%n";
+        UtmpMode = "user";
+        # A virtual terminal is needed.
+        TTYPath = "/dev/tty1";
+        TTYReset = "yes";
+        TTYVHangup = "yes";
+        TTYVTDisallocate = "yes";
+        # Fail to start if not controlling the virtual terminal.
+        StandardInput = "tty-fail";
+        StandardOutput = "syslog";
+        StandardError = "syslog";
+        # Set up a full (custom) user session for the user, required by Cage.
+        PAMName = "cage";
+      };
+    };
+
+    security.pam.services.cage.text = ''
+      auth    required pam_unix.so nullok
+      account required pam_unix.so
+      session required pam_unix.so
+      session required ${pkgs.systemd}/lib/security/pam_systemd.so
+    '';
+
+    hardware.opengl.enable = mkDefault true;
+
+    systemd.targets.graphical.wants = [ "cage-tty1.service" ];
+
+    systemd.defaultUnit = "graphical.target";
+  };
+
+  meta.maintainers = with lib.maintainers; [ matthewbauer flokli ];
+
+}