1{
2 lib,
3 config,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.homebox;
9 inherit (lib)
10 mkEnableOption
11 mkPackageOption
12 mkDefault
13 types
14 mkIf
15 ;
16in
17{
18 options.services.homebox = {
19 enable = mkEnableOption "homebox";
20 package = mkPackageOption pkgs "homebox" { };
21 settings = lib.mkOption {
22 type = types.attrsOf types.str;
23 defaultText = lib.literalExpression ''
24 {
25 HBOX_STORAGE_DATA = "/var/lib/homebox/data";
26 HBOX_DATABASE_DRIVER = "sqlite3";
27 HBOX_DATABASE_SQLITE_PATH = "/var/lib/homebox/data/homebox.db?_pragma=busy_timeout=999&_pragma=journal_mode=WAL&_fk=1";
28 HBOX_OPTIONS_ALLOW_REGISTRATION = "false";
29 HBOX_OPTIONS_CHECK_GITHUB_RELEASE = "false";
30 HBOX_MODE = "production";
31 }
32 '';
33 description = ''
34 The homebox configuration as Environment variables. For definitions and available options see the upstream
35 [documentation](https://homebox.software/en/configure-homebox.html).
36 '';
37 };
38 database = {
39 createLocally = lib.mkOption {
40 type = lib.types.bool;
41 default = false;
42 description = ''
43 Configure local PostgreSQL database server for Homebox.
44 '';
45 };
46 };
47 };
48
49 config = mkIf cfg.enable {
50 users.users.homebox = {
51 isSystemUser = true;
52 group = "homebox";
53 };
54 users.groups.homebox = { };
55 services.homebox.settings = lib.mkMerge [
56 (lib.mapAttrs (_: mkDefault) {
57 HBOX_STORAGE_DATA = "/var/lib/homebox/data";
58 HBOX_DATABASE_DRIVER = "sqlite3";
59 HBOX_DATABASE_SQLITE_PATH = "/var/lib/homebox/data/homebox.db?_pragma=busy_timeout=999&_pragma=journal_mode=WAL&_fk=1";
60 HBOX_OPTIONS_ALLOW_REGISTRATION = "false";
61 HBOX_OPTIONS_CHECK_GITHUB_RELEASE = "false";
62 HBOX_MODE = "production";
63 })
64
65 (lib.mkIf cfg.database.createLocally {
66 HBOX_DATABASE_DRIVER = "postgres";
67 HBOX_DATABASE_HOST = "/run/postgresql";
68 HBOX_DATABASE_USERNAME = "homebox";
69 HBOX_DATABASE_DATABASE = "homebox";
70 HBOX_DATABASE_PORT = toString config.services.postgresql.settings.port;
71 })
72 ];
73 services.postgresql = lib.mkIf cfg.database.createLocally {
74 enable = true;
75 ensureDatabases = [ "homebox" ];
76 ensureUsers = [
77 {
78 name = "homebox";
79 ensureDBOwnership = true;
80 }
81 ];
82 };
83 systemd.services.homebox = {
84 requires = lib.optional cfg.database.createLocally "postgresql.service";
85 after = lib.optional cfg.database.createLocally "postgresql.service";
86 environment = cfg.settings;
87 serviceConfig = {
88 User = "homebox";
89 Group = "homebox";
90 ExecStart = lib.getExe cfg.package;
91 StateDirectory = "homebox";
92 WorkingDirectory = "/var/lib/homebox";
93 LimitNOFILE = "1048576";
94 PrivateTmp = true;
95 PrivateDevices = true;
96 StateDirectoryMode = "0700";
97 Restart = "always";
98
99 # Hardening
100 CapabilityBoundingSet = "";
101 LockPersonality = true;
102 MemoryDenyWriteExecute = true;
103 PrivateUsers = true;
104 ProtectClock = true;
105 ProtectControlGroups = true;
106 ProtectHome = true;
107 ProtectHostname = true;
108 ProtectKernelLogs = true;
109 ProtectKernelModules = true;
110 ProtectKernelTunables = true;
111 ProtectProc = "invisible";
112 ProcSubset = "pid";
113 ProtectSystem = "strict";
114 RestrictAddressFamilies = [
115 "AF_UNIX"
116 "AF_INET"
117 "AF_INET6"
118 "AF_NETLINK"
119 ];
120 RestrictNamespaces = true;
121 RestrictRealtime = true;
122 SystemCallArchitectures = "native";
123 SystemCallFilter = [
124 "@system-service"
125 "@pkey"
126 ];
127 RestrictSUIDSGID = true;
128 PrivateMounts = true;
129 UMask = "0077";
130 };
131 wantedBy = [ "multi-user.target" ];
132 };
133 };
134 meta.maintainers = with lib.maintainers; [ patrickdag ];
135}