From 42a99b1be2955eb007a199f319b3afa47d6da780 Mon Sep 17 00:00:00 2001 From: Izorkin Date: Mon, 25 Feb 2019 17:08:01 +0300 Subject: [PATCH] nixos/unit: init service unit --- nixos/modules/module-list.nix | 1 + .../services/web-servers/unit/default.nix | 125 ++++++++++++++++++ pkgs/servers/http/unit/default.nix | 9 +- pkgs/servers/http/unit/unit-rootless.patch | 24 ++++ 4 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 nixos/modules/services/web-servers/unit/default.nix create mode 100644 pkgs/servers/http/unit/unit-rootless.patch diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 32b3f14e82df..cc0db0b2de66 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -760,6 +760,7 @@ ./services/web-servers/nginx/default.nix ./services/web-servers/nginx/gitweb.nix ./services/web-servers/phpfpm/default.nix + ./services/web-servers/unit/default.nix ./services/web-servers/shellinabox.nix ./services/web-servers/tomcat.nix ./services/web-servers/traefik.nix diff --git a/nixos/modules/services/web-servers/unit/default.nix b/nixos/modules/services/web-servers/unit/default.nix new file mode 100644 index 000000000000..a4a9d370d644 --- /dev/null +++ b/nixos/modules/services/web-servers/unit/default.nix @@ -0,0 +1,125 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.unit; + + configFile = pkgs.writeText "unit.json" cfg.config; + +in { + options = { + services.unit = { + enable = mkEnableOption "Unit App Server"; + package = mkOption { + type = types.package; + default = pkgs.unit; + defaultText = "pkgs.unit"; + description = "Unit package to use."; + }; + user = mkOption { + type = types.str; + default = "unit"; + description = "User account under which unit runs."; + }; + group = mkOption { + type = types.str; + default = "unit"; + description = "Group account under which unit runs."; + }; + stateDir = mkOption { + default = "/var/spool/unit"; + description = "Unit data directory."; + }; + logDir = mkOption { + default = "/var/log/unit"; + description = "Unit log directory."; + }; + config = mkOption { + type = types.str; + default = '' + { + "listeners": {}, + "applications": {} + } + ''; + example = literalExample '' + { + "listeners": { + "*:8300": { + "application": "example-php-72" + } + }, + "applications": { + "example-php-72": { + "type": "php 7.2", + "processes": 4, + "user": "nginx", + "group": "nginx", + "root": "/var/www", + "index": "index.php", + "options": { + "file": "/etc/php.d/default.ini", + "admin": { + "max_execution_time": "30", + "max_input_time": "30", + "display_errors": "off", + "display_startup_errors": "off", + "open_basedir": "/dev/urandom:/proc/cpuinfo:/proc/meminfo:/etc/ssl/certs:/var/www", + "disable_functions": "exec,passthru,shell_exec,system" + } + } + } + } + } + ''; + description = "Unit configuration in JSON format. More details here https://unit.nginx.org/configuration"; + }; + }; + }; + + config = mkIf cfg.enable { + + environment.systemPackages = [ cfg.package ]; + + systemd.tmpfiles.rules = [ + "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -" + "d '${cfg.logDir}' 0750 ${cfg.user} ${cfg.group} - -" + ]; + + systemd.services.unit = { + description = "Unit App Server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = with pkgs; [ curl ]; + preStart = '' + test -f '/run/unit/control.unit.sock' || rm -f '/run/unit/control.unit.sock' + ''; + postStart = '' + curl -X PUT --data-binary '@${configFile}' --unix-socket '/run/unit/control.unit.sock' 'http://localhost/config' + ''; + serviceConfig = { + User = cfg.user; + Group = cfg.group; + AmbientCapabilities = "CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID"; + CapabilityBoundingSet = "CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID"; + ExecStart = '' + ${cfg.package}/bin/unitd --control 'unix:/run/unit/control.unit.sock' --pid '/run/unit/unit.pid' \ + --log '${cfg.logDir}/unit.log' --state '${cfg.stateDir}' --no-daemon \ + --user ${cfg.user} --group ${cfg.group} + ''; + RuntimeDirectory = "unit"; + RuntimeDirectoryMode = "0750"; + }; + }; + + users.users = optionalAttrs (cfg.user == "unit") (singleton { + name = "unit"; + group = cfg.group; + }); + + users.groups = optionalAttrs (cfg.group == "unit") (singleton { + name = "unit"; + }); + }; +} diff --git a/pkgs/servers/http/unit/default.nix b/pkgs/servers/http/unit/default.nix index f250dd5e9bb4..9efc1d64335f 100644 --- a/pkgs/servers/http/unit/default.nix +++ b/pkgs/servers/http/unit/default.nix @@ -40,9 +40,14 @@ stdenv.mkDerivation rec { ++ optional withRuby ruby ++ optional withSSL openssl; + # Used patch to enable work with unprivileged user - https://github.com/nginx/unit/issues/228 + patches = [ ./unit-rootless.patch ]; + configureFlags = [ - "--control=unix:/run/control.unit.sock" - "--pid=/run/unit.pid" + "--control=unix:/run/unit/control.unit.sock" + "--pid=/run/unit/unit.pid" + "--user=unit" + "--group=unit" ] ++ optional withSSL [ "--openssl" ] ++ optional (!withIPv6) [ "--no-ipv6" ] ++ optional withDebug [ "--debug" ]; diff --git a/pkgs/servers/http/unit/unit-rootless.patch b/pkgs/servers/http/unit/unit-rootless.patch new file mode 100644 index 000000000000..36506847f915 --- /dev/null +++ b/pkgs/servers/http/unit/unit-rootless.patch @@ -0,0 +1,24 @@ +diff --git a/src/nxt_process.c b/src/nxt_process.c +index 5952029..7b29369 100644 +--- a/src/nxt_process.c ++++ b/src/nxt_process.c +@@ -136,7 +136,7 @@ nxt_process_start(nxt_task_t *task, nxt_process_t *process) + + nxt_random_init(&thread->random); + +- if (init->user_cred != NULL && getuid() == 0) { ++ if (init->user_cred != NULL) { + /* Super-user. */ + + ret = nxt_user_cred_set(task, init->user_cred); +@@ -434,9 +434,7 @@ nxt_user_cred_get(nxt_task_t *task, nxt_user_cred_t *uc, const char *group) + uc->base_gid = grp->gr_gid; + } + +- if (getuid() == 0) { + return nxt_user_groups_get(task, uc); +- } + + return NXT_OK; + } +