diff options
Diffstat (limited to 'nixos/modules')
-rw-r--r-- | nixos/modules/misc/ids.nix | 2 | ||||
-rw-r--r-- | nixos/modules/module-list.nix | 1 | ||||
-rw-r--r-- | nixos/modules/security/rngd.nix | 33 | ||||
-rw-r--r-- | nixos/modules/services/logging/journalbeat.nix | 43 | ||||
-rw-r--r-- | nixos/modules/services/misc/jellyfin.nix | 6 | ||||
-rw-r--r-- | nixos/modules/services/misc/paperless.nix | 185 | ||||
-rw-r--r-- | nixos/modules/services/monitoring/vnstat.nix | 19 | ||||
-rw-r--r-- | nixos/modules/services/x11/display-managers/lightdm.nix | 5 | ||||
-rw-r--r-- | nixos/modules/services/x11/display-managers/sddm.nix | 9 | ||||
-rw-r--r-- | nixos/modules/system/boot/kexec.nix | 12 | ||||
-rw-r--r-- | nixos/modules/virtualisation/virtualbox-host.nix | 2 |
11 files changed, 289 insertions, 28 deletions
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index cd6bb9019b18..5198bedc1387 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -339,6 +339,7 @@ rss2email = 312; cockroachdb = 313; zoneminder = 314; + paperless = 315; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -638,6 +639,7 @@ rss2email = 312; cockroachdb = 313; zoneminder = 314; + paperless = 315; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index b8d3c9245136..dee850f47f27 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -436,6 +436,7 @@ ./services/misc/octoprint.nix ./services/misc/osrm.nix ./services/misc/packagekit.nix + ./services/misc/paperless.nix ./services/misc/parsoid.nix ./services/misc/phd.nix ./services/misc/plex.nix diff --git a/nixos/modules/security/rngd.nix b/nixos/modules/security/rngd.nix index a54ef2e6fcad..60361d9960ed 100644 --- a/nixos/modules/security/rngd.nix +++ b/nixos/modules/security/rngd.nix @@ -2,20 +2,30 @@ with lib; +let + cfg = config.security.rngd; +in { options = { - security.rngd.enable = mkOption { - type = types.bool; - default = true; - description = '' - Whether to enable the rng daemon, which adds entropy from - hardware sources of randomness to the kernel entropy pool when - available. - ''; + security.rngd = { + enable = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable the rng daemon, which adds entropy from + hardware sources of randomness to the kernel entropy pool when + available. + ''; + }; + debug = mkOption { + type = types.bool; + default = false; + description = "Whether to enable debug output (-d)."; + }; }; }; - config = mkIf config.security.rngd.enable { + config = mkIf cfg.enable { services.udev.extraRules = '' KERNEL=="random", TAG+="systemd" SUBSYSTEM=="cpu", ENV{MODALIAS}=="cpu:type:x86,*feature:*009E*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="rngd.service" @@ -29,7 +39,10 @@ with lib; description = "Hardware RNG Entropy Gatherer Daemon"; - serviceConfig.ExecStart = "${pkgs.rng-tools}/sbin/rngd -f"; + serviceConfig = { + ExecStart = "${pkgs.rng-tools}/sbin/rngd -f" + + optionalString cfg.debug " -d"; + }; }; }; } diff --git a/nixos/modules/services/logging/journalbeat.nix b/nixos/modules/services/logging/journalbeat.nix index 8186a3b02c37..89f53b1b2454 100644 --- a/nixos/modules/services/logging/journalbeat.nix +++ b/nixos/modules/services/logging/journalbeat.nix @@ -5,11 +5,13 @@ with lib; let cfg = config.services.journalbeat; + lt6 = builtins.compareVersions cfg.package.version "6" < 0; + journalbeatYml = pkgs.writeText "journalbeat.yml" '' name: ${cfg.name} tags: ${builtins.toJSON cfg.tags} - journalbeat.cursor_state_file: ${cfg.stateDir}/cursor-state + ${optionalString lt6 "journalbeat.cursor_state_file: /var/lib/${cfg.stateDir}/cursor-state"} ${cfg.extraConfig} ''; @@ -22,6 +24,16 @@ in enable = mkEnableOption "journalbeat"; + package = mkOption { + type = types.package; + default = pkgs.journalbeat; + defaultText = "pkgs.journalbeat"; + example = literalExample "pkgs.journalbeat7"; + description = '' + The journalbeat package to use + ''; + }; + name = mkOption { type = types.str; default = "journalbeat"; @@ -36,13 +48,17 @@ in stateDir = mkOption { type = types.str; - default = "/var/lib/journalbeat"; - description = "The state directory. Journalbeat's own logs and other data are stored here."; + default = "journalbeat"; + description = '' + Directory below <literal>/var/lib/</literal> to store journalbeat's + own logs and other data. This directory will be created automatically + using systemd's StateDirectory mechanism. + ''; }; extraConfig = mkOption { type = types.lines; - default = '' + default = optionalString lt6 '' journalbeat: seek_position: cursor cursor_seek_fallback: tail @@ -61,7 +77,16 @@ in config = mkIf cfg.enable { - systemd.services.journalbeat = with pkgs; { + assertions = [ + { + assertion = !hasPrefix "/" cfg.stateDir; + message = + "The option services.journalbeat.stateDir shouldn't be an absolute directory." + + " It should be a directory relative to /var/lib/."; + } + ]; + + systemd.services.journalbeat = { description = "Journalbeat log shipper"; wantedBy = [ "multi-user.target" ]; preStart = '' @@ -69,7 +94,13 @@ in mkdir -p ${cfg.stateDir}/logs ''; serviceConfig = { - ExecStart = "${pkgs.journalbeat}/bin/journalbeat -c ${journalbeatYml} -path.data ${cfg.stateDir}/data -path.logs ${cfg.stateDir}/logs"; + StateDirectory = cfg.stateDir; + ExecStart = '' + ${cfg.package}/bin/journalbeat \ + -c ${journalbeatYml} \ + -path.data /var/lib/${cfg.stateDir}/data \ + -path.logs /var/lib/${cfg.stateDir}/logs''; + Restart = "always"; }; }; }; diff --git a/nixos/modules/services/misc/jellyfin.nix b/nixos/modules/services/misc/jellyfin.nix index 7f38dd0ff233..55559206568d 100644 --- a/nixos/modules/services/misc/jellyfin.nix +++ b/nixos/modules/services/misc/jellyfin.nix @@ -48,12 +48,6 @@ in jellyfin = {}; }; - assertions = [ - { - assertion = !config.services.emby.enable; - message = "Emby and Jellyfin are incompatible, you cannot enable both"; - } - ]; }; meta.maintainers = with lib.maintainers; [ minijackson ]; diff --git a/nixos/modules/services/misc/paperless.nix b/nixos/modules/services/misc/paperless.nix new file mode 100644 index 000000000000..4e6cd80e2425 --- /dev/null +++ b/nixos/modules/services/misc/paperless.nix @@ -0,0 +1,185 @@ +{ config, pkgs, lib, ... }: + +with lib; +let + cfg = config.services.paperless; + + defaultUser = "paperless"; + + manage = cfg.package.withConfig { + config = { + PAPERLESS_CONSUMPTION_DIR = cfg.consumptionDir; + PAPERLESS_INLINE_DOC = "true"; + PAPERLESS_DISABLE_LOGIN = "true"; + } // cfg.extraConfig; + inherit (cfg) dataDir ocrLanguages; + paperlessPkg = cfg.package; + }; +in +{ + options.services.paperless = { + enable = mkOption { + type = lib.types.bool; + default = false; + description = '' + Enable Paperless. + + When started, the Paperless database is automatically created if it doesn't + exist and updated if the Paperless package has changed. + Both tasks are achieved by running a Django migration. + ''; + }; + + dataDir = mkOption { + type = types.str; + default = "/var/lib/paperless"; + description = "Directory to store the Paperless data."; + }; + + consumptionDir = mkOption { + type = types.str; + default = "${cfg.dataDir}/consume"; + defaultText = "\${dataDir}/consume"; + description = "Directory from which new documents are imported."; + }; + + consumptionDirIsPublic = mkOption { + type = types.bool; + default = false; + description = "Whether all users can write to the consumption dir."; + }; + + ocrLanguages = mkOption { + type = with types; nullOr (listOf string); + default = null; + description = '' + Languages available for OCR via Tesseract, specified as + <literal>ISO 639-2/T</literal> language codes. + If unset, defaults to all available languages. + ''; + example = [ "eng" "spa" "jpn" ]; + }; + + address = mkOption { + type = types.str; + default = "localhost"; + description = "Server listening address."; + }; + + port = mkOption { + type = types.int; + default = 28981; + description = "Server port to listen on."; + }; + + extraConfig = mkOption { + type = types.attrs; + default = {}; + description = '' + Extra paperless config options. + + The config values are evaluated as double-quoted Bash string literals. + + See <literal>paperless-src/paperless.conf.example</literal> for available options. + + To enable user authentication, set <literal>PAPERLESS_DISABLE_LOGIN = "false"</literal> + and run the shell command <literal>$dataDir/paperless-manage createsuperuser</literal>. + + To define secret options without storing them in /nix/store, use the following pattern: + <literal>PAPERLESS_PASSPHRASE = "$(< /etc/my_passphrase_file)"</literal> + ''; + example = literalExample '' + { + PAPERLESS_OCR_LANGUAGE = "deu"; + } + ''; + }; + + user = mkOption { + type = types.str; + default = defaultUser; + description = "User under which Paperless runs."; + }; + + package = mkOption { + type = types.package; + default = pkgs.paperless; + defaultText = "pkgs.paperless"; + description = "The Paperless package to use."; + }; + + manage = mkOption { + type = types.package; + readOnly = true; + default = manage; + description = '' + A script to manage the Paperless instance. + It wraps Django's manage.py and is also available at + <literal>$dataDir/manage-paperless</literal> + ''; + }; + }; + + config = mkIf cfg.enable { + + systemd.tmpfiles.rules = [ + "d '${cfg.dataDir}' - ${cfg.user} ${cfg.user} - -" + ] ++ (optional cfg.consumptionDirIsPublic + "d '${cfg.consumptionDir}' 777 ${cfg.user} ${cfg.user} - -" + # If the consumption dir is not created here, it's automatically created by + # 'manage' with the default permissions. + ); + + systemd.services.paperless-consumer = { + description = "Paperless document consumer"; + serviceConfig = { + User = cfg.user; + ExecStart = "${manage} document_consumer"; + Restart = "always"; + }; + after = [ "systemd-tmpfiles-setup.service" ]; + wantedBy = [ "multi-user.target" ]; + preStart = '' + if [[ $(readlink ${cfg.dataDir}/paperless-manage) != ${manage} ]]; then + ln -sf ${manage} ${cfg.dataDir}/paperless-manage + fi + + ${manage.setupEnv} + # Auto-migrate on first run or if the package has changed + versionFile="$PAPERLESS_DBDIR/src-version" + if [[ $(cat "$versionFile" 2>/dev/null) != ${cfg.package} ]]; then + python $paperlessSrc/manage.py migrate + echo ${cfg.package} > "$versionFile" + fi + ''; + }; + + systemd.services.paperless-server = { + description = "Paperless document server"; + serviceConfig = { + User = cfg.user; + ExecStart = "${manage} runserver --noreload ${cfg.address}:${toString cfg.port}"; + Restart = "always"; + }; + # Bind to `paperless-consumer` so that the server never runs + # during migrations + bindsTo = [ "paperless-consumer.service" ]; + after = [ "paperless-consumer.service" ]; + wantedBy = [ "multi-user.target" ]; + }; + + users = optionalAttrs (cfg.user == defaultUser) { + users = [{ + name = defaultUser; + group = defaultUser; + uid = config.ids.uids.paperless; + home = cfg.dataDir; + }]; + + groups = [{ + name = defaultUser; + gid = config.ids.gids.paperless; + }]; + }; + }; +} diff --git a/nixos/modules/services/monitoring/vnstat.nix b/nixos/modules/services/monitoring/vnstat.nix index cb2f8c07edb9..e9bedb704a43 100644 --- a/nixos/modules/services/monitoring/vnstat.nix +++ b/nixos/modules/services/monitoring/vnstat.nix @@ -28,14 +28,29 @@ in { path = [ pkgs.coreutils ]; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - unitConfig.documentation = "man:vnstatd(1) man:vnstat(1) man:vnstat.conf(5)"; + documentation = [ + "man:vnstatd(1)" + "man:vnstat(1)" + "man:vnstat.conf(5)" + ]; preStart = "chmod 755 /var/lib/vnstat"; serviceConfig = { ExecStart = "${pkgs.vnstat}/bin/vnstatd -n"; ExecReload = "${pkgs.procps}/bin/kill -HUP $MAINPID"; - ProtectHome = true; + + # Hardening (from upstream example service) + ProtectSystem = "strict"; + StateDirectory = "vnstat"; PrivateDevices = true; + ProtectKernelTunables = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectKernelModules = true; PrivateTmp = true; + MemoryDenyWriteExecute = true; + RestrictRealtime = true; + RestrictNamespaces = true; + User = "vnstatd"; }; }; diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix index 3ab4f26399f3..afa0cebbc527 100644 --- a/nixos/modules/services/x11/display-managers/lightdm.nix +++ b/nixos/modules/services/x11/display-managers/lightdm.nix @@ -189,6 +189,11 @@ in config = mkIf cfg.enable { assertions = [ + { assertion = xcfg.enable; + message = '' + LightDM requires services.xserver.enable to be true + ''; + } { assertion = cfg.autoLogin.enable -> cfg.autoLogin.user != null; message = '' LightDM auto-login requires services.xserver.displayManager.lightdm.autoLogin.user to be set diff --git a/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix index 05830e325d51..d1ed345ac579 100644 --- a/nixos/modules/services/x11/display-managers/sddm.nix +++ b/nixos/modules/services/x11/display-managers/sddm.nix @@ -195,6 +195,11 @@ in config = mkIf cfg.enable { assertions = [ + { assertion = xcfg.enable; + message = '' + SDDM requires services.xserver.enable to be true + ''; + } { assertion = cfg.autoLogin.enable -> cfg.autoLogin.user != null; message = '' SDDM auto-login requires services.xserver.displayManager.sddm.autoLogin.user to be set @@ -264,8 +269,8 @@ in }; environment.etc."sddm.conf".source = cfgFile; - environment.pathsToLink = [ - "/share/sddm" + environment.pathsToLink = [ + "/share/sddm" ]; users.groups.sddm.gid = config.ids.gids.sddm; diff --git a/nixos/modules/system/boot/kexec.nix b/nixos/modules/system/boot/kexec.nix index 61f9c6d0e7eb..fd2cb94b756b 100644 --- a/nixos/modules/system/boot/kexec.nix +++ b/nixos/modules/system/boot/kexec.nix @@ -13,8 +13,18 @@ path = [ pkgs.kexectools ]; script = '' + # Don't load the current system profile if we already have a kernel loaded + if [[ 1 = "$(</sys/kernel/kexec_loaded)" ]] ; then + echo "kexec kernel has already been loaded, prepare-kexec skipped" + exit 0 + fi + p=$(readlink -f /nix/var/nix/profiles/system) - if ! [ -d $p ]; then exit 1; fi + if ! [[ -d $p ]]; then + echo "Could not find system profile for prepare-kexec" + exit 1 + fi + echo "Loading NixOS system via kexec." exec kexec --load $p/kernel --initrd=$p/initrd --append="$(cat $p/kernel-params) init=$p/init" ''; }; diff --git a/nixos/modules/virtualisation/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix index 6f7370181740..41bcb909fb5c 100644 --- a/nixos/modules/virtualisation/virtualbox-host.nix +++ b/nixos/modules/virtualisation/virtualbox-host.nix @@ -104,7 +104,7 @@ in "VBoxNetNAT" "VBoxSDL" "VBoxVolInfo" - "VirtualBox" + "VirtualBoxVM" ])); users.groups.vboxusers.gid = config.ids.gids.vboxusers; |