···
cfg = config.services.nezha-agent;
10
+
# nezha-agent uses yaml as the configuration file format.
11
+
# Since we need to use jq to update the content, so here we generate json
12
+
settingsFormat = pkgs.formats.json { };
13
+
configFile = settingsFormat.generate "config.json" cfg.settings;
···
enable = lib.mkEnableOption "Agent of Nezha Monitoring";
package = lib.mkPackageOption pkgs "nezha-agent" { };
debug = lib.mkEnableOption "verbose log";
20
-
tls = lib.mkOption {
21
-
type = lib.types.bool;
27
+
settings = lib.mkOption {
24
-
Enable SSL/TLS encryption.
29
+
Generate to {file}`config.json` as a Nix attribute set.
30
+
Check the [guide](https://nezha.wiki/en_US/guide/agent.html)
31
+
for possible options.
27
-
gpu = lib.mkOption {
28
-
type = lib.types.bool;
31
-
Enable GPU monitoring.
34
-
temperature = lib.mkOption {
35
-
type = lib.types.bool;
38
-
Enable temperature monitoring.
33
+
type = lib.types.submodule {
34
+
freeformType = settingsFormat.type;
37
+
disable_command_execute = lib.mkOption {
38
+
type = lib.types.bool;
41
+
Disable executing the command from dashboard.
44
+
disable_nat = lib.mkOption {
45
+
type = lib.types.bool;
48
+
Disable NAT penetration.
51
+
disable_send_query = lib.mkOption {
52
+
type = lib.types.bool;
55
+
Disable sending TCP/ICMP/HTTP requests.
58
+
gpu = lib.mkOption {
59
+
type = lib.types.bool;
62
+
Enable GPU monitoring.
65
+
tls = lib.mkOption {
66
+
type = lib.types.bool;
69
+
Enable SSL/TLS encryption.
72
+
temperature = lib.mkOption {
73
+
type = lib.types.bool;
76
+
Enable temperature monitoring.
79
+
use_ipv6_country_code = lib.mkOption {
80
+
type = lib.types.bool;
83
+
Use ipv6 countrycode to report location.
86
+
skip_connection_count = lib.mkOption {
87
+
type = lib.types.bool;
90
+
Do not monitor the number of connections.
93
+
skip_procs_count = lib.mkOption {
94
+
type = lib.types.bool;
97
+
Do not monitor the number of processes.
100
+
report_delay = lib.mkOption {
101
+
type = lib.types.enum [
109
+
The interval between system status reportings.
110
+
The value must be an integer from 1 to 4.
113
+
server = lib.mkOption {
114
+
type = lib.types.str;
115
+
example = "127.0.0.1:8008";
117
+
Address to the dashboard.
120
+
uuid = lib.mkOption {
121
+
type = with lib.types; nullOr str;
122
+
# pre-defined uuid of Dns in RFC 4122
123
+
example = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
126
+
Must be set to a unique identifier, preferably a UUID according to
127
+
RFC 4122. UUIDs can be generated with `uuidgen` command, found in
128
+
the `util-linux` package.
130
+
Set {option}`services.nezha-agent.genUuid` to true to generate uuid
131
+
from {option}`networking.fqdn` automatically.
41
-
useIPv6CountryCode = lib.mkOption {
42
-
type = lib.types.bool;
45
-
Use ipv6 countrycode to report location.
48
-
disableCommandExecute = lib.mkOption {
49
-
type = lib.types.bool;
52
-
Disable executing the command from dashboard.
55
-
disableNat = lib.mkOption {
138
+
genUuid = lib.mkOption {
59
-
Disable NAT penetration.
62
-
disableSendQuery = lib.mkOption {
63
-
type = lib.types.bool;
66
-
Disable sending TCP/ICMP/HTTP requests.
69
-
skipConnection = lib.mkOption {
70
-
type = lib.types.bool;
73
-
Do not monitor the number of connections.
76
-
skipProcess = lib.mkOption {
77
-
type = lib.types.bool;
80
-
Do not monitor the number of processes.
83
-
reportDelay = lib.mkOption {
84
-
type = lib.types.enum [
92
-
The interval between system status reportings.
93
-
The value must be an integer from 1 to 4
142
+
Whether to generate uuid from fqdn automatically.
143
+
Please note that changes in hostname/domain will result in different uuid.
96
-
passwordFile = lib.mkOption {
97
-
type = with lib.types; nullOr str;
147
+
clientSecretFile = lib.mkOption {
148
+
type = with lib.types; nullOr path;
100
-
Path to the file contained the password from dashboard.
103
-
server = lib.mkOption {
104
-
type = lib.types.str;
106
-
Address to the dashboard
109
-
extraFlags = lib.mkOption {
110
-
type = lib.types.listOf lib.types.str;
112
-
example = [ "--gpu" ];
114
-
Extra command-line flags passed to nezha-agent.
151
+
Path to the file contained the client_secret of the dashboard.
157
+
imports = with lib; [
158
+
(mkRenamedOptionModule
159
+
[ "services" "nezha-agent" "disableCommandExecute" ]
160
+
[ "services" "nezha-agent" "settings" "disable_command_execute" ]
162
+
(mkRenamedOptionModule
163
+
[ "services" "nezha-agent" "disableNat" ]
164
+
[ "services" "nezha-agent" "settings" "disable_nat" ]
166
+
(mkRenamedOptionModule
167
+
[ "services" "nezha-agent" "disableSendQuery" ]
168
+
[ "services" "nezha-agent" "settings" "disable_send_query" ]
170
+
(mkRenamedOptionModule
171
+
[ "services" "nezha-agent" "gpu" ]
172
+
[ "services" "nezha-agent" "settings" "gpu" ]
174
+
(mkRenamedOptionModule
175
+
[ "services" "nezha-agent" "tls" ]
176
+
[ "services" "nezha-agent" "settings" "tls" ]
178
+
(mkRenamedOptionModule
179
+
[ "services" "nezha-agent" "temperature" ]
180
+
[ "services" "nezha-agent" "settings" "temperature" ]
182
+
(mkRenamedOptionModule
183
+
[ "services" "nezha-agent" "useIPv6CountryCode" ]
184
+
[ "services" "nezha-agent" "settings" "use_ipv6_country_code" ]
186
+
(mkRenamedOptionModule
187
+
[ "services" "nezha-agent" "skipConnection" ]
188
+
[ "services" "nezha-agent" "settings" "skip_connection_count" ]
190
+
(mkRenamedOptionModule
191
+
[ "services" "nezha-agent" "skipProcess" ]
192
+
[ "services" "nezha-agent" "settings" "skip_procs_count" ]
194
+
(mkRenamedOptionModule
195
+
[ "services" "nezha-agent" "reportDelay" ]
196
+
[ "services" "nezha-agent" "settings" "report_delay" ]
198
+
(mkRenamedOptionModule
199
+
[ "services" "nezha-agent" "server" ]
200
+
[ "services" "nezha-agent" "settings" "server" ]
202
+
(lib.mkRemovedOptionModule [ "services" "nezha-agent" "extraFlags" ] ''
203
+
Use `services.nezha-agent.settings` instead.
205
+
Nezha-agent v1 is no longer configured via command line flags.
207
+
(lib.mkRemovedOptionModule [ "services" "nezha-agent" "passwordFile" ] ''
208
+
Use `services.nezha-agent.clientSecretFile` instead.
210
+
Nezha-agent v1 uses the client secret from the dashboard to connect.
config = lib.mkIf cfg.enable {
121
-
systemd.packages = [ cfg.package ];
217
+
assertion = cfg.settings.uuid == null -> cfg.genUuid;
218
+
message = "Please set `service.nezha-agent.settings.uuid` while `genUuid` is false.";
221
+
assertion = cfg.settings.uuid != null -> !cfg.genUuid;
222
+
message = "When `service.nezha-agent.genUuid = true`, `settings.uuid` cannot be set.";
226
+
services.nezha-agent.settings = {
228
+
# Automatic updates should never be enabled in NixOS.
229
+
disable_auto_update = true;
230
+
disable_force_update = true;
systemd.services.nezha-agent = {
125
-
ProtectSystem = "full";
235
+
Restart = "on-failure";
236
+
StateDirectory = "nezha-agent";
237
+
RuntimeDirectory = "nezha-agent";
238
+
WorkingDirectory = "/var/lib/nezha-agent";
239
+
ReadWritePaths = "/var/lib/nezha-agent";
241
+
LoadCredential = lib.optionalString (
242
+
cfg.clientSecretFile != null
243
+
) "client-secret:${cfg.clientSecretFile}";
246
+
ProcSubset = "all"; # Needed to get host information
247
+
DynamicUser = true;
249
+
LockPersonality = true;
250
+
ProtectClock = true;
251
+
MemoryDenyWriteExecute = true;
252
+
PrivateUsers = true;
253
+
ProtectHostname = true;
254
+
RestrictSUIDSGID = true;
255
+
AmbientCapabilities = [ ];
256
+
CapabilityBoundingSet = "";
257
+
NoNewPrivileges = true;
259
+
ProtectControlGroups = true;
260
+
ProtectHome = true;
261
+
ProtectKernelLogs = true;
262
+
ProtectKernelModules = true;
263
+
ProtectKernelTunables = true;
264
+
ProtectProc = "invisible";
265
+
ProtectSystem = "strict";
266
+
RestrictNamespaces = true;
267
+
RestrictRealtime = true;
268
+
SystemCallArchitectures = "native";
270
+
SystemCallFilter = [
274
+
RestrictAddressFamilies = [
127
-
PrivateTmp = "yes";
128
-
NoNewPrivileges = true;
130
-
path = [ cfg.package ];
280
+
environment.HOME = "/var/lib/nezha-agent";
281
+
enableStrictShellChecks = true;
startLimitIntervalSec = 10;
133
-
script = lib.concatStringsSep " " (
135
-
"${lib.getExe cfg.package}"
136
-
"--disable-auto-update"
137
-
"--disable-force-update"
138
-
"--password $(cat ${cfg.passwordFile})"
140
-
++ lib.optional cfg.debug "--debug"
141
-
++ lib.optional cfg.disableCommandExecute "--disable-command-execute"
142
-
++ lib.optional cfg.disableNat "--disable-nat"
143
-
++ lib.optional cfg.disableSendQuery "--disable-send-query"
144
-
++ lib.optional (cfg.reportDelay != null) "--report-delay ${toString cfg.reportDelay}"
145
-
++ lib.optional (cfg.server != null) "--server ${cfg.server}"
146
-
++ lib.optional cfg.skipConnection "--skip-conn"
147
-
++ lib.optional cfg.skipProcess "--skip-procs"
148
-
++ lib.optional cfg.tls "--tls"
149
-
++ lib.optional cfg.gpu "--gpu"
150
-
++ lib.optional cfg.temperature "--temperature"
151
-
++ lib.optional cfg.useIPv6CountryCode "--use-ipv6-countrycode"
285
+
cp "${configFile}" "''${RUNTIME_DIRECTORY}"/config.json
286
+
${lib.optionalString (cfg.clientSecretFile != null) ''
287
+
${lib.getExe pkgs.jq} --arg client_secret "$(<"''${CREDENTIALS_DIRECTORY}"/client-secret)" \
288
+
'. + { client_secret: $client_secret }' < "''${RUNTIME_DIRECTORY}"/config.json > "''${RUNTIME_DIRECTORY}"/config.json.tmp
289
+
mv "''${RUNTIME_DIRECTORY}"/config.json.tmp "''${RUNTIME_DIRECTORY}"/config.json
291
+
${lib.optionalString cfg.genUuid ''
292
+
${lib.getExe pkgs.jq} --arg uuid "$(${lib.getExe' pkgs.util-linux "uuidgen"} --md5 -n @dns -N "${config.networking.fqdn}")" \
293
+
'. + { uuid: $uuid }' < "''${RUNTIME_DIRECTORY}"/config.json > "''${RUNTIME_DIRECTORY}"/config.json.tmp
294
+
mv "''${RUNTIME_DIRECTORY}"/config.json.tmp "''${RUNTIME_DIRECTORY}"/config.json
296
+
${lib.getExe cfg.package} --config "''${RUNTIME_DIRECTORY}"/config.json
wantedBy = [ "multi-user.target" ];