]> granicus.if.org Git - icinga2/blob - doc/07-agent-based-monitoring.md
Update 08-advanced-topics.md
[icinga2] / doc / 07-agent-based-monitoring.md
1 # Additional Agent-based Checks <a id="agent-based-checks-addon"></a>
2
3 If the remote services are not directly accessible through the network, a
4 local agent installation exposing the results to check queries can
5 become handy.
6
7 ## SNMP <a id="agent-based-checks-snmp"></a>
8
9 The SNMP daemon runs on the remote system and answers SNMP queries by plugin
10 binaries. The [Monitoring Plugins package](02-getting-started.md#setting-up-check-plugins) ships
11 the `check_snmp` plugin binary, but there are plenty of [existing plugins](05-service-monitoring.md#service-monitoring-plugins)
12 for specific use cases already around, for example monitoring Cisco routers.
13
14 The following example uses the [SNMP ITL](10-icinga-template-library.md#plugin-check-command-snmp) `CheckCommand` and just
15 overrides the `snmp_oid` custom attribute. A service is created for all hosts which
16 have the `snmp-community` custom attribute.
17
18     apply Service "uptime" {
19       import "generic-service"
20
21       check_command = "snmp"
22       vars.snmp_oid = "1.3.6.1.2.1.1.3.0"
23       vars.snmp_miblist = "DISMAN-EVENT-MIB"
24
25       assign where host.vars.snmp_community != ""
26     }
27
28 Additional SNMP plugins are available using the [Manubulon SNMP Plugins](10-icinga-template-library.md#snmp-manubulon-plugin-check-commands).
29
30 If no `snmp_miblist` is specified, the plugin will default to `ALL`. As the number of available MIB files
31 on the system increases so will the load generated by this plugin if no `MIB` is specified.
32 As such, it is recommended to always specify at least one `MIB`.
33
34 ## SSH <a id="agent-based-checks-ssh"></a>
35
36 Calling a plugin using the SSH protocol to execute a plugin on the remote server fetching
37 its return code and output. The `by_ssh` command object is part of the built-in templates and
38 requires the `check_by_ssh` check plugin which is available in the [Monitoring Plugins package](02-getting-started.md#setting-up-check-plugins).
39
40     object CheckCommand "by_ssh_swap" {
41       import "by_ssh"
42
43       vars.by_ssh_command = "/usr/lib/nagios/plugins/check_swap -w $by_ssh_swap_warn$ -c $by_ssh_swap_crit$"
44       vars.by_ssh_swap_warn = "75%"
45       vars.by_ssh_swap_crit = "50%"
46     }
47
48     object Service "swap" {
49       import "generic-service"
50
51       host_name = "remote-ssh-host"
52
53       check_command = "by_ssh_swap"
54
55       vars.by_ssh_logname = "icinga"
56     }
57
58 ## NSClient++ <a id="agent-based-checks-nsclient"></a>
59
60 [NSClient++](https://nsclient.org/) works on both Windows and Linux platforms and is well
61 known for its magnificent Windows support. There are alternatives like the WMI interface,
62 but using `NSClient++` will allow you to run local scripts similar to check plugins fetching
63 the required output and performance counters.
64
65 You can use the `check_nt` plugin from the Monitoring Plugins project to query NSClient++.
66 Icinga 2 provides the [nscp check command](10-icinga-template-library.md#plugin-check-command-nscp) for this:
67
68 Example:
69
70     object Service "disk" {
71       import "generic-service"
72
73       host_name = "remote-windows-host"
74
75       check_command = "nscp"
76
77       vars.nscp_variable = "USEDDISKSPACE"
78       vars.nscp_params = "c"
79       vars.nscp_warn = 70
80       vars.nscp_crit = 80
81     }
82
83 For details on the `NSClient++` configuration please refer to the [official documentation](https://docs.nsclient.org/).
84
85 ## NSCA-NG <a id="agent-based-checks-nsca-ng"></a>
86
87 [NSCA-ng](http://www.nsca-ng.org) provides a client-server pair that allows the
88 remote sender to push check results into the Icinga 2 `ExternalCommandListener`
89 feature.
90
91 > **Note**
92 >
93 > This addon works in a similar fashion like the Icinga 1.x distributed model. If you
94 > are looking for a real distributed architecture with Icinga 2, scroll down.
95
96 ## NRPE <a id="agent-based-checks-nrpe"></a>
97
98 [NRPE](https://docs.icinga.com/latest/en/nrpe.html) runs as daemon on the remote client including
99 the required plugins and command definitions.
100 Icinga 2 calls the `check_nrpe` plugin binary in order to query the configured command on the
101 remote client.
102
103 > **Note**
104 >
105 > The NRPE protocol is considered insecure and has multiple flaws in its
106 > design. Upstream is not willing to fix these issues.
107 >
108 > In order to stay safe, please use the native [Icinga 2 client](06-distributed-monitoring.md#distributed-monitoring)
109 > instead.
110
111 The NRPE daemon uses its own configuration format in nrpe.cfg while `check_nrpe`
112 can be embedded into the Icinga 2 `CheckCommand` configuration syntax.
113
114 You can use the `check_nrpe` plugin from the NRPE project to query the NRPE daemon.
115 Icinga 2 provides the [nrpe check command](10-icinga-template-library.md#plugin-check-command-nrpe) for this:
116
117 Example:
118
119     object Service "users" {
120       import "generic-service"
121
122       host_name = "remote-nrpe-host"
123
124       check_command = "nrpe"
125       vars.nrpe_command = "check_users"
126     }
127
128 nrpe.cfg:
129
130     command[check_users]=/usr/local/icinga/libexec/check_users -w 5 -c 10
131
132 If you are planning to pass arguments to NRPE using the `-a`
133 command line parameter, make sure that your NRPE daemon has them
134 supported and enabled.
135
136 > **Note**
137 >
138 > Enabling command arguments in NRPE is considered harmful
139 > and exposes a security risk allowing attackers to execute
140 > commands remotely. Details at [seclists.org](http://seclists.org/fulldisclosure/2014/Apr/240).
141
142 The plugin check command `nrpe` provides the `nrpe_arguments` custom
143 attribute which expects either a single value or an array of values.
144
145 Example:
146
147     object Service "nrpe-disk-/" {
148       import "generic-service"
149
150       host_name = "remote-nrpe-host"
151
152       check_command = "nrpe"
153       vars.nrpe_command = "check_disk"
154       vars.nrpe_arguments = [ "20%", "10%", "/" ]
155     }
156
157 Icinga 2 will execute the nrpe plugin like this:
158
159     /usr/lib/nagios/plugins/check_nrpe -H <remote-nrpe-host> -c 'check_disk' -a '20%' '10%' '/'
160
161 NRPE expects all additional arguments in an ordered fashion
162 and interprets the first value as `$ARG1$` macro, the second
163 value as `$ARG2$`, and so on.
164
165 nrpe.cfg:
166
167     command[check_disk]=/usr/local/icinga/libexec/check_disk -w $ARG1$ -c $ARG2$ -p $ARG3$
168
169 Using the above example with `nrpe_arguments` the command
170 executed by the NRPE daemon looks similar to that:
171
172     /usr/local/icinga/libexec/check_disk -w 20% -c 10% -p /
173
174 You can pass arguments in a similar manner to [NSClient++](07-agent-based-monitoring.md#agent-based-checks-nsclient)
175 when using its NRPE supported check method.
176
177
178 ## Passive Check Results and SNMP Traps <a id="agent-based-checks-snmp-traps"></a>
179
180 SNMP Traps can be received and filtered by using [SNMPTT](http://snmptt.sourceforge.net/)
181 and specific trap handlers passing the check results to Icinga 2.
182
183 Following the SNMPTT [Format](http://snmptt.sourceforge.net/docs/snmptt.shtml#SNMPTT.CONF-FORMAT)
184 documentation and the Icinga external command syntax found [here](24-appendix.md#external-commands-list-detail)
185 we can create generic services that can accommodate any number of hosts for a given scenario.
186
187 ### Simple SNMP Traps <a id="simple-traps"></a>
188
189 A simple example might be monitoring host reboots indicated by an SNMP agent reset.
190 Building the event to auto reset after dispatching a notification is important.
191 Setup the manual check parameters to reset the event from an initial unhandled
192 state or from a missed reset event.
193
194 Add a directive in `snmptt.conf`
195
196     EVENT coldStart .1.3.6.1.6.3.1.1.5.1 "Status Events" Normal
197     FORMAT Device reinitialized (coldStart)
198     EXEC echo "[$@] PROCESS_SERVICE_CHECK_RESULT;$A;Coldstart;2;The snmp agent has reinitialized." >> /var/run/icinga2/cmd/icinga2.cmd
199     SDESC
200     A coldStart trap signifies that the SNMPv2 entity, acting
201     in an agent role, is reinitializing itself and that its
202     configuration may have been altered.
203     EDESC
204
205 1. Define the `EVENT` as per your need.
206 2. Construct the `EXEC` statement with the service name matching your template
207 applied to your _n_ hosts. The host address inferred by SNMPTT will be the
208 correlating factor. You can have snmptt provide host names or ip addresses to
209 match your Icinga convention.
210
211 Add an `EventCommand` configuration object for the passive service auto reset event.
212
213     object EventCommand "coldstart-reset-event" {
214       command = [ SysconfDir + "/icinga2/conf.d/custom/scripts/coldstart_reset_event.sh" ]
215
216       arguments = {
217         "-i" = "$service.state_id$"
218         "-n" = "$host.name$"
219         "-s" = "$service.name$"
220       }
221     }
222
223 Create the `coldstart_reset_event.sh` shell script to pass the expanded variable
224 data in. The `$service.state_id$` is important in order to prevent an endless loop
225 of event firing after the service has been reset.
226
227     #!/bin/bash
228
229     SERVICE_STATE_ID=""
230     HOST_NAME=""
231     SERVICE_NAME=""
232
233     show_help()
234     {
235     cat <<-EOF
236         Usage: ${0##*/} [-h] -n HOST_NAME -s SERVICE_NAME
237         Writes a coldstart reset event to the Icinga command pipe.
238
239           -h                  Display this help and exit.
240           -i SERVICE_STATE_ID The associated service state id.
241           -n HOST_NAME        The associated host name.
242           -s SERVICE_NAME     The associated service name.
243     EOF
244     }
245
246     while getopts "hi:n:s:" opt; do
247         case "$opt" in
248           h)
249               show_help
250               exit 0
251               ;;
252           i)
253               SERVICE_STATE_ID=$OPTARG
254               ;;
255           n)
256               HOST_NAME=$OPTARG
257               ;;
258           s)
259               SERVICE_NAME=$OPTARG
260               ;;
261           '?')
262               show_help
263               exit 0
264               ;;
265           esac
266     done
267
268     if [ -z "$SERVICE_STATE_ID" ]; then
269         show_help
270         printf "\n  Error: -i required.\n"
271         exit 1
272     fi
273
274     if [ -z "$HOST_NAME" ]; then
275         show_help
276         printf "\n  Error: -n required.\n"
277         exit 1
278     fi
279
280     if [ -z "$SERVICE_NAME" ]; then
281         show_help
282         printf "\n  Error: -s required.\n"
283         exit 1
284     fi
285
286     if [ "$SERVICE_STATE_ID" -gt 0 ]; then
287         echo "[`date +%s`] PROCESS_SERVICE_CHECK_RESULT;$HOST_NAME;$SERVICE_NAME;0;Auto-reset (`date +"%m-%d-%Y %T"`)." >> /var/run/icinga2/cmd/icinga2.cmd
288     fi
289
290 Finally create the `Service` and assign it:
291
292     apply Service "Coldstart" {
293       import "generic-service-custom"
294
295       check_command         = "dummy"
296       event_command         = "coldstart-reset-event"
297
298       enable_notifications  = 1
299       enable_active_checks  = 0
300       enable_passive_checks = 1
301       enable_flapping       = 0
302       volatile              = 1
303       enable_perfdata       = 0
304
305       vars.dummy_state      = 0
306       vars.dummy_text       = "Manual reset."
307
308       vars.sla              = "24x7"
309
310       assign where (host.vars.os == "Linux" || host.vars.os == "Windows")
311     }
312
313 ### Complex SNMP Traps <a id="complex-traps"></a>
314
315 A more complex example might be passing dynamic data from a traps varbind list
316 for a backup scenario where the backup software dispatches status updates. By
317 utilizing active and passive checks, the older freshness concept can be leveraged.
318
319 By defining the active check as a hard failed state, a missed backup can be reported.
320 As long as the most recent passive update has occurred, the active check is bypassed.
321
322 Add a directive in `snmptt.conf`
323
324     EVENT enterpriseSpecific <YOUR OID> "Status Events" Normal
325     FORMAT Enterprise specific trap
326     EXEC echo "[$@] PROCESS_SERVICE_CHECK_RESULT;$A;$1;$2;$3" >> /var/run/icinga2/cmd/icinga2.cmd
327     SDESC
328     An enterprise specific trap.
329     The varbinds in order denote the Icinga service name, state and text.
330     EDESC
331
332 1. Define the `EVENT` as per your need using your actual oid.
333 2. The service name, state and text are extracted from the first three varbinds.
334 This has the advantage of accommodating an unlimited set of use cases.
335
336 Create a `Service` for the specific use case associated to the host. If the host
337 matches and the first varbind value is `Backup`, SNMPTT will submit the corresponding
338 passive update with the state and text from the second and third varbind:
339
340     object Service "Backup" {
341       import "generic-service-custom"
342
343       host_name             = "host.domain.com"
344       check_command         = "dummy"
345
346       enable_notifications  = 1
347       enable_active_checks  = 1
348       enable_passive_checks = 1
349       enable_flapping       = 0
350       volatile              = 1
351       max_check_attempts    = 1
352       check_interval        = 87000
353       enable_perfdata       = 0
354
355       vars.sla              = "24x7"
356       vars.dummy_state      = 2
357       vars.dummy_text       = "No passive check result received."
358     }
359