From ba200f74e199f361ce6a1c6a6741454687f4eb24 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lorenz=20K=C3=A4stle?=
<12514511+RincewindsHat@users.noreply.github.com>
Date: Fri, 30 Aug 2024 12:25:27 +0200
Subject: [PATCH] Add check_curl to ITL (#9205)
* Add check_curl to ITL
* small fixes and boolean defaults
* Add documentation for check_curl
* Replace dash with underscore in variables
* Add link to documentation
* Change order of argument attributes to adhere to style guide
* Shorten description of tls option in itl
* Just remove information for check_curl options
* itl - check_curl: document -4 and -6
* itl - check_curl: Add haproxy option for check_curl
* itl - check_curl: add cookie-jar option
* itl - check_curl: add continue_after_certificate option
* itl - check_curl: replace dashes with underscores in macros
* Update itl/command-plugins.conf
Co-authored-by: alvar <8402811+oxzi@users.noreply.github.com>
* Update itl/command-plugins.conf
Co-authored-by: alvar <8402811+oxzi@users.noreply.github.com>
* itl - check_curl: add missing option documentation and reorder options
* itl - check_curl: Split certificate lifetime in two parameters
* itl - check_curl: replace remaining instances of single parameter for remaining valid time
* check_curl: allow assignements for host without address set
* check_curl: fix typo expext -> expect
* itl - check_curl: add state-regex option and documentation
* Add Tls options with version and without
* itl - check_curl: fix indentation
* itl - check_curl: Set v4/v6 variables
* itl - check_curl: Edit description for --sni
* doc - check_curl: fix singular-plural typo for curl_max_redir(s)
* doc/check_curl: sni description
* itl - check_curl: remove superfluous brace
* itl - check_curl: add extra-opts parameter
---------
Co-authored-by: alvar <8402811+oxzi@users.noreply.github.com>
---
doc/10-icinga-template-library.md | 61 +++++++++
itl/command-plugins.conf | 208 +++++++++++++++++++++++++++++-
2 files changed, 268 insertions(+), 1 deletion(-)
diff --git a/doc/10-icinga-template-library.md b/doc/10-icinga-template-library.md
index f7b57b831..5b2a2fd27 100644
--- a/doc/10-icinga-template-library.md
+++ b/doc/10-icinga-template-library.md
@@ -738,6 +738,67 @@ http_verbose | **Optional.** Show details for command-line d
http_extra_opts | **Optional.** Read extra plugin options from an ini file.
http_verify_host | **Optional.** Verify SSL certificate is for the -H hostname (with --sni and -S). Defaults to false. **Only supported by the Nagios plugins version of check\_http, not by the monitoring plugins one.**
+### curl
+
+The [check_curl](https://www.monitoring-plugins.org/doc/man/check_curl.html) plugin
+tests the HTTP service on the specified host. It can test normal (http) and secure
+(https) servers, follow redirects, search for strings and regular expressions,
+check connection times, and report on certificate expiration times.
+
+The plugin can either test the HTTP response of a server, or if `curl_certificate_valid_days_min_warning`/`curl_certificate_valid_days_min_critical` is set to a non-empty value, the TLS certificate age for a HTTPS host.
+
+Custom variables passed as [command parameters](03-monitoring-basics.md#command-passing-parameters):
+
+Name | Description
+---------------------------------|---------------------------------
+curl_extra_opts | **Optional.** Read options from an ini file.
+curl_vhost | **Optional.** The virtual host that should be sent in the "Host" header.
+curl_ip | **Optional.** The host's address. Defaults to "$address$" if the host's `address` attribute is set, "$address6$" otherwise.
+curl_port | **Optional.** The TCP port. Defaults to 80 when not using SSL, 443 otherwise.
+curl_ipv4 | **Optional.** Use IPv4 connection. Defaults to false.
+curl_ipv6 | **Optional.** Use IPv6 connection. Defaults to false.
+curl_tls | **Optional.** Whether to use SSL. Defaults to false.
+curl_tls_version | **Optional.** Connect via SSL. Port defaults to 443. VERSION is optional, and prevents auto-negotiation (2 = SSLv2, 3 = SSLv3, 1 = TLSv1, 1.1 = TLSv1.1, 1.2 = TLSv1.2, 1.3 = TLSv1.3). With a '+' suffix, newer versions are also accepted. Note: SSLv2 and SSLv3 are deprecated and are usually disabled in libcurl.
+curl_sni | **Optional.** Whether to use SNI. This is the default of `check_curl` in *most* cases and this option will not change this behaviour then. For obscure and old setup it might be necessary to manually activate it. The variable itself defaults to false.
+curl_certificate_valid_days_min_warning | **Optional.** Minimum number of days a certificate has to be valid. Port defaults to 443. When this option is used, the URL is not checked (by default). This defines the warning threshold (in days).
+curl_certificate_valid_days_min_critical | **Optional.** Minimum number of days a certificate has to be valid. This parameter defines the critical threshold (in days). See also `curl_certificate_valid_days_min_warning` above for more information.
+curl_continue_after_certificate | **Optional.** Allows the HTTP check to continue after performing the certificate check. Does nothing unless tls certificate check mode is used (`curl_certificate_valid_days_min_warning`/`curl_certificate_valid_days_min_critical`). (available since Monitoring Plugins v2.3.2)
+curl_client_certificate_file | **Optional.** Name of file contains the client certificate (PEM format).
+curl_client_certificate_key_file | **Optional.** Name of file contains the private key (PEM format).
+curl_ca_cert_file | **Optional.** CA certificate file to verify peer against.
+curl_verify_peer_cert | **Optional.** Verify that the peers certificate matches against the hostname
+curl_expect_string | **Optional.** Comma-delimited list of strings, at least one of them is expected in the first (status) line of the server response. Default: HTTP/1.
+curl_expect_header_string | **Optional.** String to expect in the response headers.
+curl_expect_content_string | **Optional.** String to expect in the content.
+curl_url | **Optional.** The request URL for GET or POST. Defaults to `/`.
+curl_post_data | **Optional.** URL encoded curl POST data.
+curl_http_method | **Optional.** Set curl method (for example: HEAD, OPTIONS, TRACE, PUT, DELETE).
+curl_no_body | **Optional.** Don't wait for document body: stop reading after headers. (Note that this stilldoes an HTTP GET or POST, not a HEAD.).
+curl_max_age | **Optional.** Warn if document is more than seconds old.
+curl_content_type | **Optional.** Specify Content-Type header when POSTing.
+curl_linespan | **Optional.** Allow regex to span newline.
+curl_ereg | **Optional.** A regular expression which the body must match against. Incompatible with curl_no-body.
+curl_eregi | **Optional.** A case-insensitive expression which the body must match against. Incompatible with curl_no-body.
+curl_invert_regex | **Optional.** Changes behavior of curl_ereg and curl_eregi to return CRITICAL if found, OK if not.
+curl_state_regex | **Optional.** Return STATE if regex is found, OK if not. STATE can be one of "critical","warning"
+curl_authorization | **Optional.** Add 'username:password' authorization pair.
+curl_proxy_authorization | **Optional.** Add 'username:password' authorization pair for proxy.
+curl_user_agent | **Optional.** String to be sent in curl header as User Agent.
+curl_header | **Optional.** Any other tags to be sent in curl header. Can be an array if multiple headers should be passed to `check_curl`.
+curl_extended_perfdata | **Optional.** Print additional perfdata. Defaults to false.
+curl_show_body | **Optional.** Print body content below status line
+curl_link | **Optional.** Wrap output in HTML link. Defaults to false.
+curl_onredirect | **Optional.** How to handle redirect pages. Possible values: "ok" (default), "warning", "critical", "follow", "sticky" (like follow but stick to address), "stickyport" (like sticky but also to port)
+curl_max_redirs | **Optional.** Maximum number of redirects
+curl_pagesize | **Optional.** Minimum page size required:Maximum page size required.
+curl_http_version | **Optional.** Connect via specific HTTP protocol. 1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)
+curl_enable_automatic_decompression | **Optional.** Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING).
+curl_haproxy_protocol | **Optional.** Send HAProxy proxy protocol v1 header (CURLOPT_HAPROXYPROTOCOL) (available since Monitoring Plugins v2.4.0)
+curl_cookie_jar_file | **Optional.** Path to a cookie jar file. Store cookies in the cookie jar and send them out when requested. (available since Monitoring Plugins v2.3.4)
+curl_warning | **Optional.** The warning threshold.
+curl_critical | **Optional.** The critical threshold.
+curl_timeout | **Optional.** Seconds before connection times out.
+
### icmp
diff --git a/itl/command-plugins.conf b/itl/command-plugins.conf
index e80d1366d..716dde757 100644
--- a/itl/command-plugins.conf
+++ b/itl/command-plugins.conf
@@ -424,7 +424,7 @@ object CheckCommand "http" {
}
"--sni" = {
set_if = "$http_sni$"
- description = "Enable SSL/TLS hostname extension support (SNI)"
+ description = "Enable SSL/TLS hostname extension support (SNI). This is (normally) the default in modern setups"
}
"-C" = {
value = "$http_certificate$"
@@ -566,6 +566,212 @@ object CheckCommand "http" {
vars.http_verbose = false
}
+object CheckCommand "curl" {
+ import "ipv4-or-ipv6"
+
+ command = [ PluginDir + "/check_curl" ]
+
+ arguments += {
+ "--extra-opts" = {
+ value = "$curl_extra_opts$"
+ description = "Read options from an ini file"
+ }
+ "-H" = {
+ value = "$curl_vhost$"
+ description = "Host name argument for servers using host headers (virtual host). Append a port to include it in the header (eg: example.com:5000)"
+ }
+ "-I" = {
+ value = "$curl_ip$"
+ set_if = {{ string(macro("$curl_ip$")) != "" }}
+ description = "IP address or name (use numeric address if possible to bypass DNS lookup)."
+ }
+ "-p" = {
+ value = "$curl_port$"
+ description = "Port number (default: 80)"
+ }
+ "-4" = {
+ set_if = "$curl_ipv4$"
+ description = "Force `check_curl` to use IPv4 instead of choosing automatically"
+ }
+ "-6" = {
+ set_if = "$curl_ipv6$"
+ description = "Force `check_curl` to use IPv6 instead of choosing automatically"
+ }
+ "(-S w/ value)" = {
+ set_if = {{ macro("$curl_tls$") && string(macro("$curl_tls_version$")) != "" }}
+ key = "-S"
+ value = "$curl_tls_version$"
+ description = "Connect via SSL. Port defaults to 443. VERSION is optional, and prevents auto-negotiation"
+ }
+ "(-S w/o value)" = {
+ set_if = {{ macro("$curl_tls$") && string(macro("$curl_tls_version$")) == "" }}
+ key = "-S"
+ description = "Connect via SSL. Port defaults to 443. VERSION is optional, and prevents auto-negotiation"
+ }
+ "--sni" = {
+ set_if = "$curl_sni$"
+ description = "Enable SSL/TLS hostname extension support (SNI). Default if TLS version > 1.0"
+ }
+ "-C" = {
+ value = "$curl_certificate_valid_days_min_warning$,$curl_certificate_valid_days_min_critical$"
+ description = "Minimum number of days a certificate has to be valid."
+ }
+ "--continue-after-certificate" = {
+ value = "$curl_continue_after_certificate$"
+ description = "Allows the HTTP check to continue after performing the certificate check. Does nothing unless -C is used."
+ }
+ "-J" = {
+ value = "$curl_client_certificate_file$"
+ description = "Name of file that contains the client certificate (PEM format) to be used in establishing the SSL session"
+ }
+ "-K" = {
+ value = "$curl_client_certificate_key_file$"
+ description = "Name of file containing the private key (PEM format) matching the client certificate"
+ }
+ "--ca-cert" = {
+ value = "$curl_ca_cert_file$"
+ description = "CA certificate file to verify peer against"
+ }
+ "-D" = {
+ set_if = "$curl_verify_peer_cert$"
+ description = "Verify the peer's SSL certificate and hostname"
+ }
+ "-e" = {
+ value = "$curl_expect_string$"
+ description = "Comma-delimited list of strings, at least one of them is expected in the first (status) line of the server response (default: HTTP/), If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)"
+ }
+ "-d" = {
+ value = "$curl_expect_header_string$"
+ description = "String to expect in the response headers"
+ }
+ "-s" = {
+ value = "$curl_expect_content_string$"
+ description = "String to expect in the content"
+ }
+ "-u" = {
+ value = "$curl_url$"
+ description = "URL to GET or POST (default: /)"
+ }
+ "-P" = {
+ value = "$curl_post_data$"
+ description = "URL encoded http POST data"
+ }
+ "-j" = {
+ value = "$curl_http_method$"
+ description = "Set HTTP method (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT)"
+ }
+ "-N" = {
+ value = "$curl_no_body$"
+ description = "Don't wait for document body: stop reading after headers. (Note that this still does an HTTP GET or POST, not a HEAD.)"
+ }
+ "-M" = {
+ value = "$curl_max_age$"
+ description = "Warn if document is more than SECONDS old. the number can also be of the form '10m' for minutes, '10h' for hours, or '10d' for days."
+ }
+ "-T" = {
+ value = "$curl_content_type$"
+ description = "specify Content-Type header media type when POSTing"
+ }
+ "-l" = {
+ value = "$curl_linespan$"
+ description = "Allow regex to span newlines (must precede -r or -R)"
+ }
+ "-r" = {
+ value = "$curl_ereg$"
+ description = "Search page for regex STRING"
+ }
+ "-R" = {
+ value = "$curl_eregi$"
+ description = "Search page for case-insensitive regex STRING"
+ }
+ "--invert-regex" = {
+ set_if = "$curl_invert_regex$"
+ description = "When using regex, return CRITICAL if found, OK if not"
+ }
+ "--state-regex" = {
+ value = "$curl_state_regex$"
+ description = "Return STATE if regex is found, OK if not"
+ }
+ "-a" = {
+ value = "$curl_authorization$"
+ description = "Username:password on sites with basic authentication"
+ }
+ "-b" = {
+ value = "$curl_proxy_authorization$"
+ description = "Username:password on proxy-servers with basic authentication"
+ }
+ "-A" = {
+ value = "$curl_user_agent$"
+ description = "String to be sent in http header as 'User Agent'"
+ }
+ "-k" = {
+ value = "$curl_header$"
+ repeat_key = true
+ description = "Any other tags to be sent in http header. Use multiple times for additional headers"
+ }
+ "-E" = {
+ set_if = "$curl_extended_perfdata$"
+ description = "Print additional performance data"
+ }
+ "-B" = {
+ set_if = "$curl_show_body$"
+ description = "Print body content below status line"
+ }
+ "-L" = {
+ set_if = "$curl_link$"
+ description = "Wrap output in HTML link (obsoleted by urlize)"
+ }
+ "-f" = {
+ value = "$curl_onredirect$"
+ description = "Options: How to handle redirected pages."
+ }
+ "--max-redirs" = {
+ value = "$curl_max_redirs$"
+ description = "Maximal number of redirects (default: 15)"
+ }
+ "-m" = {
+ value = "$curl_pagesize$"
+ description = "Minimum page size required (bytes) : Maximum page size required (bytes)"
+ }
+ "--http-version" = {
+ value = "$curl_http_version$"
+ description = "Connect via specific HTTP protocol. 1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)"
+ }
+ "--enable-automatic-decompression" = {
+ set_if = "$curl_enable_automatic_decompression$"
+ description = "Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING)."
+ }
+ "--haproxy-protocol" = {
+ set_if = "$curl_haproxy_protocol$"
+ description = "Send HAProxy proxy protocol v1 header (CURLOPT_HAPROXYPROTOCOL)"
+ }
+ "--cookie-jar" = {
+ value = "$curl_cookie_jar_file$"
+ description = "Store cookies in the cookie jar file and send them out when requested."
+ }
+ "-w" = {
+ value = "$curl_warning$"
+ description = "Response time to result in warning status (seconds)"
+ }
+ "-c" = {
+ value = "$curl_critical$"
+ description = "Response time to result in critical status (seconds)"
+ }
+ "-t" = {
+ value = "$curl_timeout$"
+ description = "Seconds before connection times out (default: 10)"
+ }
+ }
+
+ vars.curl_ip = "$check_address$"
+ vars.curl_link = false
+ vars.curl_invert_regex = false
+ vars.curl_show_body = false
+ vars.curl_extended_perfdata = false
+ vars.check_ipv4 = "$curl_ipv4$"
+ vars.check_ipv6 = "$curl_ipv6$"
+}
+
object CheckCommand "ftp" {
import "ipv4-or-ipv6"