diff options
| -rw-r--r-- | .github/NPTest.cache | 7 | ||||
| -rwxr-xr-x | .github/prepare_debian.sh | 21 | ||||
| -rw-r--r-- | plugins/check_curl.c | 91 | ||||
| -rw-r--r-- | plugins/check_curl.d/check_curl_helpers.c | 455 | ||||
| -rw-r--r-- | plugins/check_curl.d/check_curl_helpers.h | 9 | ||||
| -rw-r--r-- | plugins/check_curl.d/config.h | 7 | ||||
| -rw-r--r-- | plugins/t/check_curl.t | 115 | ||||
| -rwxr-xr-x | plugins/tests/check_curl.t | 135 | ||||
| -rw-r--r-- | tools/squid.conf | 3 | ||||
| -rw-r--r-- | tools/subdomain1/index.php | 1 | ||||
| -rw-r--r-- | tools/subdomain1/subdomain1.conf | 22 |
11 files changed, 835 insertions, 31 deletions
diff --git a/.github/NPTest.cache b/.github/NPTest.cache index 6b463e74..3f6d4da6 100644 --- a/.github/NPTest.cache +++ b/.github/NPTest.cache | |||
| @@ -19,6 +19,13 @@ | |||
| 19 | 'NP_HOST_TCP_HPJD' => '', | 19 | 'NP_HOST_TCP_HPJD' => '', |
| 20 | 'NP_HOST_TCP_HTTP2' => 'test.monitoring-plugins.org', | 20 | 'NP_HOST_TCP_HTTP2' => 'test.monitoring-plugins.org', |
| 21 | 'NP_HOST_TCP_HTTP' => 'localhost', | 21 | 'NP_HOST_TCP_HTTP' => 'localhost', |
| 22 | 'NP_HOST_TCP_HTTP_IPV4' => '127.0.0.1', | ||
| 23 | 'NP_HOST_TCP_HTTP_IPV4_CIDR_1' => '127.0.0.0/28', | ||
| 24 | 'NP_HOST_TCP_HTTP_IPV4_CIDR_2' => '127.0.0.1/32', | ||
| 25 | 'NP_HOST_TCP_HTTP_IPV6' => '::1', | ||
| 26 | 'NP_HOST_TCP_HTTP_IPV6_CIDR_1' => '0000:0000:0000::0000:0000:0000/16', | ||
| 27 | 'NP_HOST_TCP_HTTP_IPV6_CIDR_2' => '::1234:5678/16', | ||
| 28 | 'NP_HOST_TCP_HTTP_SUBDOMAIN' => 'subdomain1.localhost', | ||
| 22 | 'NP_HOST_TCP_IMAP' => 'imap.web.de', | 29 | 'NP_HOST_TCP_IMAP' => 'imap.web.de', |
| 23 | 'NP_HOST_TCP_JABBER' => 'jabber.org', | 30 | 'NP_HOST_TCP_JABBER' => 'jabber.org', |
| 24 | 'NP_HOST_TCP_LDAP' => 'localhost', | 31 | 'NP_HOST_TCP_LDAP' => 'localhost', |
diff --git a/.github/prepare_debian.sh b/.github/prepare_debian.sh index cffe98c5..15c2286c 100755 --- a/.github/prepare_debian.sh +++ b/.github/prepare_debian.sh | |||
| @@ -67,10 +67,10 @@ apt-get -y install perl \ | |||
| 67 | libjson-perl | 67 | libjson-perl |
| 68 | 68 | ||
| 69 | # remove ipv6 interface from hosts | 69 | # remove ipv6 interface from hosts |
| 70 | sed '/^::1/d' /etc/hosts > /tmp/hosts | 70 | # sed '/^::1/d' /etc/hosts > /tmp/hosts |
| 71 | cp -f /tmp/hosts /etc/hosts | 71 | # cp -f /tmp/hosts /etc/hosts |
| 72 | ip addr show | 72 | # ip addr show |
| 73 | cat /etc/hosts | 73 | # cat /etc/hosts |
| 74 | 74 | ||
| 75 | # apache | 75 | # apache |
| 76 | a2enmod ssl | 76 | a2enmod ssl |
| @@ -80,6 +80,19 @@ a2ensite default-ssl | |||
| 80 | rm /etc/ssl/certs/ssl-cert-snakeoil.pem | 80 | rm /etc/ssl/certs/ssl-cert-snakeoil.pem |
| 81 | rm /etc/ssl/private/ssl-cert-snakeoil.key | 81 | rm /etc/ssl/private/ssl-cert-snakeoil.key |
| 82 | openssl req -nodes -newkey rsa:2048 -x509 -sha256 -days 365 -nodes -keyout /etc/ssl/private/ssl-cert-snakeoil.key -out /etc/ssl/certs/ssl-cert-snakeoil.pem -subj "/C=GB/ST=London/L=London/O=Global Security/OU=IT Department/CN=$(hostname)" | 82 | openssl req -nodes -newkey rsa:2048 -x509 -sha256 -days 365 -nodes -keyout /etc/ssl/private/ssl-cert-snakeoil.key -out /etc/ssl/certs/ssl-cert-snakeoil.pem -subj "/C=GB/ST=London/L=London/O=Global Security/OU=IT Department/CN=$(hostname)" |
| 83 | # add a subdomain for testing | ||
| 84 | cp tools/subdomain1/subdomain1.conf /etc/apache2/sites-available/ | ||
| 85 | mkdir -p /var/www/subdomain1 | ||
| 86 | cp tools/subdomain1/index.php /var/www/subdomain1/ | ||
| 87 | echo '127.0.0.1 subdomain1.localhost' >> /etc/hosts | ||
| 88 | echo '127.0.0.1 subdomain1.localhost.com' >> /etc/hosts | ||
| 89 | apache2ctl configtest | ||
| 90 | a2ensite subdomain1.conf | ||
| 91 | |||
| 92 | # Make it listen to both IPv4 on IPv6 on localhost | ||
| 93 | sed -i 's/^Listen 80/Listen 0.0.0.0:80\nListen [::1]:80/' /etc/apache2/ports.conf | ||
| 94 | sed -i 's/^[[:space:]]*Listen 443/Listen 0.0.0.0:443\nListen [::1]:443/' /etc/apache2/ports.conf | ||
| 95 | |||
| 83 | service apache2 restart | 96 | service apache2 restart |
| 84 | 97 | ||
| 85 | # squid | 98 | # squid |
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index d7d68de5..4a1fb647 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
| @@ -874,7 +874,8 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) { | |||
| 874 | COOKIE_JAR, | 874 | COOKIE_JAR, |
| 875 | HAPROXY_PROTOCOL, | 875 | HAPROXY_PROTOCOL, |
| 876 | STATE_REGEX, | 876 | STATE_REGEX, |
| 877 | OUTPUT_FORMAT | 877 | OUTPUT_FORMAT, |
| 878 | NO_PROXY, | ||
| 878 | }; | 879 | }; |
| 879 | 880 | ||
| 880 | static struct option longopts[] = { | 881 | static struct option longopts[] = { |
| @@ -889,6 +890,8 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) { | |||
| 889 | {"url", required_argument, 0, 'u'}, | 890 | {"url", required_argument, 0, 'u'}, |
| 890 | {"port", required_argument, 0, 'p'}, | 891 | {"port", required_argument, 0, 'p'}, |
| 891 | {"authorization", required_argument, 0, 'a'}, | 892 | {"authorization", required_argument, 0, 'a'}, |
| 893 | {"proxy", required_argument, 0, 'x'}, | ||
| 894 | {"noproxy", required_argument, 0, NO_PROXY}, | ||
| 892 | {"proxy-authorization", required_argument, 0, 'b'}, | 895 | {"proxy-authorization", required_argument, 0, 'b'}, |
| 893 | {"header-string", required_argument, 0, 'd'}, | 896 | {"header-string", required_argument, 0, 'd'}, |
| 894 | {"string", required_argument, 0, 's'}, | 897 | {"string", required_argument, 0, 's'}, |
| @@ -961,7 +964,7 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) { | |||
| 961 | 964 | ||
| 962 | while (true) { | 965 | while (true) { |
| 963 | int option_index = getopt_long( | 966 | int option_index = getopt_long( |
| 964 | argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:DnlLS::m:M:NEB", | 967 | argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:x:b:d:e:p:s:R:r:u:f:C:J:K:DnlLS::m:M:NEB", |
| 965 | longopts, &option); | 968 | longopts, &option); |
| 966 | if (option_index == -1 || option_index == EOF || option_index == 1) { | 969 | if (option_index == -1 || option_index == EOF || option_index == 1) { |
| 967 | break; | 970 | break; |
| @@ -1049,6 +1052,10 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) { | |||
| 1049 | strncpy(result.config.curl_config.user_auth, optarg, MAX_INPUT_BUFFER - 1); | 1052 | strncpy(result.config.curl_config.user_auth, optarg, MAX_INPUT_BUFFER - 1); |
| 1050 | result.config.curl_config.user_auth[MAX_INPUT_BUFFER - 1] = 0; | 1053 | result.config.curl_config.user_auth[MAX_INPUT_BUFFER - 1] = 0; |
| 1051 | break; | 1054 | break; |
| 1055 | case 'x': /* proxy info */ | ||
| 1056 | strncpy(result.config.curl_config.proxy, optarg, DEFAULT_BUFFER_SIZE - 1); | ||
| 1057 | result.config.curl_config.proxy[DEFAULT_BUFFER_SIZE - 1] = 0; | ||
| 1058 | break; | ||
| 1052 | case 'b': /* proxy-authorization info */ | 1059 | case 'b': /* proxy-authorization info */ |
| 1053 | strncpy(result.config.curl_config.proxy_auth, optarg, MAX_INPUT_BUFFER - 1); | 1060 | strncpy(result.config.curl_config.proxy_auth, optarg, MAX_INPUT_BUFFER - 1); |
| 1054 | result.config.curl_config.proxy_auth[MAX_INPUT_BUFFER - 1] = 0; | 1061 | result.config.curl_config.proxy_auth[MAX_INPUT_BUFFER - 1] = 0; |
| @@ -1344,6 +1351,10 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) { | |||
| 1344 | case HAPROXY_PROTOCOL: | 1351 | case HAPROXY_PROTOCOL: |
| 1345 | result.config.curl_config.haproxy_protocol = true; | 1352 | result.config.curl_config.haproxy_protocol = true; |
| 1346 | break; | 1353 | break; |
| 1354 | case NO_PROXY: | ||
| 1355 | strncpy(result.config.curl_config.no_proxy, optarg, DEFAULT_BUFFER_SIZE - 1); | ||
| 1356 | result.config.curl_config.no_proxy[DEFAULT_BUFFER_SIZE - 1] = 0; | ||
| 1357 | break; | ||
| 1347 | case '?': | 1358 | case '?': |
| 1348 | /* print short usage statement if args not parsable */ | 1359 | /* print short usage statement if args not parsable */ |
| 1349 | usage5(); | 1360 | usage5(); |
| @@ -1371,35 +1382,35 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) { | |||
| 1371 | * parameters, like -S and -C combinations */ | 1382 | * parameters, like -S and -C combinations */ |
| 1372 | result.config.curl_config.ssl_version = CURL_SSLVERSION_DEFAULT; | 1383 | result.config.curl_config.ssl_version = CURL_SSLVERSION_DEFAULT; |
| 1373 | if (tls_option_optarg != NULL) { | 1384 | if (tls_option_optarg != NULL) { |
| 1374 | char *plus_ptr = strchr(optarg, '+'); | 1385 | char *plus_ptr = strchr(tls_option_optarg, '+'); |
| 1375 | if (plus_ptr) { | 1386 | if (plus_ptr) { |
| 1376 | got_plus = true; | 1387 | got_plus = true; |
| 1377 | *plus_ptr = '\0'; | 1388 | *plus_ptr = '\0'; |
| 1378 | } | 1389 | } |
| 1379 | 1390 | ||
| 1380 | if (optarg[0] == '2') { | 1391 | if (tls_option_optarg[0] == '2') { |
| 1381 | result.config.curl_config.ssl_version = CURL_SSLVERSION_SSLv2; | 1392 | result.config.curl_config.ssl_version = CURL_SSLVERSION_SSLv2; |
| 1382 | } else if (optarg[0] == '3') { | 1393 | } else if (tls_option_optarg[0] == '3') { |
| 1383 | result.config.curl_config.ssl_version = CURL_SSLVERSION_SSLv3; | 1394 | result.config.curl_config.ssl_version = CURL_SSLVERSION_SSLv3; |
| 1384 | } else if (!strcmp(optarg, "1") || !strcmp(optarg, "1.0")) { | 1395 | } else if (!strcmp(tls_option_optarg, "1") || !strcmp(tls_option_optarg, "1.0")) { |
| 1385 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) | 1396 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) |
| 1386 | result.config.curl_config.ssl_version = CURL_SSLVERSION_TLSv1_0; | 1397 | result.config.curl_config.ssl_version = CURL_SSLVERSION_TLSv1_0; |
| 1387 | #else | 1398 | #else |
| 1388 | result.config.ssl_version = CURL_SSLVERSION_DEFAULT; | 1399 | result.config.ssl_version = CURL_SSLVERSION_DEFAULT; |
| 1389 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ | 1400 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ |
| 1390 | } else if (!strcmp(optarg, "1.1")) { | 1401 | } else if (!strcmp(tls_option_optarg, "1.1")) { |
| 1391 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) | 1402 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) |
| 1392 | result.config.curl_config.ssl_version = CURL_SSLVERSION_TLSv1_1; | 1403 | result.config.curl_config.ssl_version = CURL_SSLVERSION_TLSv1_1; |
| 1393 | #else | 1404 | #else |
| 1394 | result.config.ssl_version = CURL_SSLVERSION_DEFAULT; | 1405 | result.config.ssl_version = CURL_SSLVERSION_DEFAULT; |
| 1395 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ | 1406 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ |
| 1396 | } else if (!strcmp(optarg, "1.2")) { | 1407 | } else if (!strcmp(tls_option_optarg, "1.2")) { |
| 1397 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) | 1408 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) |
| 1398 | result.config.curl_config.ssl_version = CURL_SSLVERSION_TLSv1_2; | 1409 | result.config.curl_config.ssl_version = CURL_SSLVERSION_TLSv1_2; |
| 1399 | #else | 1410 | #else |
| 1400 | result.config.ssl_version = CURL_SSLVERSION_DEFAULT; | 1411 | result.config.ssl_version = CURL_SSLVERSION_DEFAULT; |
| 1401 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ | 1412 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ |
| 1402 | } else if (!strcmp(optarg, "1.3")) { | 1413 | } else if (!strcmp(tls_option_optarg, "1.3")) { |
| 1403 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 52, 0) | 1414 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 52, 0) |
| 1404 | result.config.curl_config.ssl_version = CURL_SSLVERSION_TLSv1_3; | 1415 | result.config.curl_config.ssl_version = CURL_SSLVERSION_TLSv1_3; |
| 1405 | #else | 1416 | #else |
| @@ -1522,8 +1533,8 @@ void print_help(void) { | |||
| 1522 | printf(" %s\n", "-I, --IP-address=ADDRESS"); | 1533 | printf(" %s\n", "-I, --IP-address=ADDRESS"); |
| 1523 | printf(" %s\n", | 1534 | printf(" %s\n", |
| 1524 | "IP address or name (use numeric address if possible to bypass DNS lookup)."); | 1535 | "IP address or name (use numeric address if possible to bypass DNS lookup)."); |
| 1525 | printf(" %s\n", "This overwrites the network address of the target while leaving everything " | 1536 | printf(" %s\n", |
| 1526 | "else (HTTP headers) as they are"); | 1537 | "This overwrites the network address of the target while leaving everything else (HTTP headers) as they are"); |
| 1527 | printf(" %s\n", "-p, --port=INTEGER"); | 1538 | printf(" %s\n", "-p, --port=INTEGER"); |
| 1528 | printf(" %s", _("Port number (default: ")); | 1539 | printf(" %s", _("Port number (default: ")); |
| 1529 | printf("%d)\n", HTTP_PORT); | 1540 | printf("%d)\n", HTTP_PORT); |
| @@ -1587,8 +1598,7 @@ void print_help(void) { | |||
| 1587 | printf(" %s\n", _("String to expect in the content")); | 1598 | printf(" %s\n", _("String to expect in the content")); |
| 1588 | printf(" %s\n", "-u, --url=PATH"); | 1599 | printf(" %s\n", "-u, --url=PATH"); |
| 1589 | printf(" %s\n", _("URL to GET or POST (default: /)")); | 1600 | printf(" %s\n", _("URL to GET or POST (default: /)")); |
| 1590 | printf(" %s\n", _("This is the part after the address in a URL, so for " | 1601 | printf(" %s\n", _("This is the part after the address in a URL, so for \"https://example.com/index.html\" it would be '-u /index.html'")); |
| 1591 | "\"https://example.com/index.html\" it would be '-u /index.html'")); | ||
| 1592 | printf(" %s\n", "-P, --post=STRING"); | 1602 | printf(" %s\n", "-P, --post=STRING"); |
| 1593 | printf(" %s\n", _("URL decoded http POST data")); | 1603 | printf(" %s\n", _("URL decoded http POST data")); |
| 1594 | printf(" %s\n", | 1604 | printf(" %s\n", |
| @@ -1614,6 +1624,18 @@ void print_help(void) { | |||
| 1614 | printf(" %s\n", "--state-regex=STATE"); | 1624 | printf(" %s\n", "--state-regex=STATE"); |
| 1615 | printf(" %s\n", _("Return STATE if regex is found, OK if not. STATE can be one of " | 1625 | printf(" %s\n", _("Return STATE if regex is found, OK if not. STATE can be one of " |
| 1616 | "\"critical\",\"warning\"")); | 1626 | "\"critical\",\"warning\"")); |
| 1627 | printf(" %s\n", "-x, --proxy=PROXY_SERVER"); | ||
| 1628 | printf(" %s\n", _("Specify the proxy in form of <scheme>://<host(name)>:<port>")); | ||
| 1629 | printf(" %s\n", _("Available schemes are http, https, socks4, socks4a, socks5, socks5h")); | ||
| 1630 | printf(" %s\n", _("If port is not specified, libcurl defaults to 1080")); | ||
| 1631 | printf(" %s\n", _("This value will be set as CURLOPT_PROXY")); | ||
| 1632 | printf(" %s\n", "--noproxy=COMMA_SEPARATED_LIST"); | ||
| 1633 | printf(" %s\n", _("Specify hostnames, addresses and subnets where proxy should not be used")); | ||
| 1634 | printf(" %s\n", _("Example usage: \"example.com,::1,1.1.1.1,localhost,192.168.0.0/16\"")); | ||
| 1635 | printf(" %s\n", _("Do not use brackets when specifying IPv6 addresses")); | ||
| 1636 | printf(" %s\n", _("Special case when an item is '*' : matches all hosts/addresses " | ||
| 1637 | "and effectively disables proxy.")); | ||
| 1638 | printf(" %s\n", _("This value will be set as CURLOPT_NOPROXY")); | ||
| 1617 | printf(" %s\n", "-a, --authorization=AUTH_PAIR"); | 1639 | printf(" %s\n", "-a, --authorization=AUTH_PAIR"); |
| 1618 | printf(" %s\n", _("Username:password on sites with basic authentication")); | 1640 | printf(" %s\n", _("Username:password on sites with basic authentication")); |
| 1619 | printf(" %s\n", "-b, --proxy-authorization=AUTH_PAIR"); | 1641 | printf(" %s\n", "-b, --proxy-authorization=AUTH_PAIR"); |
| @@ -1722,10 +1744,39 @@ void print_help(void) { | |||
| 1722 | #endif | 1744 | #endif |
| 1723 | 1745 | ||
| 1724 | printf("\n %s\n", "CHECK WEBSERVER CONTENT VIA PROXY:"); | 1746 | printf("\n %s\n", "CHECK WEBSERVER CONTENT VIA PROXY:"); |
| 1725 | printf(" %s\n", _("It is recommended to use an environment proxy like:")); | 1747 | printf(" %s\n", _("Proxies are specified or disabled for certain hosts/addresses using environment variables" |
| 1726 | printf(" %s\n", | 1748 | " or -x/--proxy and --noproxy arguments:")); |
| 1727 | _("http_proxy=http://192.168.100.35:3128 ./check_curl -H www.monitoring-plugins.org")); | 1749 | printf(" %s\n", _("Checked environment variables: all_proxy, http_proxy, https_proxy, no_proxy")); |
| 1728 | printf(" %s\n", _("legacy proxy requests in check_http style still work:")); | 1750 | printf(" %s\n", _("Environment variables can also be given in uppercase, but the lowercase ones will " |
| 1751 | "take predence if both are defined.")); | ||
| 1752 | printf(" %s\n", _("The environment variables are overwritten by -x/--proxy and --noproxy arguments:")); | ||
| 1753 | printf(" %s\n", _("all_proxy/ALL_PROXY environment variables are read first, but protocol " | ||
| 1754 | "specific environment variables override them.")); | ||
| 1755 | printf(" %s\n", _("If SSL is enabled and used, https_proxy/HTTPS_PROXY will be checked and overwrite " | ||
| 1756 | "http_proxy/HTTPS_PROXY.")); | ||
| 1757 | printf(" %s\n", _("Curl accepts proxies using http, https, socks4, socks4a, socks5 and socks5h schemes.")); | ||
| 1758 | printf(" %s\n", _("http_proxy=http://192.168.100.35:3128 ./check_curl -H www.monitoring-plugins.org")); | ||
| 1759 | printf(" %s\n", _("http_proxy=http://used.proxy.com HTTP_PROXY=http://ignored.proxy.com ./check_curl -H www.monitoring-plugins.org")); | ||
| 1760 | printf(" %s\n", _(" Lowercase http_proxy takes predence over uppercase HTTP_PROXY")); | ||
| 1761 | printf(" %s\n", _("./check_curl -H www.monitoring-plugins.org -x http://192.168.100.35:3128")); | ||
| 1762 | printf(" %s\n", _("http_proxy=http://unused.proxy1.com HTTP_PROXY=http://unused.proxy2.com ./check_curl " | ||
| 1763 | "-H www.monitoring-plugins.org --proxy http://used.proxy")); | ||
| 1764 | printf(" %s\n", _(" Proxy specified by --proxy overrides any proxy specified by environment variable.")); | ||
| 1765 | printf(" %s\n", _(" Curl uses port 1080 by default as port is not specified")); | ||
| 1766 | printf(" %s\n", _("HTTPS_PROXY=http://192.168.100.35:3128 ./check_curl -H www.monitoring-plugins.org --ssl")); | ||
| 1767 | printf(" %s\n", _(" HTTPS_PROXY is read as --ssl is toggled")); | ||
| 1768 | printf(" %s\n", _("./check_curl -H www.monitoring-plugins.org --proxy socks5h://192.168.122.21")); | ||
| 1769 | printf(" %s\n", _("./check_curl -H www.monitoring-plugins.org -x http://unused.proxy.com --noproxy '*'")); | ||
| 1770 | printf(" %s\n", _(" Disabled proxy for all hosts by using '*' in no_proxy .")); | ||
| 1771 | printf(" %s\n", _("NO_PROXY=www.monitoring-plugins.org ./check_curl -H www.monitoring-plugins.org -x http://unused.proxy.com")); | ||
| 1772 | printf(" %s\n", _(" Exact matches with the hostname/address work.")); | ||
| 1773 | printf(" %s\n", _("no_proxy=192.168.178.0/24 ./check_curl -I 192.168.178.10 -x http://proxy.acme.org")); | ||
| 1774 | printf(" %s\n", _("no_proxy=acme.org ./check_curl -H nonpublic.internalwebapp.acme.org -x http://proxy.acme.org")); | ||
| 1775 | printf(" %s\n", _(" Do not use proxy when accessing internal domains/addresses, but use a default proxy when accessing public web.")); | ||
| 1776 | printf(" %s\n", _(" IMPORTANT: Check_curl can not always determine whether itself or the proxy will " | ||
| 1777 | "resolve a hostname before sending a request and getting an answer." | ||
| 1778 | "This can lead to DNS resolvation issues if hostname is only resolvable over proxy.")); | ||
| 1779 | printf(" %s\n", _("Legacy proxy requests in check_http style still work:")); | ||
| 1729 | printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u http://www.monitoring-plugins.org/ " | 1780 | printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u http://www.monitoring-plugins.org/ " |
| 1730 | "-H www.monitoring-plugins.org")); | 1781 | "-H www.monitoring-plugins.org")); |
| 1731 | 1782 | ||
| @@ -1756,13 +1807,15 @@ void print_usage(void) { | |||
| 1756 | printf(" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n", progname); | 1807 | printf(" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n", progname); |
| 1757 | printf(" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate " | 1808 | printf(" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate " |
| 1758 | "file>] [-D]\n"); | 1809 | "file>] [-D]\n"); |
| 1759 | printf(" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n"); | 1810 | printf(" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-x <proxy>]\n"); |
| 1760 | printf(" [-b proxy_auth] [-f <ok|warning|critical|follow|sticky|stickyport|curl>]\n"); | 1811 | printf(" [-a auth] [-b proxy_auth] [-f " |
| 1812 | "<ok|warning|critical|follow|sticky|stickyport|curl>]\n"); | ||
| 1761 | printf(" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive " | 1813 | printf(" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive " |
| 1762 | "regex>]\n"); | 1814 | "regex>]\n"); |
| 1763 | printf(" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); | 1815 | printf(" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); |
| 1764 | printf(" [-A string] [-k string] [-S <version>] [--sni] [--haproxy-protocol]\n"); | 1816 | printf(" [-A string] [-k string] [-S <version>] [--sni] [--haproxy-protocol]\n"); |
| 1765 | printf(" [-T <content-type>] [-j method]\n"); | 1817 | printf(" [-T <content-type>] [-j method]\n"); |
| 1818 | printf(" [--noproxy=<comma separated list of hosts, IP addresses, IP CIDR subnets>\n"); | ||
| 1766 | printf(" [--http-version=<version>] [--enable-automatic-decompression]\n"); | 1819 | printf(" [--http-version=<version>] [--enable-automatic-decompression]\n"); |
| 1767 | printf(" [--cookie-jar=<cookie jar file>\n"); | 1820 | printf(" [--cookie-jar=<cookie jar file>\n"); |
| 1768 | printf(" %s -H <vhost> | -I <IP-address> -C <warn_age>[,<crit_age>]\n", progname); | 1821 | printf(" %s -H <vhost> | -I <IP-address> -C <warn_age>[,<crit_age>]\n", progname); |
diff --git a/plugins/check_curl.d/check_curl_helpers.c b/plugins/check_curl.d/check_curl_helpers.c index ad31b847..4372dc0b 100644 --- a/plugins/check_curl.d/check_curl_helpers.c +++ b/plugins/check_curl.d/check_curl_helpers.c | |||
| @@ -3,8 +3,11 @@ | |||
| 3 | #include <arpa/inet.h> | 3 | #include <arpa/inet.h> |
| 4 | #include <netinet/in.h> | 4 | #include <netinet/in.h> |
| 5 | #include <netdb.h> | 5 | #include <netdb.h> |
| 6 | #include <stdint.h> | ||
| 7 | #include <stdio.h> | ||
| 6 | #include <stdlib.h> | 8 | #include <stdlib.h> |
| 7 | #include <string.h> | 9 | #include <string.h> |
| 10 | #include <sys/socket.h> | ||
| 8 | #include "../utils.h" | 11 | #include "../utils.h" |
| 9 | #include "check_curl.d/config.h" | 12 | #include "check_curl.d/config.h" |
| 10 | #include "output.h" | 13 | #include "output.h" |
| @@ -116,6 +119,107 @@ check_curl_configure_curl(const check_curl_static_curl_config config, | |||
| 116 | curl_easy_setopt(result.curl_state.curl, CURLOPT_TIMEOUT, config.socket_timeout), | 119 | curl_easy_setopt(result.curl_state.curl, CURLOPT_TIMEOUT, config.socket_timeout), |
| 117 | "CURLOPT_TIMEOUT"); | 120 | "CURLOPT_TIMEOUT"); |
| 118 | 121 | ||
| 122 | /* set proxy */ | ||
| 123 | /* http(s) proxy can either be given from the command line, or taken from environment variables */ | ||
| 124 | /* socks4(a) / socks5(h) proxy should be given using the command line */ | ||
| 125 | |||
| 126 | /* first source to check is the environment variables */ | ||
| 127 | /* lower case proxy environment variables are almost always accepted, while some programs also checking | ||
| 128 | uppercase ones. discover both, but take the lowercase one if both are present */ | ||
| 129 | |||
| 130 | /* extra information: libcurl does not discover the uppercase version HTTP_PROXY due to security reasons */ | ||
| 131 | /* https://github.com/curl/curl/blob/d445f2d930ae701039518d695481ee53b8490521/lib/url.c#L1987 */ | ||
| 132 | |||
| 133 | /* first environment variable to read is all_proxy. it can be overridden by protocol specific environment variables */ | ||
| 134 | char *all_proxy_env, *all_proxy_uppercase_env; | ||
| 135 | all_proxy_env = getenv("all_proxy"); | ||
| 136 | all_proxy_uppercase_env = getenv("ALL_PROXY"); | ||
| 137 | if (all_proxy_env != NULL && strlen(all_proxy_env)){ | ||
| 138 | working_state.curlopt_proxy = strdup(all_proxy_env); | ||
| 139 | if (all_proxy_uppercase_env != NULL && verbose >= 1) { | ||
| 140 | printf("* cURL ignoring environment variable 'ALL_PROXY' as 'all_proxy' is set\n"); | ||
| 141 | } | ||
| 142 | } else if (all_proxy_uppercase_env != NULL && strlen(all_proxy_uppercase_env) > 0) { | ||
| 143 | working_state.curlopt_proxy = strdup(all_proxy_uppercase_env); | ||
| 144 | } | ||
| 145 | |||
| 146 | /* second environment variable to read is http_proxy. only set curlopt_proxy if ssl is not toggled */ | ||
| 147 | char *http_proxy_env, *http_proxy_uppercase_env; | ||
| 148 | http_proxy_env = getenv("http_proxy"); | ||
| 149 | http_proxy_uppercase_env = getenv("HTTP_PROXY"); | ||
| 150 | if (!working_state.use_ssl){ | ||
| 151 | if (http_proxy_env != NULL && strlen(http_proxy_env) > 0) { | ||
| 152 | working_state.curlopt_proxy = strdup(http_proxy_env); | ||
| 153 | if (http_proxy_uppercase_env != NULL && verbose >= 1) { | ||
| 154 | printf("* cURL ignoring environment variable 'HTTP_PROXY' as 'http_proxy' is set\n"); | ||
| 155 | } | ||
| 156 | } else if (http_proxy_uppercase_env != NULL && strlen(http_proxy_uppercase_env) > 0) { | ||
| 157 | working_state.curlopt_proxy = strdup(http_proxy_uppercase_env); | ||
| 158 | } | ||
| 159 | } | ||
| 160 | #ifdef LIBCURL_FEATURE_SSL | ||
| 161 | /* optionally read https_proxy environment variable and set curlopt_proxy if ssl is toggled */ | ||
| 162 | char *https_proxy_env, *https_proxy_uppercase_env; | ||
| 163 | https_proxy_env = getenv("https_proxy"); | ||
| 164 | https_proxy_uppercase_env = getenv("HTTPS_PROXY"); | ||
| 165 | if (working_state.use_ssl) { | ||
| 166 | if (https_proxy_env != NULL && strlen(https_proxy_env) > 0) { | ||
| 167 | working_state.curlopt_proxy = strdup(https_proxy_env); | ||
| 168 | if (https_proxy_uppercase_env != NULL && verbose >= 1) { | ||
| 169 | printf("* cURL ignoring environment variable 'HTTPS_PROXY' as 'https_proxy' is set\n"); | ||
| 170 | } | ||
| 171 | } | ||
| 172 | else if (https_proxy_uppercase_env != NULL && strlen(https_proxy_uppercase_env) >= 0) { | ||
| 173 | working_state.curlopt_proxy = strdup(https_proxy_uppercase_env); | ||
| 174 | } | ||
| 175 | } | ||
| 176 | #endif /* LIBCURL_FEATURE_SSL */ | ||
| 177 | |||
| 178 | /* second source to check for proxies is command line argument, overwriting the environment variables */ | ||
| 179 | if (strlen(config.proxy) > 0) { | ||
| 180 | working_state.curlopt_proxy = strdup(config.proxy); | ||
| 181 | } | ||
| 182 | |||
| 183 | if (working_state.curlopt_proxy != NULL && strlen(working_state.curlopt_proxy)){ | ||
| 184 | handle_curl_option_return_code( | ||
| 185 | curl_easy_setopt(result.curl_state.curl, CURLOPT_PROXY, working_state.curlopt_proxy), "CURLOPT_PROXY"); | ||
| 186 | if (verbose >= 1) { | ||
| 187 | printf("* curl CURLOPT_PROXY: %s\n", working_state.curlopt_proxy); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | /* set no_proxy */ | ||
| 192 | /* first source to check is environment variables */ | ||
| 193 | char *no_proxy_env, *no_proxy_uppercase_env; | ||
| 194 | no_proxy_env = getenv("no_proxy"); | ||
| 195 | no_proxy_uppercase_env = getenv("NO_PROXY"); | ||
| 196 | if (no_proxy_env != NULL && strlen(no_proxy_env)){ | ||
| 197 | working_state.curlopt_noproxy = strdup(no_proxy_env); | ||
| 198 | if (no_proxy_uppercase_env != NULL && verbose >= 1){ | ||
| 199 | printf("* cURL ignoring environment variable 'NO_PROXY' as 'no_proxy' is set\n"); | ||
| 200 | } | ||
| 201 | }else if (no_proxy_uppercase_env != NULL && strlen(no_proxy_uppercase_env) > 0){ | ||
| 202 | working_state.curlopt_noproxy = strdup(no_proxy_uppercase_env); | ||
| 203 | } | ||
| 204 | |||
| 205 | /* second source to check for no_proxy is command line argument, overwriting the environment variables */ | ||
| 206 | if (strlen(config.no_proxy) > 0) { | ||
| 207 | working_state.curlopt_noproxy = strdup(config.no_proxy); | ||
| 208 | } | ||
| 209 | |||
| 210 | if ( working_state.curlopt_noproxy != NULL && strlen(working_state.curlopt_noproxy)){ | ||
| 211 | handle_curl_option_return_code( | ||
| 212 | curl_easy_setopt(result.curl_state.curl, CURLOPT_NOPROXY, working_state.curlopt_noproxy), "CURLOPT_NOPROXY"); | ||
| 213 | if (verbose >= 1) { | ||
| 214 | printf("* curl CURLOPT_NOPROXY: %s\n", working_state.curlopt_noproxy); | ||
| 215 | } | ||
| 216 | } | ||
| 217 | |||
| 218 | int proxy_resolves_hostname = determine_hostname_resolver(working_state, config); | ||
| 219 | if (verbose >= 1) { | ||
| 220 | printf("* proxy_resolves_hostname: %d\n", proxy_resolves_hostname); | ||
| 221 | } | ||
| 222 | |||
| 119 | /* enable haproxy protocol */ | 223 | /* enable haproxy protocol */ |
| 120 | if (config.haproxy_protocol) { | 224 | if (config.haproxy_protocol) { |
| 121 | handle_curl_option_return_code( | 225 | handle_curl_option_return_code( |
| @@ -123,11 +227,11 @@ check_curl_configure_curl(const check_curl_static_curl_config config, | |||
| 123 | "CURLOPT_HAPROXYPROTOCOL"); | 227 | "CURLOPT_HAPROXYPROTOCOL"); |
| 124 | } | 228 | } |
| 125 | 229 | ||
| 126 | // fill dns resolve cache to make curl connect to the given server_address instead of the | 230 | /* fill dns resolve cache to make curl connect to the given server_address instead of the */ |
| 127 | // host_name, only required for ssl, because we use the host_name later on to make SNI happy | 231 | /* host_name, only required for ssl, because we use the host_name later on to make SNI happy */ |
| 128 | char dnscache[DEFAULT_BUFFER_SIZE]; | 232 | char dnscache[DEFAULT_BUFFER_SIZE]; |
| 129 | char addrstr[DEFAULT_BUFFER_SIZE / 2]; | 233 | char addrstr[DEFAULT_BUFFER_SIZE / 2]; |
| 130 | if (working_state.use_ssl && working_state.host_name != NULL) { | 234 | if (working_state.use_ssl && working_state.host_name != NULL && !proxy_resolves_hostname ) { |
| 131 | char *tmp_mod_address; | 235 | char *tmp_mod_address; |
| 132 | 236 | ||
| 133 | /* lookup_host() requires an IPv6 address without the brackets. */ | 237 | /* lookup_host() requires an IPv6 address without the brackets. */ |
| @@ -562,7 +666,7 @@ check_curl_configure_curl(const check_curl_static_curl_config config, | |||
| 562 | 666 | ||
| 563 | void handle_curl_option_return_code(CURLcode res, const char *option) { | 667 | void handle_curl_option_return_code(CURLcode res, const char *option) { |
| 564 | if (res != CURLE_OK) { | 668 | if (res != CURLE_OK) { |
| 565 | die(STATE_CRITICAL, _("Error while setting cURL option '%s': cURL returned %d - %s"), | 669 | die(STATE_CRITICAL, _("Error while setting cURL option '%s': cURL returned %d - %s\n"), |
| 566 | option, res, curl_easy_strerror(res)); | 670 | option, res, curl_easy_strerror(res)); |
| 567 | } | 671 | } |
| 568 | } | 672 | } |
| @@ -589,6 +693,8 @@ check_curl_working_state check_curl_working_state_init() { | |||
| 589 | .serverPort = HTTP_PORT, | 693 | .serverPort = HTTP_PORT, |
| 590 | .use_ssl = false, | 694 | .use_ssl = false, |
| 591 | .no_body = false, | 695 | .no_body = false, |
| 696 | .curlopt_proxy = NULL, | ||
| 697 | .curlopt_noproxy = NULL, | ||
| 592 | }; | 698 | }; |
| 593 | return result; | 699 | return result; |
| 594 | } | 700 | } |
| @@ -612,6 +718,8 @@ check_curl_config check_curl_config_init() { | |||
| 612 | .ca_cert = NULL, | 718 | .ca_cert = NULL, |
| 613 | .verify_peer_and_host = false, | 719 | .verify_peer_and_host = false, |
| 614 | .user_agent = {'\0'}, | 720 | .user_agent = {'\0'}, |
| 721 | .proxy = "", | ||
| 722 | .no_proxy = "", | ||
| 615 | .proxy_auth = "", | 723 | .proxy_auth = "", |
| 616 | .user_auth = "", | 724 | .user_auth = "", |
| 617 | .http_content_type = NULL, | 725 | .http_content_type = NULL, |
| @@ -1295,3 +1403,342 @@ char *fmt_url(check_curl_working_state workingState) { | |||
| 1295 | 1403 | ||
| 1296 | return url; | 1404 | return url; |
| 1297 | } | 1405 | } |
| 1406 | |||
| 1407 | int determine_hostname_resolver(const check_curl_working_state working_state, const check_curl_static_curl_config config){ | ||
| 1408 | char *host_name_display = "NULL"; | ||
| 1409 | unsigned long host_name_len = 0; | ||
| 1410 | if( working_state.host_name){ | ||
| 1411 | host_name_len = strlen(working_state.host_name); | ||
| 1412 | host_name_display = working_state.host_name; | ||
| 1413 | } | ||
| 1414 | |||
| 1415 | /* IPv4 or IPv6 version of the address */ | ||
| 1416 | char *server_address_clean = strdup(working_state.server_address); | ||
| 1417 | /* server address might be a full length ipv6 address encapsulated in square brackets */ | ||
| 1418 | if ((strnlen(working_state.server_address, MAX_IPV4_HOSTLENGTH) > 2) && (working_state.server_address[0] == '[') && (working_state.server_address[strlen(working_state.server_address)-1] == ']') ) { | ||
| 1419 | server_address_clean = strndup( working_state.server_address + 1, strlen(working_state.server_address) - 2); | ||
| 1420 | } | ||
| 1421 | |||
| 1422 | /* check curlopt_noproxy option first */ | ||
| 1423 | /* https://curl.se/libcurl/c/CURLOPT_NOPROXY.html */ | ||
| 1424 | |||
| 1425 | /* curlopt_noproxy is specified as a comma separated list of | ||
| 1426 | direct IPv4 or IPv6 addresses e.g 130.133.8.40, 2001:4860:4802:32::a , | ||
| 1427 | IPv4 or IPv6 CIDR regions e.g 10.241.0.0/16 , abcd:ef01:2345::/48 , | ||
| 1428 | direct hostnames e.g example.com, google.de */ | ||
| 1429 | |||
| 1430 | if (working_state.curlopt_noproxy != NULL){ | ||
| 1431 | char* curlopt_noproxy_copy = strdup( working_state.curlopt_noproxy); | ||
| 1432 | char* noproxy_item = strtok(curlopt_noproxy_copy, ","); | ||
| 1433 | while(noproxy_item != NULL){ | ||
| 1434 | unsigned long noproxy_item_len = strlen(noproxy_item); | ||
| 1435 | |||
| 1436 | /* According to the CURLOPT_NOPROXY documentation: */ | ||
| 1437 | /* https://curl.se/libcurl/c/CURLOPT_NOPROXY.html */ | ||
| 1438 | /* The only wildcard available is a single * character, which matches all hosts, and effectively disables the proxy. */ | ||
| 1439 | if ( strlen(noproxy_item) == 1 && noproxy_item[0] == '*'){ | ||
| 1440 | if (verbose >= 1){ | ||
| 1441 | printf("* noproxy includes '*' which disables proxy for all host name incl. : %s / server address incl. : %s\n", host_name_display , server_address_clean); | ||
| 1442 | } | ||
| 1443 | free(curlopt_noproxy_copy); | ||
| 1444 | free(server_address_clean); | ||
| 1445 | return 0; | ||
| 1446 | } | ||
| 1447 | |||
| 1448 | /* direct comparison with the server_address */ | ||
| 1449 | if( server_address_clean != NULL && strlen(server_address_clean) == strlen(noproxy_item) && strcmp(server_address_clean, noproxy_item) == 0){ | ||
| 1450 | if (verbose >= 1){ | ||
| 1451 | printf("* server_address is in the no_proxy list: %s\n", noproxy_item); | ||
| 1452 | } | ||
| 1453 | free(curlopt_noproxy_copy); | ||
| 1454 | free(server_address_clean); | ||
| 1455 | return 0; | ||
| 1456 | } | ||
| 1457 | |||
| 1458 | /* direct comparison with the host_name */ | ||
| 1459 | if( working_state.host_name != NULL && host_name_len == noproxy_item_len && strcmp(working_state.host_name, noproxy_item) == 0){ | ||
| 1460 | if (verbose >= 1){ | ||
| 1461 | printf("* host_name is in the no_proxy list: %s\n", noproxy_item); | ||
| 1462 | } | ||
| 1463 | free(curlopt_noproxy_copy); | ||
| 1464 | free(server_address_clean); | ||
| 1465 | return 0; | ||
| 1466 | } | ||
| 1467 | |||
| 1468 | /* check if hostname is a subdomain of the item, e.g www.example.com when token is example.com */ | ||
| 1469 | /* subdomain1.acme.com will not will use a proxy if you only specify 'acme' in the noproxy */ | ||
| 1470 | /* check if noproxy_item is a suffix */ | ||
| 1471 | /* check if the character just before the suffix is '.' */ | ||
| 1472 | if( working_state.host_name != NULL && host_name_len > noproxy_item_len){ | ||
| 1473 | unsigned long suffix_start_idx = host_name_len - noproxy_item_len; | ||
| 1474 | if (strcmp(working_state.host_name + suffix_start_idx, noproxy_item ) == 0 && working_state.host_name[suffix_start_idx-1] == '.' ){ | ||
| 1475 | if (verbose >= 1){ | ||
| 1476 | printf("* host_name: %s is a subdomain of the no_proxy list item: %s\n", working_state.host_name , noproxy_item); | ||
| 1477 | } | ||
| 1478 | free(curlopt_noproxy_copy); | ||
| 1479 | free(server_address_clean); | ||
| 1480 | return 0; | ||
| 1481 | } | ||
| 1482 | } | ||
| 1483 | |||
| 1484 | // noproxy_item could be a CIDR IP range | ||
| 1485 | if( server_address_clean != NULL && strlen(server_address_clean)){ | ||
| 1486 | |||
| 1487 | int ip_addr_inside_cidr_ret = ip_addr_inside_cidr(noproxy_item, server_address_clean); | ||
| 1488 | |||
| 1489 | switch(ip_addr_inside_cidr_ret){ | ||
| 1490 | case 1: | ||
| 1491 | return 0; | ||
| 1492 | break; | ||
| 1493 | case 0: | ||
| 1494 | if(verbose >= 1){ | ||
| 1495 | printf("server address: %s is not inside IP cidr: %s\n", server_address_clean, noproxy_item); | ||
| 1496 | } | ||
| 1497 | break; | ||
| 1498 | case -1: | ||
| 1499 | if(verbose >= 1){ | ||
| 1500 | printf("could not fully determine if server address: %s is inside the IP cidr: %s\n", server_address_clean, noproxy_item); | ||
| 1501 | } | ||
| 1502 | break; | ||
| 1503 | } | ||
| 1504 | } | ||
| 1505 | |||
| 1506 | noproxy_item = strtok(NULL, ","); | ||
| 1507 | } | ||
| 1508 | |||
| 1509 | free(curlopt_noproxy_copy); | ||
| 1510 | } | ||
| 1511 | |||
| 1512 | if (working_state.curlopt_proxy != NULL){ | ||
| 1513 | // Libcurl documentation | ||
| 1514 | // Setting the proxy string to "" (an empty string) explicitly disables the use of a proxy, even if there is an environment variable set for it. | ||
| 1515 | if ( strlen(working_state.curlopt_proxy) == 0){ | ||
| 1516 | return 0; | ||
| 1517 | } | ||
| 1518 | |||
| 1519 | if ( strncmp( working_state.curlopt_proxy, "http://", 7) == 0){ | ||
| 1520 | if (verbose >= 1){ | ||
| 1521 | printf("* proxy scheme is http, proxy: %s resolves host: %s or server_address: %s\n", working_state.curlopt_proxy, host_name_display, server_address_clean); | ||
| 1522 | } | ||
| 1523 | free(server_address_clean); | ||
| 1524 | return 1; | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | if ( strncmp( working_state.curlopt_proxy, "https://", 8) == 0){ | ||
| 1528 | if (verbose >= 1){ | ||
| 1529 | printf("* proxy scheme is https, proxy: %s resolves host: %s or server_address: %s\n", working_state.curlopt_proxy, host_name_display, server_address_clean); | ||
| 1530 | } | ||
| 1531 | free(server_address_clean); | ||
| 1532 | return 1; | ||
| 1533 | } | ||
| 1534 | |||
| 1535 | if ( strncmp( working_state.curlopt_proxy, "socks4://", 9) == 0){ | ||
| 1536 | if (verbose >= 1){ | ||
| 1537 | printf("* proxy scheme is socks, proxy: %s does not resolve host: %s or server_address: %s\n", working_state.curlopt_proxy, host_name_display, server_address_clean); | ||
| 1538 | } | ||
| 1539 | free(server_address_clean); | ||
| 1540 | return 0; | ||
| 1541 | } | ||
| 1542 | |||
| 1543 | if ( strncmp( working_state.curlopt_proxy, "socks4a://", 10) == 0){ | ||
| 1544 | if (verbose >= 1){ | ||
| 1545 | printf("* proxy scheme is socks4a, proxy: %s resolves host: %s or server_address: %s\n", working_state.curlopt_proxy, host_name_display, server_address_clean); | ||
| 1546 | } | ||
| 1547 | free(server_address_clean); | ||
| 1548 | return 1; | ||
| 1549 | } | ||
| 1550 | |||
| 1551 | if ( strncmp( working_state.curlopt_proxy, "socks5://", 9) == 0){ | ||
| 1552 | if (verbose >= 1){ | ||
| 1553 | printf("* proxy scheme is socks5, proxy: %s does not resolve host: %s or server_address: %s\n", working_state.curlopt_proxy, host_name_display, server_address_clean); | ||
| 1554 | } | ||
| 1555 | free(server_address_clean); | ||
| 1556 | return 0; | ||
| 1557 | } | ||
| 1558 | |||
| 1559 | if ( strncmp( working_state.curlopt_proxy, "socks5h://", 10) == 0){ | ||
| 1560 | if (verbose >= 1){ | ||
| 1561 | printf("* proxy scheme is socks5h, proxy: %s resolves host: %s or server_address: %s\n", working_state.curlopt_proxy, host_name_display, server_address_clean); | ||
| 1562 | } | ||
| 1563 | free(server_address_clean); | ||
| 1564 | return 1; | ||
| 1565 | } | ||
| 1566 | |||
| 1567 | // Libcurl documentation: | ||
| 1568 | // Without a scheme prefix, CURLOPT_PROXYTYPE can be used to specify which kind of proxy the string identifies. | ||
| 1569 | // We do not set this value | ||
| 1570 | // Without a scheme, it is treated as an http proxy | ||
| 1571 | |||
| 1572 | return 1; | ||
| 1573 | } | ||
| 1574 | |||
| 1575 | if (verbose >= 1){ | ||
| 1576 | printf("* proxy scheme is unknown/unavailable, no proxy is assumed for host: %s or server_address: %s\n", host_name_display, server_address_clean); | ||
| 1577 | } | ||
| 1578 | |||
| 1579 | free(server_address_clean); | ||
| 1580 | return 0; | ||
| 1581 | } | ||
| 1582 | |||
| 1583 | int ip_addr_inside_cidr(const char* cidr_region_or_ip_addr, const char* target_ip){ | ||
| 1584 | unsigned int slash_count = 0; | ||
| 1585 | unsigned int last_slash_idx = 0; | ||
| 1586 | for(size_t i = 0; i < strlen(cidr_region_or_ip_addr); i++){ | ||
| 1587 | if(cidr_region_or_ip_addr[i] == '/'){ | ||
| 1588 | slash_count++; | ||
| 1589 | last_slash_idx = (unsigned int)i; | ||
| 1590 | } | ||
| 1591 | } | ||
| 1592 | |||
| 1593 | char *cidr_ip_part = NULL; | ||
| 1594 | int prefix_length = 0; | ||
| 1595 | |||
| 1596 | if (slash_count == 0) { | ||
| 1597 | cidr_ip_part = strdup(cidr_region_or_ip_addr); | ||
| 1598 | if (!cidr_ip_part) return -1; | ||
| 1599 | } else if (slash_count == 1) { | ||
| 1600 | cidr_ip_part = strndup(cidr_region_or_ip_addr, last_slash_idx); | ||
| 1601 | if (!cidr_ip_part) return -1; | ||
| 1602 | |||
| 1603 | errno = 0; | ||
| 1604 | long long tmp = strtoll(cidr_region_or_ip_addr + last_slash_idx + 1, NULL, 10); | ||
| 1605 | if (errno == ERANGE) { | ||
| 1606 | if (verbose >= 1) { | ||
| 1607 | printf("cidr_region_or_ip: %s , could not parse subnet length\n", cidr_region_or_ip_addr); | ||
| 1608 | } | ||
| 1609 | free(cidr_ip_part); | ||
| 1610 | return -1; | ||
| 1611 | } | ||
| 1612 | prefix_length = (int)tmp; | ||
| 1613 | } else { | ||
| 1614 | printf("cidr_region_or_ip: %s , has %d number of '/' characters, is not a valid cidr_region or IP\n", cidr_region_or_ip_addr, slash_count); | ||
| 1615 | return -1; | ||
| 1616 | } | ||
| 1617 | |||
| 1618 | int cidr_addr_family, target_addr_family; | ||
| 1619 | if (strchr(cidr_ip_part, ':')){ | ||
| 1620 | cidr_addr_family = AF_INET6; | ||
| 1621 | } else { | ||
| 1622 | cidr_addr_family = AF_INET; | ||
| 1623 | } | ||
| 1624 | |||
| 1625 | if (strchr(target_ip, ':')){ | ||
| 1626 | target_addr_family = AF_INET6; | ||
| 1627 | } else { | ||
| 1628 | target_addr_family = AF_INET; | ||
| 1629 | } | ||
| 1630 | |||
| 1631 | if (cidr_addr_family != target_addr_family){ | ||
| 1632 | if (verbose >= 1){ | ||
| 1633 | printf("cidr address: %s and target ip address: %s have different address families\n", cidr_ip_part, target_ip); | ||
| 1634 | } | ||
| 1635 | free(cidr_ip_part); | ||
| 1636 | return 0; | ||
| 1637 | } | ||
| 1638 | |||
| 1639 | // If no prefix is given, treat the cidr as a single address (full-length prefix) | ||
| 1640 | if (slash_count == 0) { | ||
| 1641 | prefix_length = (cidr_addr_family == AF_INET) ? 32 : 128; | ||
| 1642 | } | ||
| 1643 | |||
| 1644 | int max_bits = (cidr_addr_family == AF_INET) ? 32u : 128u; | ||
| 1645 | if (prefix_length < 0 || prefix_length > max_bits) { | ||
| 1646 | if (verbose >= 1) { | ||
| 1647 | printf("cidr_region_or_ip: %s has invalid prefix length: %u\n", cidr_region_or_ip_addr, prefix_length); | ||
| 1648 | } | ||
| 1649 | free(cidr_ip_part); | ||
| 1650 | return -1; | ||
| 1651 | } | ||
| 1652 | |||
| 1653 | if (verbose >= 1){ | ||
| 1654 | printf("cidr_region_or_ip: %s , has prefix length: %u\n", cidr_region_or_ip_addr, prefix_length); | ||
| 1655 | } | ||
| 1656 | |||
| 1657 | int inet_pton_rc; | ||
| 1658 | uint8_t *cidr_bytes = NULL; | ||
| 1659 | uint8_t *target_bytes = NULL; | ||
| 1660 | uint8_t cidr_buf[16]; | ||
| 1661 | uint8_t target_buf[16]; | ||
| 1662 | size_t total_bytes = 0; | ||
| 1663 | |||
| 1664 | if (cidr_addr_family == AF_INET) { | ||
| 1665 | struct in_addr cidr_ipv4; | ||
| 1666 | struct in_addr target_ipv4; | ||
| 1667 | inet_pton_rc = inet_pton(AF_INET, cidr_ip_part, &cidr_ipv4); | ||
| 1668 | if (inet_pton_rc != 1) { | ||
| 1669 | if (verbose >= 1) { | ||
| 1670 | printf("ip string: %s contains characters not valid for its address family: IPv4\n", cidr_ip_part); | ||
| 1671 | } | ||
| 1672 | free(cidr_ip_part); | ||
| 1673 | return -1; | ||
| 1674 | } | ||
| 1675 | inet_pton_rc = inet_pton(AF_INET, target_ip, &target_ipv4); | ||
| 1676 | if (inet_pton_rc != 1) { | ||
| 1677 | if (verbose >= 1) { | ||
| 1678 | printf("ip string: %s contains characters not valid for its address family: IPv4\n", target_ip); | ||
| 1679 | } | ||
| 1680 | free(cidr_ip_part); | ||
| 1681 | return -1; | ||
| 1682 | } | ||
| 1683 | // copy the addresses in network byte order to a buffer for comparison | ||
| 1684 | memcpy(cidr_buf, &cidr_ipv4.s_addr, 4); | ||
| 1685 | memcpy(target_buf, &target_ipv4.s_addr, 4); | ||
| 1686 | cidr_bytes = cidr_buf; | ||
| 1687 | target_bytes = target_buf; | ||
| 1688 | total_bytes = 4; | ||
| 1689 | } else { | ||
| 1690 | struct in6_addr cidr_ipv6; | ||
| 1691 | struct in6_addr target_ipv6; | ||
| 1692 | inet_pton_rc = inet_pton(AF_INET6, cidr_ip_part, &cidr_ipv6); | ||
| 1693 | if (inet_pton_rc != 1) { | ||
| 1694 | if (verbose >= 1) { | ||
| 1695 | printf("ip string: %s contains characters not valid for its address family: IPv6\n", cidr_ip_part); | ||
| 1696 | } | ||
| 1697 | free(cidr_ip_part); | ||
| 1698 | return -1; | ||
| 1699 | } | ||
| 1700 | inet_pton_rc = inet_pton(AF_INET6, target_ip, &target_ipv6); | ||
| 1701 | if (inet_pton_rc != 1) { | ||
| 1702 | if (verbose >= 1) { | ||
| 1703 | printf("ip string: %s contains characters not valid for its address family: IPv6\n", target_ip); | ||
| 1704 | } | ||
| 1705 | free(cidr_ip_part); | ||
| 1706 | return -1; | ||
| 1707 | } | ||
| 1708 | memcpy(cidr_buf, &cidr_ipv6, 16); | ||
| 1709 | memcpy(target_buf, &target_ipv6, 16); | ||
| 1710 | cidr_bytes = cidr_buf; | ||
| 1711 | target_bytes = target_buf; | ||
| 1712 | total_bytes = 16; | ||
| 1713 | } | ||
| 1714 | |||
| 1715 | int prefix_bytes = prefix_length / 8; | ||
| 1716 | int prefix_bits = prefix_length % 8; | ||
| 1717 | |||
| 1718 | if (prefix_bytes > 0) { | ||
| 1719 | if (memcmp(cidr_bytes, target_bytes, (size_t)prefix_bytes) != 0) { | ||
| 1720 | if (verbose >= 1) { | ||
| 1721 | printf("the first %d bytes of the cidr_region_or_ip: %s and target_ip: %s are different\n", prefix_bytes, cidr_ip_part, target_ip); | ||
| 1722 | } | ||
| 1723 | free(cidr_ip_part); | ||
| 1724 | return 0; | ||
| 1725 | } | ||
| 1726 | } | ||
| 1727 | |||
| 1728 | if (prefix_bits != 0) { | ||
| 1729 | uint8_t cidr_oct = cidr_bytes[prefix_bytes]; | ||
| 1730 | uint8_t target_oct = target_bytes[prefix_bytes]; | ||
| 1731 | // the mask has first prefix_bits bits 1, the rest as 0 | ||
| 1732 | uint8_t mask = (uint8_t)(0xFFu << (8 - prefix_bits)); | ||
| 1733 | if ((cidr_oct & mask) != (target_oct & mask)) { | ||
| 1734 | if (verbose >= 1) { | ||
| 1735 | printf("looking at the last %d bits of the prefix, cidr_region_or_ip(%s) byte is: %u and target_ip byte(%s) is: %u, applying bitmask: %02X returns different results\n", prefix_bits, cidr_ip_part, (unsigned)cidr_oct, target_ip, (unsigned)target_oct, mask); | ||
| 1736 | } | ||
| 1737 | free(cidr_ip_part); | ||
| 1738 | return 0; | ||
| 1739 | } | ||
| 1740 | } | ||
| 1741 | |||
| 1742 | free(cidr_ip_part); | ||
| 1743 | return 1; | ||
| 1744 | } | ||
diff --git a/plugins/check_curl.d/check_curl_helpers.h b/plugins/check_curl.d/check_curl_helpers.h index e77b763b..cc47bf9d 100644 --- a/plugins/check_curl.d/check_curl_helpers.h +++ b/plugins/check_curl.d/check_curl_helpers.h | |||
| @@ -126,3 +126,12 @@ void test_file(char *path); | |||
| 126 | mp_subcheck check_curl_certificate_checks(CURL *curl, X509 *cert, int warn_days_till_exp, | 126 | mp_subcheck check_curl_certificate_checks(CURL *curl, X509 *cert, int warn_days_till_exp, |
| 127 | int crit_days_till_exp); | 127 | int crit_days_till_exp); |
| 128 | char *fmt_url(check_curl_working_state workingState); | 128 | char *fmt_url(check_curl_working_state workingState); |
| 129 | |||
| 130 | |||
| 131 | /* function that will determine if the host or the proxy resolves the target hostname | ||
| 132 | returns 0 if requester resolves the hostname locally, 1 if proxy resolves the hostname */ | ||
| 133 | int determine_hostname_resolver(const check_curl_working_state working_state, const check_curl_static_curl_config config); | ||
| 134 | |||
| 135 | /* Checks if an IP is inside given CIDR region. Using /protocol_size or not specifying the prefix length performs an equality check. Supports both IPv4 and IPv6 | ||
| 136 | returns 1 if the target_ip address is inside the given cidr_region_or_ip_addr, 0 if its out. return codes < 0 mean an error has occurred. */ | ||
| 137 | int ip_addr_inside_cidr(const char* cidr_region_or_ip_addr, const char* target_ip); | ||
diff --git a/plugins/check_curl.d/config.h b/plugins/check_curl.d/config.h index 61067d46..bcdf3010 100644 --- a/plugins/check_curl.d/config.h +++ b/plugins/check_curl.d/config.h | |||
| @@ -48,6 +48,11 @@ typedef struct { | |||
| 48 | 48 | ||
| 49 | bool use_ssl; | 49 | bool use_ssl; |
| 50 | bool no_body; | 50 | bool no_body; |
| 51 | |||
| 52 | /* curl CURLOPT_PROXY option will be set to this value if not NULL */ | ||
| 53 | char *curlopt_proxy; | ||
| 54 | /* curl CURLOPT_NOPROXY option will be set to this value if not NULL */ | ||
| 55 | char *curlopt_noproxy; | ||
| 51 | } check_curl_working_state; | 56 | } check_curl_working_state; |
| 52 | 57 | ||
| 53 | check_curl_working_state check_curl_working_state_init(); | 58 | check_curl_working_state check_curl_working_state_init(); |
| @@ -65,6 +70,8 @@ typedef struct { | |||
| 65 | char *client_privkey; | 70 | char *client_privkey; |
| 66 | char *ca_cert; | 71 | char *ca_cert; |
| 67 | bool verify_peer_and_host; | 72 | bool verify_peer_and_host; |
| 73 | char proxy[DEFAULT_BUFFER_SIZE]; | ||
| 74 | char no_proxy[DEFAULT_BUFFER_SIZE]; | ||
| 68 | char user_agent[DEFAULT_BUFFER_SIZE]; | 75 | char user_agent[DEFAULT_BUFFER_SIZE]; |
| 69 | char proxy_auth[MAX_INPUT_BUFFER]; | 76 | char proxy_auth[MAX_INPUT_BUFFER]; |
| 70 | char user_auth[MAX_INPUT_BUFFER]; | 77 | char user_auth[MAX_INPUT_BUFFER]; |
diff --git a/plugins/t/check_curl.t b/plugins/t/check_curl.t index 2c2fafde..a8326f12 100644 --- a/plugins/t/check_curl.t +++ b/plugins/t/check_curl.t | |||
| @@ -13,7 +13,7 @@ use vars qw($tests $has_ipv6); | |||
| 13 | BEGIN { | 13 | BEGIN { |
| 14 | use NPTest; | 14 | use NPTest; |
| 15 | $has_ipv6 = NPTest::has_ipv6(); | 15 | $has_ipv6 = NPTest::has_ipv6(); |
| 16 | $tests = $has_ipv6 ? 55 : 53; | 16 | $tests = $has_ipv6 ? 57 : 92; |
| 17 | plan tests => $tests; | 17 | plan tests => $tests; |
| 18 | } | 18 | } |
| 19 | 19 | ||
| @@ -25,7 +25,13 @@ my $plugin = 'check_http'; | |||
| 25 | $plugin = 'check_curl' if $0 =~ m/check_curl/mx; | 25 | $plugin = 'check_curl' if $0 =~ m/check_curl/mx; |
| 26 | 26 | ||
| 27 | my $host_tcp_http = getTestParameter("NP_HOST_TCP_HTTP", "A host providing the HTTP Service (a web server)", "localhost"); | 27 | my $host_tcp_http = getTestParameter("NP_HOST_TCP_HTTP", "A host providing the HTTP Service (a web server)", "localhost"); |
| 28 | my $host_tcp_http_subdomain = getTestParameter("NP_HOST_TCP_HTTP_SUBDOMAIN", "A host that is served under a subdomain name", "subdomain1.localhost.com"); | ||
| 29 | my $host_tcp_http_ipv4 = getTestParameter("NP_HOST_TCP_HTTP_IPV4", "An IPv6 address providing a HTTP Service (a web server)", "127.0.0.1"); | ||
| 30 | my $host_tcp_http_ipv4_cidr_1 = getTestParameter("NP_HOST_TCP_HTTP_IPV4_CIDR_1", "A CIDR that the provided IPv4 address is in."); | ||
| 31 | my $host_tcp_http_ipv4_cidr_2 = getTestParameter("NP_HOST_TCP_HTTP_IPV4_CIDR_2", "A CIDR that the provided IPv4 address is in."); | ||
| 28 | my $host_tcp_http_ipv6 = getTestParameter("NP_HOST_TCP_HTTP_IPV6", "An IPv6 address providing a HTTP Service (a web server)", "::1"); | 32 | my $host_tcp_http_ipv6 = getTestParameter("NP_HOST_TCP_HTTP_IPV6", "An IPv6 address providing a HTTP Service (a web server)", "::1"); |
| 33 | my $host_tcp_http_ipv6_cidr_1 = getTestParameter("NP_HOST_TCP_HTTP_IPV6_CIDR_1", "A CIDR that the provided IPv6 address is in."); | ||
| 34 | my $host_tcp_http_ipv6_cidr_2 = getTestParameter("NP_HOST_TCP_HTTP_IPV6_CIDR_2", "A CIDR that the provided IPv6 address is in."); | ||
| 29 | my $host_tls_http = getTestParameter("NP_HOST_TLS_HTTP", "A host providing the HTTPS Service (a tls web server)", "localhost"); | 35 | my $host_tls_http = getTestParameter("NP_HOST_TLS_HTTP", "A host providing the HTTPS Service (a tls web server)", "localhost"); |
| 30 | my $host_tls_cert = getTestParameter("NP_HOST_TLS_CERT", "the common name of the certificate.", "localhost"); | 36 | my $host_tls_cert = getTestParameter("NP_HOST_TLS_CERT", "the common name of the certificate.", "localhost"); |
| 31 | my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", "The hostname of system not responsive to network requests", "10.0.0.1"); | 37 | my $host_nonresponsive = getTestParameter("NP_HOST_NONRESPONSIVE", "The hostname of system not responsive to network requests", "10.0.0.1"); |
| @@ -222,3 +228,110 @@ SKIP: { | |||
| 222 | $res = NPTest->testCmd( "./$plugin -H monitoring-plugins.org --extended-perfdata" ); | 228 | $res = NPTest->testCmd( "./$plugin -H monitoring-plugins.org --extended-perfdata" ); |
| 223 | like ( $res->output, '/\'time_connect\'=[\d\.]+/', 'Extended Performance Data Output OK' ); | 229 | like ( $res->output, '/\'time_connect\'=[\d\.]+/', 'Extended Performance Data Output OK' ); |
| 224 | } | 230 | } |
| 231 | SKIP: { | ||
| 232 | skip "No internet access", 2 if $internet_access eq "no"; | ||
| 233 | |||
| 234 | # Proxy tests | ||
| 235 | # These are the proxy tests that require a working proxy server | ||
| 236 | # The debian container in the github workflow runs a squid proxy server at port 3128 | ||
| 237 | # Test that dont require one, like argument/environment variable parsing are in plugins/tests/check_curl.t | ||
| 238 | |||
| 239 | # Test if proxy works | ||
| 240 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | ||
| 241 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used, there are no preventative measures "); | ||
| 242 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | ||
| 243 | |||
| 244 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | ||
| 245 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used, there are no preventative measures "); | ||
| 246 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http_ipv4 works" ); | ||
| 247 | |||
| 248 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | ||
| 249 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used, there are no preventative measures "); | ||
| 250 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http_ipv6 works" ); | ||
| 251 | |||
| 252 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http2 --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | ||
| 253 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used, there are no preventative measures "); | ||
| 254 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http2 works" ); | ||
| 255 | |||
| 256 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http_subdomain --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | ||
| 257 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used, there are no preventative measures "); | ||
| 258 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http_subdomain works" ); | ||
| 259 | |||
| 260 | $res = NPTest->testCmd( "./$plugin -H $host_tls_http --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | ||
| 261 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used, there are no preventative measures "); | ||
| 262 | is( $res->return_code, 0, "Using proxy http://$host_tcp_proxy:$port_tcp_proxy to connect to $host_tls_http works" ); | ||
| 263 | |||
| 264 | # Noproxy '*' should prevent using proxy in any setting, even if its specified | ||
| 265 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http_subdomain --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy \"\*\" -v" ); | ||
| 266 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since noproxy has \"\*\" "); | ||
| 267 | is( $res->return_code, 0, "Should reach $host_tcp_http_subdomain with or without proxy." ); | ||
| 268 | |||
| 269 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy \"\*\" -v" ); | ||
| 270 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since noproxy has \"\*\" "); | ||
| 271 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv4 with or without proxy." ); | ||
| 272 | |||
| 273 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy \"\*\" -v" ); | ||
| 274 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since noproxy has \"\*\" "); | ||
| 275 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv6 with or without proxy." ); | ||
| 276 | |||
| 277 | # Noproxy domain should prevent using proxy for subdomains of that domain | ||
| 278 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http_subdomain --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http -v" ); | ||
| 279 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since subdomain: $host_tcp_http_subdomain is under a noproxy domain: $host_tcp_http"); | ||
| 280 | is( $res->return_code, 0, "Should reach $host_tcp_http_subdomain with or without proxy." ); | ||
| 281 | |||
| 282 | # Noproxy should prevent using IP matches if an IP is found directly | ||
| 283 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv4 -v" ); | ||
| 284 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since IP address: $host_tcp_http_ipv4 is added into noproxy: $host_tcp_http_ipv4"); | ||
| 285 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv4 with or without proxy." ); | ||
| 286 | |||
| 287 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv6 -v" ); | ||
| 288 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since IP address: $host_tcp_http_ipv6 is added into noproxy: $host_tcp_http_ipv6"); | ||
| 289 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv6 with or without proxy." ); | ||
| 290 | |||
| 291 | # Noproxy should prevent using IP matches if a CIDR region that contains that Ip is used directly. | ||
| 292 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv4_cidr_1 -v" ); | ||
| 293 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since IP address: $host_tcp_http_ipv4 is inside CIDR range: $host_tcp_http_ipv4_cidr_1"); | ||
| 294 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv4 with or without proxy." ); | ||
| 295 | |||
| 296 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv4 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv4_cidr_2 -v" ); | ||
| 297 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since IP address: $host_tcp_http_ipv4 is inside CIDR range: $host_tcp_http_ipv4_cidr_2"); | ||
| 298 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv4 with or without proxy." ); | ||
| 299 | |||
| 300 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv6_cidr_1 -v " ); | ||
| 301 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since IP address: $host_tcp_http_ipv6 is inside CIDR range: $host_tcp_http_ipv6_cidr_1"); | ||
| 302 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv6 with or without proxy." ); | ||
| 303 | |||
| 304 | $res = NPTest->testCmd( "./$plugin -I $host_tcp_http_ipv6 --proxy http://$host_tcp_proxy:$port_tcp_proxy --noproxy $host_tcp_http_ipv6_cidr_2 -v" ); | ||
| 305 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used since IP address: $host_tcp_http_ipv6 is inside CIDR range: $host_tcp_http_ipv6_cidr_2"); | ||
| 306 | is( $res->return_code, 0, "Should reach $host_tcp_http_ipv6 with or without proxy." ); | ||
| 307 | |||
| 308 | # Noproxy should discern over different types of proxy schemes | ||
| 309 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy http://$host_tcp_proxy:$port_tcp_proxy -v" ); | ||
| 310 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used for resolving hostname, and is using scheme http "); | ||
| 311 | is( $res->return_code, 0, "Using proxy http:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | ||
| 312 | |||
| 313 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy https://$host_tcp_proxy:$port_tcp_proxy -v" ); | ||
| 314 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used for resolving hostname, and is using scheme https"); | ||
| 315 | # Squid is not configured for https | ||
| 316 | # is( $res->return_code, 0, "Using proxy https:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | ||
| 317 | |||
| 318 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy socks4://$host_tcp_proxy:$port_tcp_proxy -v" ); | ||
| 319 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used for resolving hostname, and is using scheme socks4"); | ||
| 320 | # Squid is not configured for socks4 | ||
| 321 | # is( $res->return_code, 0, "Using proxy socks4:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | ||
| 322 | |||
| 323 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy socks4a://$host_tcp_proxy:$port_tcp_proxy -v" ); | ||
| 324 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used for resolving hostname, and is using scheme socks4a"); | ||
| 325 | # Squid is not configured for socks4a | ||
| 326 | # is( $res->return_code, 0, "Using proxy socks4a:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | ||
| 327 | |||
| 328 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy socks5://$host_tcp_proxy:$port_tcp_proxy -v" ); | ||
| 329 | like($res->output, qr/^\* proxy_resolves_hostname: 0/m, "proxy is not used for resolving hostname, and is using scheme socks5"); | ||
| 330 | # Squid is not configured for socks5 | ||
| 331 | # is( $res->return_code, 0, "Using proxy socks5:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | ||
| 332 | |||
| 333 | $res = NPTest->testCmd( "./$plugin -H $host_tcp_http --proxy socks5h://$host_tcp_proxy:$port_tcp_proxy -v" ); | ||
| 334 | like($res->output, qr/^\* proxy_resolves_hostname: 1/m, "proxy is used for resolving hostname, and is using scheme socks5h"); | ||
| 335 | # Squid is not configured for socks5h | ||
| 336 | # is( $res->return_code, 0, "Using proxy socks5h:$host_tcp_proxy:$port_tcp_proxy to connect to $host_tcp_http works" ); | ||
| 337 | } | ||
diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t index 248eb4c5..94058d5b 100755 --- a/plugins/tests/check_curl.t +++ b/plugins/tests/check_curl.t | |||
| @@ -27,8 +27,8 @@ use HTTP::Daemon::SSL; | |||
| 27 | 27 | ||
| 28 | $ENV{'LC_TIME'} = "C"; | 28 | $ENV{'LC_TIME'} = "C"; |
| 29 | 29 | ||
| 30 | my $common_tests = 95; | 30 | my $common_tests = 111; |
| 31 | my $ssl_only_tests = 8; | 31 | my $ssl_only_tests = 12; |
| 32 | # Check that all dependent modules are available | 32 | # Check that all dependent modules are available |
| 33 | eval "use HTTP::Daemon 6.01;"; | 33 | eval "use HTTP::Daemon 6.01;"; |
| 34 | plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@; | 34 | plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@; |
| @@ -41,7 +41,7 @@ my $plugin = 'check_http'; | |||
| 41 | $plugin = 'check_curl' if $0 =~ m/check_curl/mx; | 41 | $plugin = 'check_curl' if $0 =~ m/check_curl/mx; |
| 42 | 42 | ||
| 43 | # look for libcurl version to see if some advanced checks are possible (>= 7.49.0) | 43 | # look for libcurl version to see if some advanced checks are possible (>= 7.49.0) |
| 44 | my $advanced_checks = 12; | 44 | my $advanced_checks = 16; |
| 45 | my $use_advanced_checks = 0; | 45 | my $use_advanced_checks = 0; |
| 46 | my $required_version = '7.49.0'; | 46 | my $required_version = '7.49.0'; |
| 47 | my $virtual_host = 'www.somefunnyhost.com'; | 47 | my $virtual_host = 'www.somefunnyhost.com'; |
| @@ -410,6 +410,41 @@ SKIP: { | |||
| 410 | $result = NPTest->testCmd( $cmd ); | 410 | $result = NPTest->testCmd( $cmd ); |
| 411 | is( $result->return_code, 0, $cmd); | 411 | is( $result->return_code, 0, $cmd); |
| 412 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); | 412 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 413 | |||
| 414 | # curlopt proxy/noproxy parsing tests, ssl disabled | ||
| 415 | { | ||
| 416 | # Make a scope and change environment variables here, to not mess them up for other tests using environment variables | ||
| 417 | |||
| 418 | local $ENV{"http_proxy"} = 'http://proxy.example.com:8080'; | ||
| 419 | $cmd = "$command -u /statuscode/200 -v"; | ||
| 420 | $result = NPTest->testCmd( $cmd ); | ||
| 421 | like( $result->output, '/.*CURLOPT_PROXY: http://proxy.example.com:8080 */', "Correctly took 'http_proxy' environment variable: ".$result->output ); | ||
| 422 | delete($ENV{"http_proxy"}); | ||
| 423 | |||
| 424 | local $ENV{"http_proxy"} = 'http://taken.proxy.example:8080'; | ||
| 425 | local $ENV{"HTTP_PROXY"} = 'http://discarded.proxy.example:8080'; | ||
| 426 | $cmd = "$command -u /statuscode/200 -v"; | ||
| 427 | $result = NPTest->testCmd( $cmd ); | ||
| 428 | like( $result->output, '/.*CURLOPT_PROXY: http://taken.proxy.example:8080 */', "Correctly took 'http_proxy' environment variable over 'HTTP_PROXY': ".$result->output ); | ||
| 429 | delete(local $ENV{"http_proxy"}); | ||
| 430 | delete(local $ENV{"HTTP_PROXY"}); | ||
| 431 | |||
| 432 | local $ENV{"http_proxy"} = 'http://discarded1.proxy.example:8080'; | ||
| 433 | local $ENV{"HTTP_PROXY"} = 'http://discarded2.proxy.example:8080'; | ||
| 434 | $cmd = "$command -u /statuscode/200 -x 'http://taken.proxy.example:8080' -v"; | ||
| 435 | $result = NPTest->testCmd( $cmd ); | ||
| 436 | like( $result->output, '/.*CURLOPT_PROXY: http://taken.proxy.example:8080 */', "Argument -x overwrote 'http_proxy' and 'HTTP_PROXY' environment variables: ".$result->output ); | ||
| 437 | delete(local $ENV{"http_proxy"}); | ||
| 438 | delete(local $ENV{"HTTP_PROXY"}); | ||
| 439 | |||
| 440 | local $ENV{"http_proxy"} = 'http://discarded1.proxy.example:8080'; | ||
| 441 | local $ENV{"HTTP_PROXY"} = 'http://discarded2.proxy.example:8080'; | ||
| 442 | $cmd = "$command -u /statuscode/200 --proxy 'http://taken.example.com:8080' -v"; | ||
| 443 | $result = NPTest->testCmd( $cmd ); | ||
| 444 | like( $result->output, '/.*CURLOPT_PROXY: http://taken.example.com:8080 */', "Argument --proxy overwrote 'http_proxy' and 'HTTP_PROXY' environment variables: ".$result->output ); | ||
| 445 | delete(local $ENV{"http_proxy"}); | ||
| 446 | delete(local $ENV{"HTTP_PROXY"}); | ||
| 447 | } | ||
| 413 | } | 448 | } |
| 414 | 449 | ||
| 415 | # and the same for SSL | 450 | # and the same for SSL |
| @@ -432,6 +467,41 @@ SKIP: { | |||
| 432 | $result = NPTest->testCmd( $cmd ); | 467 | $result = NPTest->testCmd( $cmd ); |
| 433 | is( $result->return_code, 0, $cmd); | 468 | is( $result->return_code, 0, $cmd); |
| 434 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); | 469 | like( $result->output, '/.*HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second.*/', "Output correct: ".$result->output ); |
| 470 | |||
| 471 | # curlopt proxy/noproxy parsing tests, ssl enabled | ||
| 472 | { | ||
| 473 | # Make a scope and change environment variables here, to not mess them up for other tests using environment variables | ||
| 474 | |||
| 475 | local $ENV{"https_proxy"} = 'http://proxy.example.com:8080'; | ||
| 476 | $cmd = "$command -u /statuscode/200 --ssl -v"; | ||
| 477 | $result = NPTest->testCmd( $cmd ); | ||
| 478 | like( $result->output, '/.*CURLOPT_PROXY: http://proxy.example.com:8080 */', "Correctly took 'https_proxy' environment variable: ".$result->output ); | ||
| 479 | delete($ENV{"https_proxy"}); | ||
| 480 | |||
| 481 | local $ENV{"https_proxy"} = 'http://taken.proxy.example:8080'; | ||
| 482 | local $ENV{"HTTPS_PROXY"} = 'http://discarded.proxy.example:8080'; | ||
| 483 | $cmd = "$command -u /statuscode/200 --ssl -v"; | ||
| 484 | $result = NPTest->testCmd( $cmd ); | ||
| 485 | like( $result->output, '/.*CURLOPT_PROXY: http://taken.proxy.example:8080 */', "Correctly took 'https_proxy' environment variable over 'HTTPS_PROXY': ".$result->output ); | ||
| 486 | delete(local $ENV{"https_proxy"}); | ||
| 487 | delete(local $ENV{"HTTPS_PROXY"}); | ||
| 488 | |||
| 489 | local $ENV{"https_proxy"} = 'http://discarded1.proxy.example:8080'; | ||
| 490 | local $ENV{"HTTPS_PROXY"} = 'http://discarded2.proxy.example:8080'; | ||
| 491 | $cmd = "$command -u /statuscode/200 --ssl -x 'http://taken.example.com:8080' -v"; | ||
| 492 | $result = NPTest->testCmd( $cmd ); | ||
| 493 | like( $result->output, '/.*CURLOPT_PROXY: http://taken.example.com:8080 */', "Argument -x overwrote environment variables 'https_proxy' and 'HTTPS_PROXY': ".$result->output ); | ||
| 494 | delete(local $ENV{"https_proxy"}); | ||
| 495 | delete(local $ENV{"HTTPS_PROXY"}); | ||
| 496 | |||
| 497 | local $ENV{"https_proxy"} = 'http://discarded1.proxy.example:8080'; | ||
| 498 | local $ENV{"HTTPS_PROXY"} = 'http://discarded2.proxy.example:8080'; | ||
| 499 | $cmd = "$command -u /statuscode/200 --ssl --proxy 'http://taken.example.com:8080' -v"; | ||
| 500 | $result = NPTest->testCmd( $cmd ); | ||
| 501 | like( $result->output, '/.*CURLOPT_PROXY: http://taken.example.com:8080 */', "Argument --proxy overwrote environment variables 'https_proxy' and 'HTTPS_PROXY': ".$result->output ); | ||
| 502 | delete(local $ENV{"https_proxy"}); | ||
| 503 | delete(local $ENV{"HTTPS_PROXY"}); | ||
| 504 | } | ||
| 435 | } | 505 | } |
| 436 | 506 | ||
| 437 | 507 | ||
| @@ -712,4 +782,63 @@ sub run_common_tests { | |||
| 712 | $result = NPTest->testCmd( $cmd, 5 ); | 782 | $result = NPTest->testCmd( $cmd, 5 ); |
| 713 | }; | 783 | }; |
| 714 | is( $@, "", $cmd ); | 784 | is( $@, "", $cmd ); |
| 785 | |||
| 786 | # curlopt proxy/noproxy parsing tests | ||
| 787 | { | ||
| 788 | # Make a scope and change environment variables here, to not mess them up for other tests using environment variables | ||
| 789 | |||
| 790 | local $ENV{"no_proxy"} = 'internal.acme.org'; | ||
| 791 | $cmd = "$command -u /statuscode/200 -v"; | ||
| 792 | $result = NPTest->testCmd( $cmd ); | ||
| 793 | like( $result->output, '/.* curl CURLOPT_NOPROXY: internal.acme.org */', "Correctly took 'no_proxy' environment variable: ".$result->output ); | ||
| 794 | delete($ENV{"no_proxy"}); | ||
| 795 | |||
| 796 | local $ENV{"no_proxy"} = 'taken.acme.org'; | ||
| 797 | local $ENV{"NO_PROXY"} = 'discarded.acme.org'; | ||
| 798 | $cmd = "$command -u /statuscode/200 -v"; | ||
| 799 | $result = NPTest->testCmd( $cmd ); | ||
| 800 | is( $result->return_code, 0, $cmd); | ||
| 801 | like( $result->output, '/.*CURLOPT_NOPROXY: taken.acme.org*/', "Correctly took 'no_proxy' environment variable over 'NO_PROXY': ".$result->output ); | ||
| 802 | delete(local $ENV{"no_proxy"}); | ||
| 803 | delete(local $ENV{"NO_PROXY"}); | ||
| 804 | |||
| 805 | local $ENV{"no_proxy"} = 'taken.acme.org'; | ||
| 806 | local $ENV{"NO_PROXY"} = 'discarded.acme.org'; | ||
| 807 | $cmd = "$command -u /statuscode/200 --noproxy 'taken.acme.org' -v"; | ||
| 808 | $result = NPTest->testCmd( $cmd ); | ||
| 809 | is( $result->return_code, 0, $cmd); | ||
| 810 | like( $result->output, '/.*CURLOPT_NOPROXY: taken.acme.org*/', "Argument --noproxy overwrote environment variables 'no_proxy' and 'NO_PROXY': ".$result->output ); | ||
| 811 | delete(local $ENV{"no_proxy"}); | ||
| 812 | delete(local $ENV{"NO_PROXY"}); | ||
| 813 | |||
| 814 | $cmd = "$command -u /statuscode/200 --noproxy 'internal1.acme.org,internal2.acme.org,internal3.acme.org' -v"; | ||
| 815 | $result = NPTest->testCmd( $cmd ); | ||
| 816 | is( $result->return_code, 0, $cmd); | ||
| 817 | like( $result->output, '/.*CURLOPT_NOPROXY: internal1.acme.org,internal2.acme.org,internal3.acme.org*/', "Argument --noproxy read multiple noproxy domains: ".$result->output ); | ||
| 818 | |||
| 819 | $cmd = "$command -u /statuscode/200 --noproxy '10.11.12.13,256.256.256.256,0.0.0.0,192.156.0.0/22,10.0.0.0/4' -v"; | ||
| 820 | $result = NPTest->testCmd( $cmd ); | ||
| 821 | is( $result->return_code, 0, $cmd); | ||
| 822 | like( $result->output, '/.*CURLOPT_NOPROXY: 10.11.12.13,256.256.256.256,0.0.0.0,192.156.0.0/22,10.0.0.0/4*/', "Argument --noproxy took multiple noproxy domains: ".$result->output ); | ||
| 823 | |||
| 824 | $cmd = "$command -u /statuscode/200 --noproxy '0123:4567:89AB:CDEF:0123:4567:89AB:CDEF,0123::CDEF,0123:4567/96,[::1],::1,[1234::5678:ABCD/4]' -v"; | ||
| 825 | $result = NPTest->testCmd( $cmd ); | ||
| 826 | is( $result->return_code, 0, $cmd); | ||
| 827 | like( $result->output, '/.*CURLOPT_NOPROXY: 0123:4567:89AB:CDEF:0123:4567:89AB:CDEF,0123::CDEF,0123:4567\/96,\[::1\],::1,\[1234::5678:ABCD\/4\].*/', "Argument --noproxy took multiple noproxy domains: ".$result->output ); | ||
| 828 | |||
| 829 | $cmd = "$command -u /statuscode/200 --noproxy '300.400.500.600,1.2.3,XYZD:0123::,1:2:3:4:5:6:7,1::2::3,1.1.1.1/64,::/256' -v"; | ||
| 830 | $result = NPTest->testCmd( $cmd ); | ||
| 831 | is( $result->return_code, 0, $cmd); | ||
| 832 | |||
| 833 | $cmd = "$command -u /statuscode/200 --proxy http://proxy.example.com:8080 --noproxy '*' -v"; | ||
| 834 | $result = NPTest->testCmd( $cmd ); | ||
| 835 | is( $result->return_code, 0, $cmd); | ||
| 836 | like( $result->output, '/.*proxy_resolves_hostname: 0.*/', "Proxy will not be used due to '*' in noproxy: ".$result->output ); | ||
| 837 | |||
| 838 | $cmd = "$command -u /statuscode/200 --proxy http://proxy.example.com:8080 --noproxy '127.0.0.1' -v"; | ||
| 839 | $result = NPTest->testCmd( $cmd ); | ||
| 840 | is( $result->return_code, 0, $cmd); | ||
| 841 | like( $result->output, '/.*proxy_resolves_hostname: 0.*/', "Proxy will not be used due to '127.0.0.1' in noproxy: ".$result->output ); | ||
| 842 | } | ||
| 843 | |||
| 715 | } | 844 | } |
diff --git a/tools/squid.conf b/tools/squid.conf index bed7a583..048aa576 100644 --- a/tools/squid.conf +++ b/tools/squid.conf | |||
| @@ -972,6 +972,8 @@ | |||
| 972 | # Example rule allowing access from your local networks. | 972 | # Example rule allowing access from your local networks. |
| 973 | # Adapt to list your (internal) IP networks from where browsing | 973 | # Adapt to list your (internal) IP networks from where browsing |
| 974 | # should be allowed | 974 | # should be allowed |
| 975 | acl localhost src 127.0.0.1/32 | ||
| 976 | acl localhost src ::1/128 | ||
| 975 | acl localnet src 10.0.0.0/8 # RFC1918 possible internal network | 977 | acl localnet src 10.0.0.0/8 # RFC1918 possible internal network |
| 976 | acl localnet src 172.16.0.0/12 # RFC1918 possible internal network | 978 | acl localnet src 172.16.0.0/12 # RFC1918 possible internal network |
| 977 | acl localnet src 192.168.0.0/16 # RFC1918 possible internal network | 979 | acl localnet src 192.168.0.0/16 # RFC1918 possible internal network |
| @@ -1172,6 +1174,7 @@ http_access deny !Safe_ports | |||
| 1172 | http_access deny CONNECT !SSL_ports | 1174 | http_access deny CONNECT !SSL_ports |
| 1173 | 1175 | ||
| 1174 | # Only allow cachemgr access from localhost | 1176 | # Only allow cachemgr access from localhost |
| 1177 | http_access allow localhost | ||
| 1175 | http_access allow localhost manager | 1178 | http_access allow localhost manager |
| 1176 | http_access deny manager | 1179 | http_access deny manager |
| 1177 | 1180 | ||
diff --git a/tools/subdomain1/index.php b/tools/subdomain1/index.php new file mode 100644 index 00000000..e97b19f5 --- /dev/null +++ b/tools/subdomain1/index.php | |||
| @@ -0,0 +1 @@ | |||
| Subdomain: subdomain1.localhost.com | |||
diff --git a/tools/subdomain1/subdomain1.conf b/tools/subdomain1/subdomain1.conf new file mode 100644 index 00000000..74521792 --- /dev/null +++ b/tools/subdomain1/subdomain1.conf | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | # This apache configuration file is used testing | ||
| 2 | # check_curl tests use this subdomain to see if --noproxy works on subdomains of a domain. | ||
| 3 | |||
| 4 | <VirtualHost *:80> | ||
| 5 | ServerName subdomain1.localhost.com | ||
| 6 | DocumentRoot /var/www/subdomain1 | ||
| 7 | |||
| 8 | ErrorLog ${APACHE_LOG_DIR}/subdomain1_error.log | ||
| 9 | CustomLog ${APACHE_LOG_DIR}/subdomain1_access.log combined | ||
| 10 | </VirtualHost> | ||
| 11 | |||
| 12 | <VirtualHost *:443> | ||
| 13 | ServerName subdomain1.localhost.com | ||
| 14 | DocumentRoot /var/www/subdomain1 | ||
| 15 | |||
| 16 | SSLEngine on | ||
| 17 | SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem | ||
| 18 | SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key | ||
| 19 | |||
| 20 | ErrorLog ${APACHE_LOG_DIR}/subdomain1_ssl_error.log | ||
| 21 | CustomLog ${APACHE_LOG_DIR}/subdomain1_ssl_access.log combined | ||
| 22 | </VirtualHost> | ||
