at 25.11-pre 4.0 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.centrifugo; 9 10 settingsFormat = pkgs.formats.json { }; 11 12 configFile = settingsFormat.generate "centrifugo.json" cfg.settings; 13in 14{ 15 options.services.centrifugo = { 16 enable = lib.mkEnableOption "Centrifugo messaging server"; 17 18 package = lib.mkPackageOption pkgs "centrifugo" { }; 19 20 settings = lib.mkOption { 21 type = settingsFormat.type; 22 default = { }; 23 description = '' 24 Declarative Centrifugo configuration. See the [Centrifugo 25 documentation] for a list of options. 26 27 [Centrifugo documentation]: https://centrifugal.dev/docs/server/configuration 28 ''; 29 }; 30 31 credentials = lib.mkOption { 32 type = lib.types.attrsOf lib.types.path; 33 default = { }; 34 example = { 35 CENTRIFUGO_UNI_GRPC_TLS_KEY = "/run/keys/centrifugo-uni-grpc-tls.key"; 36 }; 37 description = '' 38 Environment variables with absolute paths to credentials files to load 39 on service startup. 40 ''; 41 }; 42 43 environmentFiles = lib.mkOption { 44 type = lib.types.listOf lib.types.path; 45 default = [ ]; 46 description = '' 47 Files to load environment variables from. Options set via environment 48 variables take precedence over {option}`settings`. 49 50 See the [Centrifugo documentation] for the environment variable name 51 format. 52 53 [Centrifugo documentation]: https://centrifugal.dev/docs/server/configuration#os-environment-variables 54 ''; 55 }; 56 57 extraGroups = lib.mkOption { 58 type = lib.types.listOf lib.types.str; 59 default = [ ]; 60 example = [ "redis-centrifugo" ]; 61 description = '' 62 Additional groups for the systemd service. 63 ''; 64 }; 65 }; 66 67 config = lib.mkIf cfg.enable { 68 assertions = [ 69 { 70 assertion = 71 (lib.versionAtLeast cfg.package.version "6") -> (!(cfg.settings ? name) && !(cfg.settings ? port)); 72 message = "`services.centrifugo.settings` is v5 config, must be compatible with centrifugo v6 config format"; 73 } 74 ]; 75 76 systemd.services.centrifugo = { 77 description = "Centrifugo messaging server"; 78 wantedBy = [ "multi-user.target" ]; 79 after = [ "network.target" ]; 80 81 serviceConfig = { 82 Type = "exec"; 83 84 ExecStartPre = "${lib.getExe cfg.package} checkconfig --config ${configFile}"; 85 ExecStart = "${lib.getExe cfg.package} --config ${configFile}"; 86 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 87 88 Restart = "always"; 89 RestartSec = "1s"; 90 91 # Copy files to the credentials directory with file name being the 92 # environment variable name. Note that "%d" specifier expands to the 93 # path of the credentials directory. 94 LoadCredential = lib.mapAttrsToList (name: value: "${name}:${value}") cfg.credentials; 95 Environment = lib.mapAttrsToList (name: _: "${name}=%d/${name}") cfg.credentials; 96 97 EnvironmentFile = cfg.environmentFiles; 98 99 SupplementaryGroups = cfg.extraGroups; 100 101 DynamicUser = true; 102 UMask = "0077"; 103 104 ProtectHome = true; 105 ProtectProc = "invisible"; 106 ProcSubset = "pid"; 107 ProtectClock = true; 108 ProtectHostname = true; 109 ProtectControlGroups = true; 110 ProtectKernelLogs = true; 111 ProtectKernelModules = true; 112 ProtectKernelTunables = true; 113 PrivateUsers = true; 114 PrivateDevices = true; 115 RestrictRealtime = true; 116 RestrictNamespaces = true; 117 RestrictAddressFamilies = [ 118 "AF_INET" 119 "AF_INET6" 120 "AF_UNIX" 121 ]; 122 DeviceAllow = [ "" ]; 123 DevicePolicy = "closed"; 124 CapabilityBoundingSet = [ "" ]; 125 MemoryDenyWriteExecute = true; 126 LockPersonality = true; 127 SystemCallArchitectures = "native"; 128 SystemCallErrorNumber = "EPERM"; 129 SystemCallFilter = [ 130 "@system-service" 131 "~@privileged" 132 ]; 133 }; 134 }; 135 }; 136}