lol

nixos/legit: init

authored by

Victor Freire and committed by
Anderson Torres
77520d39 3e5995d7

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