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