From 3887e64f581cc100ca5c5ae6aebbea5baf503d6d Mon Sep 17 00:00:00 2001 From: Lukas Wurzinger Date: Mon, 19 May 2025 17:43:46 +0200 Subject: [PATCH] stuff --- hosts/abacus/filebrowser.nix | 25 +++++ modules/filebrowser.nix | 191 +++++++++++++++++++++++++++++++++++ 2 files changed, 216 insertions(+) create mode 100644 hosts/abacus/filebrowser.nix create mode 100644 modules/filebrowser.nix diff --git a/hosts/abacus/filebrowser.nix b/hosts/abacus/filebrowser.nix new file mode 100644 index 0000000..54555a1 --- /dev/null +++ b/hosts/abacus/filebrowser.nix @@ -0,0 +1,25 @@ +{config, ...}: let + virtualHostName = "filebrowser.helveticanonstandard.net"; + cfg = config.services.filebrowser; +in{ + services.filebrowser = { + enable = true; + settings = { + address = "localhost"; + port = 8090; + database = "/var/lib/filebrowser/filebrowser.db"; + }; + }; + + services.nginx.virtualHosts.${virtualHostName} = { + enableACME = true; + forceSSL = true; + + locations."/".proxyPass = + let + host = cfg.settings.address; + port = builtins.toString cfg.settings.port; + in + "http://${host}:${port}"; + }; +} diff --git a/modules/filebrowser.nix b/modules/filebrowser.nix new file mode 100644 index 0000000..7779ec8 --- /dev/null +++ b/modules/filebrowser.nix @@ -0,0 +1,191 @@ +{ + config, + pkgs, + lib, + utils, + ... +}: +let + cfg = config.services.filebrowser; + inherit (lib) types; + format = pkgs.formats.json { }; + defaultUser = "filebrowser"; + defaultGroup = "filebrowser"; +in +{ + options = { + services.filebrowser = { + enable = lib.mkEnableOption "FileBrowser"; + + package = lib.mkPackageOption pkgs "filebrowser" { }; + + user = lib.mkOption { + type = types.str; + default = defaultUser; + description = '' + The name of the user account under which FileBrowser should run. + ''; + }; + + group = lib.mkOption { + type = types.str; + default = defaultGroup; + description = '' + The name of the user group under which FileBrowser should run. + ''; + }; + + openFirewall = lib.mkOption { + default = false; + description = '' + Whether to automatically open the ports for FileBrowser in the firewall. + ''; + type = types.bool; + }; + + storage = lib.mkOption { + default = "${cfg.settings.root}/data"; + defaultText = lib.literalExpression '' + "''${config.services.filebrowser.settings.root}/data" + ''; + description = '' + The directory where FileBrowser stores files. + ''; + type = types.path; + }; + + settings = lib.mkOption { + default = { }; + description = '' + Settings for FileBrowser. + Refer to for all supported values. + ''; + type = types.submodule { + freeformType = format.type; + options = { + address = lib.mkOption { + default = "localhost"; + description = '' + The address to listen on. + ''; + type = types.str; + }; + + port = lib.mkOption { + default = 8080; + description = '' + The port to listen on. + ''; + type = types.port; + }; + + root = lib.mkOption { + default = "/var/lib/filebrowser"; + description = '' + The directory where FileBrowser stores its state. + ''; + type = types.path; + }; + + database = lib.mkOption { + default = "${cfg.settings.root}/database.db"; + defaultText = lib.literalExpression '' + "''${config.services.filebrowser.settings.root}/database.db" + ''; + description = '' + The path to FileBrowser's database. + ''; + type = types.path; + }; + + cache-dir = lib.mkOption { + default = null; + description = '' + The directory where FileBrowser stores its cache. + ''; + type = types.nullOr types.path; + }; + }; + }; + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd = { + services.filebrowser = { + after = [ "network.target" ]; + description = "FileBrowser"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = + let + args = [ + (lib.getExe cfg.package) + "--config" + (format.generate "config.json" cfg.settings) + ]; + in + utils.escapeSystemdExecArgs args; + + StateDirectory = cfg.settings.root; + WorkingDirectory = cfg.storage; + + User = cfg.user; + Group = cfg.group; + + NoNewPrivileges = true; + PrivateDevices = true; + ProtectSystem = "full"; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + MemoryDenyWriteExecute = true; + LockPersonality = true; + RestrictAddressFamilies = [ + "AF_UNIX" + "AF_INET" + "AF_INET6" + ]; + PrivateTmp = true; + DevicePolicy = "closed"; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + }; + }; + + tmpfiles.settings.filebrowser = + lib.genAttrs + ( + [ + cfg.settings.root + cfg.storage + (builtins.dirOf cfg.settings.database) + ] + ++ (lib.optional (cfg.settings.cache-dir != null) cfg.settings.cache-dir) + ) + (_: { + d = { + inherit (cfg) user group; + mode = "0700"; + }; + }); + }; + + networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.settings.port ]; + + users = { + users.${cfg.user} = lib.mkIf (cfg.user == defaultUser) { + home = cfg.storage; + group = cfg.group; + isSystemUser = true; + }; + groups.${cfg.group} = lib.mkIf (cfg.group == defaultGroup) { }; + }; + }; + + meta.maintainers = [ + lib.maintainers.lukaswrz + ]; +}