# Nagios system/network monitoring daemon. { config, lib, pkgs, ... }: with lib; let cfg = config.services.nagios; nagiosState = "/var/lib/nagios"; nagiosLogDir = "/var/log/nagios"; urlPath = "/nagios"; nagiosObjectDefs = cfg.objectDefs; nagiosObjectDefsDir = pkgs.runCommand "nagios-objects" { inherit nagiosObjectDefs; preferLocalBuild = true; } "mkdir -p $out; ln -s $nagiosObjectDefs $out/"; nagiosCfgFile = let default = { log_file="${nagiosLogDir}/current"; log_archive_path="${nagiosLogDir}/archive"; status_file="${nagiosState}/status.dat"; object_cache_file="${nagiosState}/objects.cache"; temp_file="${nagiosState}/nagios.tmp"; lock_file="/run/nagios.lock"; state_retention_file="${nagiosState}/retention.dat"; query_socket="${nagiosState}/nagios.qh"; check_result_path="${nagiosState}"; command_file="${nagiosState}/nagios.cmd"; cfg_dir="${nagiosObjectDefsDir}"; nagios_user="nagios"; nagios_group="nagios"; illegal_macro_output_chars="`~$&|'\"<>"; retain_state_information="1"; }; lines = mapAttrsToList (key: value: "${key}=${value}") (default // cfg.extraConfig); content = concatStringsSep "\n" lines; file = pkgs.writeText "nagios.cfg" content; validated = pkgs.runCommand "nagios-checked.cfg" {preferLocalBuild=true;} '' cp ${file} nagios.cfg # nagios checks the existence of /var/lib/nagios, but # it does not exists in the build sandbox, so we fake it mkdir lib lib=$(readlink -f lib) sed -i s@=${nagiosState}@=$lib@ nagios.cfg ${pkgs.nagios}/bin/nagios -v nagios.cfg && cp ${file} $out ''; defaultCfgFile = if cfg.validateConfig then validated else file; in if cfg.mainConfigFile == null then defaultCfgFile else cfg.mainConfigFile; # Plain configuration for the Nagios web-interface with no # authentication. nagiosCGICfgFile = pkgs.writeText "nagios.cgi.conf" '' main_config_file=${cfg.mainConfigFile} use_authentication=0 url_html_path=${urlPath} ''; extraHttpdConfig = '' ScriptAlias ${urlPath}/cgi-bin ${pkgs.nagios}/sbin Options ExecCGI Require all granted SetEnv NAGIOS_CGI_CONFIG ${cfg.cgiConfigFile} Alias ${urlPath} ${pkgs.nagios}/share Options None Require all granted ''; in { imports = [ (mkRemovedOptionModule [ "services" "nagios" "urlPath" ] "The urlPath option has been removed as it is hard coded to /nagios in the nagios package.") ]; meta.maintainers = with lib.maintainers; [ symphorien ]; options = { services.nagios = { enable = mkEnableOption "Nagios to monitor your system or network."; objectDefs = mkOption { description = " A list of Nagios object configuration files that must define the hosts, host groups, services and contacts for the network that you want Nagios to monitor. "; type = types.listOf types.path; example = literalExample "[ ./objects.cfg ]"; }; plugins = mkOption { type = types.listOf types.package; default = with pkgs; [ nagiosPluginsOfficial ssmtp mailutils ]; defaultText = "[pkgs.nagiosPluginsOfficial pkgs.ssmtp pkgs.mailutils]"; description = " Packages to be added to the Nagios PATH. Typically used to add plugins, but can be anything. "; }; mainConfigFile = mkOption { type = types.nullOr types.package; default = null; description = " If non-null, overrides the main configuration file of Nagios. "; }; extraConfig = mkOption { type = types.attrsOf types.str; example = { debug_level = "-1"; debug_file = "/var/log/nagios/debug.log"; }; default = {}; description = "Configuration to add to /etc/nagios.cfg"; }; validateConfig = mkOption { type = types.bool; default = pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform; description = "if true, the syntax of the nagios configuration file is checked at build time"; }; cgiConfigFile = mkOption { type = types.package; default = nagiosCGICfgFile; defaultText = "nagiosCGICfgFile"; description = " Derivation for the configuration file of Nagios CGI scripts that can be used in web servers for running the Nagios web interface. "; }; enableWebInterface = mkOption { type = types.bool; default = false; description = " Whether to enable the Nagios web interface. You should also enable Apache (). "; }; virtualHost = mkOption { type = types.submodule (import ../web-servers/apache-httpd/vhost-options.nix); example = literalExample '' { hostName = "example.org"; adminAddr = "webmaster@example.org"; enableSSL = true; sslServerCert = "/var/lib/acme/example.org/full.pem"; sslServerKey = "/var/lib/acme/example.org/key.pem"; } ''; description = '' Apache configuration can be done by adapting . See for further information. ''; }; }; }; config = mkIf cfg.enable { users.users.nagios = { description = "Nagios user "; uid = config.ids.uids.nagios; home = nagiosState; group = "nagios"; }; users.groups.nagios = { }; # This isn't needed, it's just so that the user can type "nagiostats # -c /etc/nagios.cfg". environment.etc."nagios.cfg".source = nagiosCfgFile; environment.systemPackages = [ pkgs.nagios ]; systemd.services.nagios = { description = "Nagios monitoring daemon"; path = [ pkgs.nagios ] ++ cfg.plugins; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { User = "nagios"; Group = "nagios"; Restart = "always"; RestartSec = 2; LogsDirectory = "nagios"; StateDirectory = "nagios"; ExecStart = "${pkgs.nagios}/bin/nagios /etc/nagios.cfg"; X-ReloadIfChanged = nagiosCfgFile; }; }; services.httpd.virtualHosts = optionalAttrs cfg.enableWebInterface { ${cfg.virtualHost.hostName} = mkMerge [ cfg.virtualHost { extraConfig = extraHttpdConfig; } ]; }; }; }