1# Nagios system/network monitoring daemon.
2{ config, lib, pkgs, ... }:
3
4with lib;
5
6let
7 cfg = config.services.nagios;
8
9 nagiosState = "/var/lib/nagios";
10 nagiosLogDir = "/var/log/nagios";
11 urlPath = "/nagios";
12
13 nagiosObjectDefs = cfg.objectDefs;
14
15 nagiosObjectDefsDir = pkgs.runCommand "nagios-objects" {
16 inherit nagiosObjectDefs;
17 preferLocalBuild = true;
18 } "mkdir -p $out; ln -s $nagiosObjectDefs $out/";
19
20 nagiosCfgFile = let
21 default = {
22 log_file="${nagiosLogDir}/current";
23 log_archive_path="${nagiosLogDir}/archive";
24 status_file="${nagiosState}/status.dat";
25 object_cache_file="${nagiosState}/objects.cache";
26 temp_file="${nagiosState}/nagios.tmp";
27 lock_file="/run/nagios.lock";
28 state_retention_file="${nagiosState}/retention.dat";
29 query_socket="${nagiosState}/nagios.qh";
30 check_result_path="${nagiosState}";
31 command_file="${nagiosState}/nagios.cmd";
32 cfg_dir="${nagiosObjectDefsDir}";
33 nagios_user="nagios";
34 nagios_group="nagios";
35 illegal_macro_output_chars="`~$&|'\"<>";
36 retain_state_information="1";
37 };
38 lines = mapAttrsToList (key: value: "${key}=${value}") (default // cfg.extraConfig);
39 content = concatStringsSep "\n" lines;
40 file = pkgs.writeText "nagios.cfg" content;
41 validated = pkgs.runCommand "nagios-checked.cfg" {preferLocalBuild=true;} ''
42 cp ${file} nagios.cfg
43 # nagios checks the existence of /var/lib/nagios, but
44 # it does not exists in the build sandbox, so we fake it
45 mkdir lib
46 lib=$(readlink -f lib)
47 sed -i s@=${nagiosState}@=$lib@ nagios.cfg
48 ${pkgs.nagios}/bin/nagios -v nagios.cfg && cp ${file} $out
49 '';
50 defaultCfgFile = if cfg.validateConfig then validated else file;
51 in
52 if cfg.mainConfigFile == null then defaultCfgFile else cfg.mainConfigFile;
53
54 # Plain configuration for the Nagios web-interface with no
55 # authentication.
56 nagiosCGICfgFile = pkgs.writeText "nagios.cgi.conf"
57 ''
58 main_config_file=${cfg.mainConfigFile}
59 use_authentication=0
60 url_html_path=${urlPath}
61 '';
62
63 extraHttpdConfig =
64 ''
65 ScriptAlias ${urlPath}/cgi-bin ${pkgs.nagios}/sbin
66
67 <Directory "${pkgs.nagios}/sbin">
68 Options ExecCGI
69 Require all granted
70 SetEnv NAGIOS_CGI_CONFIG ${cfg.cgiConfigFile}
71 </Directory>
72
73 Alias ${urlPath} ${pkgs.nagios}/share
74
75 <Directory "${pkgs.nagios}/share">
76 Options None
77 Require all granted
78 </Directory>
79 '';
80
81in
82{
83 imports = [
84 (mkRemovedOptionModule [ "services" "nagios" "urlPath" ] "The urlPath option has been removed as it is hard coded to /nagios in the nagios package.")
85 ];
86
87 meta.maintainers = with lib.maintainers; [ symphorien ];
88
89 options = {
90 services.nagios = {
91 enable = mkEnableOption "<link xlink:href='http://www.nagios.org/'>Nagios</link> to monitor your system or network.";
92
93 objectDefs = mkOption {
94 description = "
95 A list of Nagios object configuration files that must define
96 the hosts, host groups, services and contacts for the
97 network that you want Nagios to monitor.
98 ";
99 type = types.listOf types.path;
100 example = literalExample "[ ./objects.cfg ]";
101 };
102
103 plugins = mkOption {
104 type = types.listOf types.package;
105 default = with pkgs; [ nagiosPluginsOfficial ssmtp mailutils ];
106 defaultText = "[pkgs.nagiosPluginsOfficial pkgs.ssmtp pkgs.mailutils]";
107 description = "
108 Packages to be added to the Nagios <envar>PATH</envar>.
109 Typically used to add plugins, but can be anything.
110 ";
111 };
112
113 mainConfigFile = mkOption {
114 type = types.nullOr types.package;
115 default = null;
116 description = "
117 If non-null, overrides the main configuration file of Nagios.
118 ";
119 };
120
121 extraConfig = mkOption {
122 type = types.attrsOf types.str;
123 example = {
124 debug_level = "-1";
125 debug_file = "/var/log/nagios/debug.log";
126 };
127 default = {};
128 description = "Configuration to add to /etc/nagios.cfg";
129 };
130
131 validateConfig = mkOption {
132 type = types.bool;
133 default = pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform;
134 description = "if true, the syntax of the nagios configuration file is checked at build time";
135 };
136
137 cgiConfigFile = mkOption {
138 type = types.package;
139 default = nagiosCGICfgFile;
140 defaultText = "nagiosCGICfgFile";
141 description = "
142 Derivation for the configuration file of Nagios CGI scripts
143 that can be used in web servers for running the Nagios web interface.
144 ";
145 };
146
147 enableWebInterface = mkOption {
148 type = types.bool;
149 default = false;
150 description = "
151 Whether to enable the Nagios web interface. You should also
152 enable Apache (<option>services.httpd.enable</option>).
153 ";
154 };
155
156 virtualHost = mkOption {
157 type = types.submodule (import ../web-servers/apache-httpd/vhost-options.nix);
158 example = literalExample ''
159 { hostName = "example.org";
160 adminAddr = "webmaster@example.org";
161 enableSSL = true;
162 sslServerCert = "/var/lib/acme/example.org/full.pem";
163 sslServerKey = "/var/lib/acme/example.org/key.pem";
164 }
165 '';
166 description = ''
167 Apache configuration can be done by adapting <option>services.httpd.virtualHosts</option>.
168 See <xref linkend="opt-services.httpd.virtualHosts"/> for further information.
169 '';
170 };
171 };
172 };
173
174
175 config = mkIf cfg.enable {
176 users.users.nagios = {
177 description = "Nagios user ";
178 uid = config.ids.uids.nagios;
179 home = nagiosState;
180 group = "nagios";
181 };
182
183 users.groups.nagios = { };
184
185 # This isn't needed, it's just so that the user can type "nagiostats
186 # -c /etc/nagios.cfg".
187 environment.etc."nagios.cfg".source = nagiosCfgFile;
188
189 environment.systemPackages = [ pkgs.nagios ];
190 systemd.services.nagios = {
191 description = "Nagios monitoring daemon";
192 path = [ pkgs.nagios ] ++ cfg.plugins;
193 wantedBy = [ "multi-user.target" ];
194 after = [ "network.target" ];
195 restartTriggers = [ nagiosCfgFile ];
196
197 serviceConfig = {
198 User = "nagios";
199 Group = "nagios";
200 Restart = "always";
201 RestartSec = 2;
202 LogsDirectory = "nagios";
203 StateDirectory = "nagios";
204 ExecStart = "${pkgs.nagios}/bin/nagios /etc/nagios.cfg";
205 };
206 };
207
208 services.httpd.virtualHosts = optionalAttrs cfg.enableWebInterface {
209 ${cfg.virtualHost.hostName} = mkMerge [ cfg.virtualHost { extraConfig = extraHttpdConfig; } ];
210 };
211 };
212}