aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/kiosk/default.nix195
1 files changed, 195 insertions, 0 deletions
diff --git a/modules/kiosk/default.nix b/modules/kiosk/default.nix
new file mode 100644
index 0000000..92cd2d5
--- /dev/null
+++ b/modules/kiosk/default.nix
@@ -0,0 +1,195 @@
+{
+ pkgs,
+ lib,
+ config,
+ ...
+}:
+let
+ inherit (lib)
+ escapeShellArg
+ mkEnableOption
+ mkOption
+ types
+ mkIf
+ ;
+ inherit (builtins) concatStringsSep;
+ cfg = config.services.kiosk;
+in
+{
+ options.services.kiosk = {
+ enable = mkEnableOption "acting as a browser-based kiosk";
+
+ user = mkOption {
+ description = "Name of user to run kiosk as";
+ default = "kiosk";
+ type = types.str;
+ };
+ group = mkOption {
+ description = "Name of group for kiosk user";
+ default = "kiosk";
+ type = types.str;
+ };
+
+ home = mkOption {
+ description = "Home directory for the user";
+ default = "/var/kiosk";
+ type = types.str;
+ };
+
+ urls = mkOption {
+ description = "URLs to open";
+ default = [ ];
+ type = types.listOf types.str;
+ };
+
+ firefoxCommand = mkOption {
+ description = "Version of firefox to use";
+ default = "${
+ pkgs.firefox.override {
+ cfg.speechSynthesisSupport = false;
+ extraPolicies =
+ let
+ lock-false = {
+ Value = false;
+ Status = "locked";
+ };
+ lock-true = {
+ Value = true;
+ Status = "locked";
+ };
+ in
+ {
+
+ DisableTelemetry = true;
+ DisableFirefoxStudies = true;
+ EnableTrackingProtection = {
+ Value = true;
+ Locked = true;
+ Cryptomining = true;
+ Fingerprinting = true;
+ };
+ DisablePocket = true;
+ OverrideFirstRunPage = "";
+ OverridePostUpdatePage = "";
+ DontCheckDefaultBrowser = true;
+ DisplayBookmarksToolbar = "never"; # alternatives: "always" or "newtab"
+ DisplayMenuBar = "default-off"; # alternatives: "always", "never" or "default-on"
+ SearchBar = "unified"; # alternative: "separate"
+
+ DisableFirefoxAccounts = true;
+ DisableFirefoxScreenshots = true;
+ DisableAccounts = true;
+
+ PasswordManagerEnabled = false;
+
+ SearchEngines.Remove = [ "Google" ];
+ Preferences = {
+
+ # Based on github.com/arkenfox/user.js
+ "extensions.pocket.enabled" = lock-false;
+
+ # Recommendations
+ "extensions.getAddons.showPane" = lock-false;
+ "extensions.htmlaboutaddons.recommendations.enabled" = lock-false;
+ "browser.discovery.enabled" = lock-false;
+ "browser.shopping.experience2023.enabled" = lock-false;
+
+ # Telemetry
+ "datareporting.policy.dataSubmissionEnabled" = lock-false;
+ "datareporting.healthreport.uploadEnabled" = lock-false;
+ "toolkit.telemetry.unified" = lock-false;
+ "toolkit.telemetry.enabled" = lock-false;
+ "toolkit.telemetry.server" = "data:";
+ "toolkit.telemetry.archive.enabled" = lock-false;
+ "toolkit.telemetry.newProfilePing.enabled" = lock-false;
+ "toolkit.telemetry.shutdownPingSender.enabled" = lock-false;
+ "toolkit.telemetry.updatePing.enabled" = lock-false;
+ "toolkit.telemetry.bhrPing.enabled" = lock-false;
+ "toolkit.telemetry.firstShutdownPing.enabled" = lock-false;
+ "toolkit.telemetry.coverage.opt-out" = lock-true;
+ "toolkit.coverage.opt-out" = lock-true;
+ "toolkit.coverage.endpoint.base" = "";
+ "browser.ping-centre.telemetry" = lock-false;
+ "browser.newtabpage.activity-stream.feeds.telemetry" = lock-false;
+ "browser.newtabpage.activity-stream.telemetry" = lock-false;
+
+ # Studies
+ "app.shield.optoutstudies.enabled" = lock-false;
+ "app.normandy.enabled" = lock-false;
+ "app.normandy.api_url" = "";
+
+ # Autofill
+ "browser.formfill.enable" = lock-false;
+ "signon.autofillForms" = lock-false;
+ "signon.formlessCapture.enabled" = lock-false;
+
+ # Better SSL error display
+ "browser.xul.error_pages.expert_bad_cert" = lock-true;
+
+ # Miscellaneous
+ "font.default.x-western" = "sans-serif";
+ "browser.uitour.enabled" = lock-false;
+ "pdfjs.enableScripting" = lock-false;
+ "browser.sessionrestore.resume_from_crash" = lock-false;
+ "browser.contentblocking.category" = "strict";
+ "privacy.donottrackheader.enabled" = lock-true;
+ "privacy.globalprivacycontrol.enabled" = lock-true;
+ "privacy.globalprivacycontrol.was-ever-enabled" = lock-true;
+ "signon.rememberSignons" = lock-false;
+ "browser.toolbars.bookmarks.visibility" = "never";
+ "browser.startup.homepage_override.mstone" = "ignore";
+ "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons" = lock-false;
+ "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features" = lock-false;
+ "browser.messaging-system.whatsNewPanel.enabled" = lock-false;
+ "toolkit.legacyUserProfileCustomizations.stylesheets" = lock-true;
+ };
+ };
+ }
+ }/bin/firefox";
+ type = types.str;
+ };
+ };
+
+ config = mkIf cfg.enable {
+ users.users.${cfg.user} = {
+ isSystemUser = true;
+ home = cfg.home;
+ group = cfg.group;
+ createHome = true;
+ useDefaultShell = true;
+ };
+ users.groups.${cfg.group} = { };
+
+ services.getty.autologinUser = cfg.user;
+
+ services.xserver = {
+ enable = true;
+ displayManager.startx.enable = true;
+ };
+ hardware.opengl = {
+ enable = true;
+ driSupport = true;
+ };
+
+ system.activationScripts.kiosk-home = {
+ text = ''
+ mkdir -p ${cfg.home}
+ cat >${cfg.home}/.xinitrc <<EOF
+ #!/usr/bin/env bash
+ xset s off
+ xset -dpms
+ ${cfg.firefoxCommand} --kiosk --kiosk-monitor 0 ${concatStringsSep " " (map escapeShellArg cfg.urls)} &
+ sleep 10
+ # Firefox kiosk mode doesn't actually maximise for some reason
+ ${pkgs.xdotool}/bin/xdotool search --name ".*Mozilla Firefox" windowsize 100% 100%
+ wait
+ EOF
+ cat >${cfg.home}/.bash_profile <<EOF
+ [[ -z \$DISPLAY && \$XDG_VTNR -eq 1 ]] && exec startx
+ EOF
+ chown -R kiosk:kiosk ${cfg.home}
+ '';
+ deps = [ "users" ];
+ };
+ };
+}