vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / web-servers / unit / default.nix
blob5e7b7be91a15b302d56e28365ba2e31f72089872
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.services.unit;
8   configFile = pkgs.writeText "unit.json" cfg.config;
10 in {
11   options = {
12     services.unit = {
13       enable = mkEnableOption "Unit App Server";
14       package = mkPackageOption pkgs "unit" { };
15       user = mkOption {
16         type = types.str;
17         default = "unit";
18         description = "User account under which unit runs.";
19       };
20       group = mkOption {
21         type = types.str;
22         default = "unit";
23         description = "Group account under which unit runs.";
24       };
25       stateDir = mkOption {
26         type = types.path;
27         default = "/var/spool/unit";
28         description = "Unit data directory.";
29       };
30       logDir = mkOption {
31         type = types.path;
32         default = "/var/log/unit";
33         description = "Unit log directory.";
34       };
35       config = mkOption {
36         type = types.str;
37         default = ''
38           {
39             "listeners": {},
40             "applications": {}
41           }
42         '';
43         example = ''
44           {
45             "listeners": {
46               "*:8300": {
47                 "application": "example-php-72"
48               }
49             },
50             "applications": {
51               "example-php-72": {
52                 "type": "php 7.2",
53                 "processes": 4,
54                 "user": "nginx",
55                 "group": "nginx",
56                 "root": "/var/www",
57                 "index": "index.php",
58                 "options": {
59                   "file": "/etc/php.d/default.ini",
60                   "admin": {
61                     "max_execution_time": "30",
62                     "max_input_time": "30",
63                     "display_errors": "off",
64                     "display_startup_errors": "off",
65                     "open_basedir": "/dev/urandom:/proc/cpuinfo:/proc/meminfo:/etc/ssl/certs:/var/www",
66                     "disable_functions": "exec,passthru,shell_exec,system"
67                   }
68                 }
69               }
70             }
71           }
72         '';
73         description = "Unit configuration in JSON format. More details here https://unit.nginx.org/configuration";
74       };
75     };
76   };
78   config = mkIf cfg.enable {
80     environment.systemPackages = [ cfg.package ];
82     systemd.tmpfiles.rules = [
83       "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -"
84       "d '${cfg.logDir}' 0750 ${cfg.user} ${cfg.group} - -"
85     ];
87     systemd.services.unit = {
88       description = "Unit App Server";
89       after = [ "network.target" ];
90       wantedBy = [ "multi-user.target" ];
91       preStart = ''
92         [ ! -e '${cfg.stateDir}/conf.json' ] || rm -f '${cfg.stateDir}/conf.json'
93       '';
94       postStart = ''
95         ${pkgs.curl}/bin/curl -X PUT --data-binary '@${configFile}' --unix-socket '/run/unit/control.unit.sock' 'http://localhost/config'
96       '';
97       serviceConfig = {
98         Type = "forking";
99         PIDFile = "/run/unit/unit.pid";
100         ExecStart = ''
101           ${cfg.package}/bin/unitd --control 'unix:/run/unit/control.unit.sock' --pid '/run/unit/unit.pid' \
102                                    --log '${cfg.logDir}/unit.log' --statedir '${cfg.stateDir}' --tmpdir '/tmp' \
103                                    --user ${cfg.user} --group ${cfg.group}
104         '';
105         ExecStop = ''
106           ${pkgs.curl}/bin/curl -X DELETE --unix-socket '/run/unit/control.unit.sock' 'http://localhost/config'
107         '';
108         # Runtime directory and mode
109         RuntimeDirectory = "unit";
110         RuntimeDirectoryMode = "0750";
111         # Access write directories
112         ReadWritePaths = [ cfg.stateDir cfg.logDir ];
113         # Security
114         NoNewPrivileges = true;
115         # Sandboxing
116         ProtectSystem = "strict";
117         ProtectHome = true;
118         PrivateTmp = true;
119         PrivateDevices = true;
120         PrivateUsers = false;
121         ProtectHostname = true;
122         ProtectClock = true;
123         ProtectKernelTunables = true;
124         ProtectKernelModules = true;
125         ProtectKernelLogs = true;
126         ProtectControlGroups = true;
127         RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
128         LockPersonality = true;
129         MemoryDenyWriteExecute = true;
130         RestrictRealtime = true;
131         RestrictSUIDSGID = true;
132         PrivateMounts = true;
133         # System Call Filtering
134         SystemCallArchitectures = "native";
135       };
136     };
138     users.users = optionalAttrs (cfg.user == "unit") {
139       unit = {
140         group = cfg.group;
141         isSystemUser = true;
142       };
143     };
145     users.groups = optionalAttrs (cfg.group == "unit") {
146       unit = { };
147     };
149   };