diff options
Diffstat (limited to 'nixos/modules/services/monitoring')
7 files changed, 269 insertions, 8 deletions
diff --git a/nixos/modules/services/monitoring/mackerel-agent.nix b/nixos/modules/services/monitoring/mackerel-agent.nix index 62a7858500f24..5915634ed26fe 100644 --- a/nixos/modules/services/monitoring/mackerel-agent.nix +++ b/nixos/modules/services/monitoring/mackerel-agent.nix @@ -84,6 +84,7 @@ in { # upstream service file in https://git.io/JUt4Q systemd.services.mackerel-agent = { description = "mackerel.io agent"; + wants = [ "network-online.target" ]; after = [ "network-online.target" "nss-lookup.target" ]; wantedBy = [ "multi-user.target" ]; environment = { diff --git a/nixos/modules/services/monitoring/prometheus/alertmanager.nix b/nixos/modules/services/monitoring/prometheus/alertmanager.nix index 4fd630015f35a..bb426d8b7beb0 100644 --- a/nixos/modules/services/monitoring/prometheus/alertmanager.nix +++ b/nixos/modules/services/monitoring/prometheus/alertmanager.nix @@ -174,6 +174,7 @@ in { systemd.services.alertmanager = { wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; after = [ "network-online.target" ]; preStart = '' ${lib.getBin pkgs.envsubst}/bin/envsubst -o "/tmp/alert-manager-substituted.yaml" \ diff --git a/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix b/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix index edc6e4b5022a5..840ce493ee812 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix @@ -4,6 +4,25 @@ with lib; let cfg = config.services.prometheus.exporters.snmp; + + # This ensures that we can deal with string paths, path types and + # store-path strings with context. + coerceConfigFile = file: + if (builtins.isPath file) || (lib.isStorePath file) then + file + else + (lib.warn '' + ${logPrefix}: configuration file "${file}" is being copied to the nix-store. + If you would like to avoid that, please set enableConfigCheck to false. + '' /. + file); + + checkConfig = file: + pkgs.runCommandLocal "checked-snmp-exporter-config.yml" { + nativeBuildInputs = [ pkgs.buildPackages.prometheus-snmp-exporter ]; + } '' + ln -s ${coerceConfigFile file} $out + snmp_exporter --dry-run --config.file $out + ''; in { port = 9116; @@ -24,15 +43,23 @@ in Snmp exporter configuration as nix attribute set. Mutually exclusive with 'configurationPath' option. ''; example = { - "default" = { - "version" = 2; - "auth" = { - "community" = "public"; - }; + auths.public_v2 = { + community = "public"; + version = 2; }; }; }; + enableConfigCheck = mkOption { + type = types.bool; + default = true; + description = lib.mdDoc '' + Whether to run a correctness check for the configuration file. This depends + on the configuration file residing in the nix-store. Paths passed as string will + be copied to the store. + ''; + }; + logFormat = mkOption { type = types.enum ["logfmt" "json"]; default = "logfmt"; @@ -50,9 +77,13 @@ in }; }; serviceOpts = let - configFile = if cfg.configurationPath != null - then cfg.configurationPath - else "${pkgs.writeText "snmp-exporter-conf.yml" (builtins.toJSON cfg.configuration)}"; + uncheckedConfigFile = if cfg.configurationPath != null + then cfg.configurationPath + else "${pkgs.writeText "snmp-exporter-conf.yml" (builtins.toJSON cfg.configuration)}"; + configFile = if cfg.enableConfigCheck then + checkConfig uncheckedConfigFile + else + uncheckedConfigFile; in { serviceConfig = { ExecStart = '' diff --git a/nixos/modules/services/monitoring/rustdesk-server.nix b/nixos/modules/services/monitoring/rustdesk-server.nix new file mode 100644 index 0000000000000..0a6a8e71672fd --- /dev/null +++ b/nixos/modules/services/monitoring/rustdesk-server.nix @@ -0,0 +1,95 @@ +{ lib, pkgs, config, ... }: +let + TCPPorts = [21115 21116 21117 21118 21119]; + UDPPorts = [21116]; +in { + options.services.rustdesk-server = with lib; with types; { + enable = mkEnableOption "RustDesk, a remote access and remote control software, allowing maintenance of computers and other devices."; + + package = mkPackageOption pkgs "rustdesk-server" {}; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = '' + Open the connection ports. + TCP (${lib.concatStringsSep ", " (map toString TCPPorts)}) + UDP (${lib.concatStringsSep ", " (map toString UDPPorts)}) + ''; + }; + + relayIP = mkOption { + type = str; + description = '' + The public facing IP of the RustDesk relay. + ''; + }; + }; + + config = let + cfg = config.services.rustdesk-server; + serviceDefaults = { + enable = true; + requiredBy = [ "rustdesk.target" ]; + serviceConfig = { + Slice = "system-rustdesk.slice"; + User = "rustdesk"; + Group = "rustdesk"; + Environment = []; + WorkingDirectory = "/var/lib/rustdesk"; + StateDirectory = "rustdesk"; + StateDirectoryMode = "0750"; + LockPersonality = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateMounts = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RemoveIPC = true; + RestrictNamespaces = true; + RestrictSUIDSGID = true; + }; + }; + in lib.mkIf cfg.enable { + users.users.rustdesk = { + description = "System user for RustDesk"; + isSystemUser = true; + group = "rustdesk"; + }; + users.groups.rustdesk = {}; + + networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall TCPPorts; + networking.firewall.allowedUDPPorts = lib.mkIf cfg.openFirewall UDPPorts; + + systemd.slices.system-rustdesk = { + enable = true; + description = "Slice designed to contain RustDesk Signal & RustDesk Relay"; + }; + + systemd.targets.rustdesk = { + enable = true; + description = "Target designed to group RustDesk Signal & RustDesk Relay"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + }; + + systemd.services.rustdesk-signal = lib.mkMerge [ serviceDefaults { + serviceConfig.ExecStart = "${cfg.package}/bin/hbbs -r ${cfg.relayIP}"; + } ]; + + systemd.services.rustdesk-relay = lib.mkMerge [ serviceDefaults { + serviceConfig.ExecStart = "${cfg.package}/bin/hbbr"; + } ]; + }; + + meta.maintainers = with lib.maintainers; [ ppom ]; +} diff --git a/nixos/modules/services/monitoring/teamviewer.nix b/nixos/modules/services/monitoring/teamviewer.nix index 9b1278317943d..7c45247aa6d5a 100644 --- a/nixos/modules/services/monitoring/teamviewer.nix +++ b/nixos/modules/services/monitoring/teamviewer.nix @@ -30,6 +30,7 @@ in description = "TeamViewer remote control daemon"; wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; after = [ "network-online.target" "network.target" "dbus.service" ]; requires = [ "dbus.service" ]; preStart = "mkdir -pv /var/lib/teamviewer /var/log/teamviewer"; diff --git a/nixos/modules/services/monitoring/telegraf.nix b/nixos/modules/services/monitoring/telegraf.nix index ee28ee03adf33..3bab8aba7bd60 100644 --- a/nixos/modules/services/monitoring/telegraf.nix +++ b/nixos/modules/services/monitoring/telegraf.nix @@ -59,6 +59,7 @@ in { in { description = "Telegraf Agent"; wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; after = [ "network-online.target" ]; path = lib.optional (config.services.telegraf.extraConfig.inputs ? procstat) pkgs.procps; serviceConfig = { diff --git a/nixos/modules/services/monitoring/watchdogd.nix b/nixos/modules/services/monitoring/watchdogd.nix new file mode 100644 index 0000000000000..e8d104651c6ad --- /dev/null +++ b/nixos/modules/services/monitoring/watchdogd.nix @@ -0,0 +1,131 @@ +{ config, lib, pkgs, ... }: +with lib; +let + cfg = config.services.watchdogd; + + mkPluginOpts = plugin: defWarn: defCrit: { + enabled = mkEnableOption "watchdogd plugin ${plugin}"; + interval = mkOption { + type = types.ints.unsigned; + default = 300; + description = '' + Amount of seconds between every poll. + ''; + }; + logmark = mkOption { + type = types.bool; + default = false; + description = '' + Whether to log current stats every poll interval. + ''; + }; + warning = mkOption { + type = types.numbers.nonnegative; + default = defWarn; + description = '' + The high watermark level. Alert sent to log. + ''; + }; + critical = mkOption { + type = types.numbers.nonnegative; + default = defCrit; + description = '' + The critical watermark level. Alert sent to log, followed by reboot or script action. + ''; + }; + }; +in { + options.services.watchdogd = { + enable = mkEnableOption "watchdogd, an advanced system & process supervisor"; + package = mkPackageOption pkgs "watchdogd" { }; + + settings = mkOption { + type = with types; submodule { + freeformType = let + valueType = oneOf [ + bool + int + float + str + ]; + in attrsOf (either valueType (attrsOf valueType)); + + options = { + timeout = mkOption { + type = types.ints.unsigned; + default = 15; + description = '' + The WDT timeout before reset. + ''; + }; + interval = mkOption { + type = types.ints.unsigned; + default = 5; + description = '' + The kick interval, i.e. how often {manpage}`watchdogd(8)` should reset the WDT timer. + ''; + }; + + safe-exit = mkOption { + type = types.bool; + default = true; + description = '' + With {var}`safeExit` enabled, the daemon will ask the driver to disable the WDT before exiting. + However, some WDT drivers (or hardware) may not support this. + ''; + }; + + filenr = mkPluginOpts "filenr" 0.9 1.0; + + loadavg = mkPluginOpts "loadavg" 1.0 2.0; + + meminfo = mkPluginOpts "meminfo" 0.9 0.95; + }; + }; + default = { }; + description = '' + Configuration to put in {file}`watchdogd.conf`. + See {manpage}`watchdogd.conf(5)` for more details. + ''; + }; + }; + + config = let + toConfig = attrs: concatStringsSep "\n" (mapAttrsToList toValue attrs); + + toValue = name: value: + if isAttrs value + then pipe value [ + (mapAttrsToList toValue) + (map (s: " ${s}")) + (concatStringsSep "\n") + (s: "${name} {\n${s}\n}") + ] + else if isBool value + then "${name} = ${boolToString value}" + else if any (f: f value) [isString isInt isFloat] + then "${name} = ${toString value}" + else throw '' + Found invalid type in `services.watchdogd.settings`: '${typeOf value}' + ''; + + watchdogdConf = pkgs.writeText "watchdogd.conf" (toConfig cfg.settings); + in mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + + systemd.services.watchdogd = { + documentation = [ + "man:watchdogd(8)" + "man:watchdogd.conf(5)" + ]; + wantedBy = [ "multi-user.target" ]; + description = "Advanced system & process supervisor"; + serviceConfig = { + Type = "simple"; + ExecStart = "${cfg.package}/bin/watchdogd -n -f ${watchdogdConf}"; + }; + }; + }; + + meta.maintainers = with maintainers; [ vifino ]; +} |