vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / networking / legit.nix
blob412f8275800b7df253abed1327e367b32f8f4954
1 { config, lib, pkgs, ... }:
3 let
4   inherit (lib)
5     literalExpression
6     mkEnableOption
7     mkIf
8     mkOption
9     mkPackageOption
10     optionalAttrs
11     optional
12     types;
14   cfg = config.services.legit;
16   yaml = pkgs.formats.yaml { };
17   configFile = yaml.generate "legit.yaml" cfg.settings;
19   defaultStateDir = "/var/lib/legit";
20   defaultStaticDir = "${cfg.settings.repo.scanPath}/static";
21   defaultTemplatesDir = "${cfg.settings.repo.scanPath}/templates";
24   options.services.legit = {
25     enable = mkEnableOption "legit git web frontend";
27     package = mkPackageOption pkgs "legit-web" { };
29     user = mkOption {
30       type = types.str;
31       default = "legit";
32       description = "User account under which legit runs.";
33     };
35     group = mkOption {
36       type = types.str;
37       default = "legit";
38       description = "Group account under which legit runs.";
39     };
41     settings = mkOption {
42       default = { };
43       description = ''
44         The primary legit configuration. See the
45         [sample configuration](https://github.com/icyphox/legit/blob/master/config.yaml)
46         for possible values.
47       '';
48       type = types.submodule {
49         options.repo = {
50           scanPath = mkOption {
51             type = types.path;
52             default = defaultStateDir;
53             description = "Directory where legit will scan for repositories.";
54           };
55           readme = mkOption {
56             type = types.listOf types.str;
57             default = [ ];
58             description = "Readme files to look for.";
59           };
60           mainBranch = mkOption {
61             type = types.listOf types.str;
62             default = [ "main" "master" ];
63             description = "Main branch to look for.";
64           };
65           ignore = mkOption {
66             type = types.listOf types.str;
67             default = [ ];
68             description = "Repositories to ignore.";
69           };
70         };
71         options.dirs = {
72           templates = mkOption {
73             type = types.path;
74             default = "${pkgs.legit-web}/lib/legit/templates";
75             defaultText = literalExpression ''"''${pkgs.legit-web}/lib/legit/templates"'';
76             description = "Directories where template files are located.";
77           };
78           static = mkOption {
79             type = types.path;
80             default = "${pkgs.legit-web}/lib/legit/static";
81             defaultText = literalExpression ''"''${pkgs.legit-web}/lib/legit/static"'';
82             description = "Directories where static files are located.";
83           };
84         };
85         options.meta = {
86           title = mkOption {
87             type = types.str;
88             default = "legit";
89             description = "Website title.";
90           };
91           description = mkOption {
92             type = types.str;
93             default = "git frontend";
94             description = "Website description.";
95           };
96         };
97         options.server = {
98           name = mkOption {
99             type = types.str;
100             default = "localhost";
101             description = "Server name.";
102           };
103           host = mkOption {
104             type = types.str;
105             default = "127.0.0.1";
106             description = "Host address.";
107           };
108           port = mkOption {
109             type = types.port;
110             default = 5555;
111             description = "Legit port.";
112           };
113         };
114       };
115     };
116   };
118   config = mkIf cfg.enable {
119     users.groups = optionalAttrs (cfg.group == "legit") {
120       "${cfg.group}" = { };
121     };
123     users.users = optionalAttrs (cfg.user == "legit") {
124       "${cfg.user}" = {
125         group = cfg.group;
126         isSystemUser = true;
127       };
128     };
130     systemd.services.legit = {
131       description = "legit git frontend";
133       after = [ "network.target" ];
134       wantedBy = [ "multi-user.target" ];
135       restartTriggers = [ configFile ];
137       serviceConfig = {
138         Type = "simple";
139         User = cfg.user;
140         Group = cfg.group;
141         ExecStart = "${cfg.package}/bin/legit -config ${configFile}";
142         Restart = "always";
144         WorkingDirectory = cfg.settings.repo.scanPath;
145         StateDirectory = [ ] ++
146           optional (cfg.settings.repo.scanPath == defaultStateDir) "legit" ++
147           optional (cfg.settings.dirs.static == defaultStaticDir) "legit/static" ++
148           optional (cfg.settings.dirs.templates == defaultTemplatesDir) "legit/templates";
150         # Hardening
151         CapabilityBoundingSet = [ "" ];
152         DeviceAllow = [ "" ];
153         LockPersonality = true;
154         MemoryDenyWriteExecute = true;
155         NoNewPrivileges = true;
156         PrivateDevices = true;
157         PrivateTmp = true;
158         PrivateUsers = true;
159         ProcSubset = "pid";
160         ProtectClock = true;
161         ProtectControlGroups = true;
162         ProtectHome = true;
163         ProtectHostname = true;
164         ProtectKernelLogs = true;
165         ProtectKernelModules = true;
166         ProtectKernelTunables = true;
167         ProtectProc = "invisible";
168         ProtectSystem = "strict";
169         ReadWritePaths = cfg.settings.repo.scanPath;
170         RemoveIPC = true;
171         RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
172         RestrictNamespaces = true;
173         RestrictRealtime = true;
174         RestrictSUIDSGID = true;
175         SystemCallArchitectures = "native";
176         SystemCallFilter = [ "@system-service" "~@privileged" ];
177         UMask = "0077";
178       };
179     };
180   };