I have a small number of our external SSL-websites in Nagios monitoring, using the standard Nagios plugin check_http. With Nagios not having a direct connection to the external facing websites (some hosted by a external party), they are all accessed using our internal proxy. With the deployment of a new proxy system (Bluecoat SG appliance) this Monday, all these checks suddenly failed with error "HTTP\1.1 400 Bad Request".

Before, the check_http plugin was working fine, using the arguments 'check_http -I <proxy-ip> -p <proxy-port> -u <check-url>' I could monitor all websites, including the SSL enabled ones using the https://xxx URL.

The cause for check_http failure with proxies

A quick packet trace shows how the Nagios check_http plugin simply connects to the proxy and makes a 'GET <check-url> HTTP/1.0' request. This worked with the old Microsoft ISA2000/2006 proxies, but fails now for SSL websites with the new Bluecoat SG proxy appliances. The proxy returns error "HTTP/1.1 400 Bad Request" instead of fetching the page with http/s.

A quick check with our Bluecoat support brought no results. It would have been nice if this functionality could be enabled, if possible with a rule specifying the Nagios hosts only. The vendors response was: 'GET https://xxx' requests are non-standard and will not be supported. Too bad - talk to your monitoring software vendor. Well, Thanks!


So, what now? Ditching the check_http plugin and implementing a cheap wrapper around commandline tools such as wget or curl? Not cool, we also use check_http for gathering performance data and graphing access times. Implement a tunnel in front of check_http that establishes a connect and write a wrapper to call it? Not cool either. Googling the net I saw others hit the same wall with no good solution.

The Solution - fix check_http

A look into the source of that latest check_http version in nagios-plugins 1.4.14 shows that Ethan started to add basic support for HTTP methods with a new argument '-j <method>'. This new function now allows checks for, say, POST instead of GET. But unfortunately the CONNECT method is fundamentally different and still not supported yet.

Since Nagios is our main monitoring tool, support for these checks is production critical and I decided to 'hack' support for the CONNECT method with a proxy for HTTP/S GET requests into the latest plugin. I hope this will serve as the base for *professionally* integrating it into the next version of check_http. For all who can't wait, here is the source check_http.c.

How to build the new plugin

Simply extract the latest plugin package (v1.4.14 at time of writing), make a backup of the original check_http.c in nagios-plugins-1.4.14/plugins and copy the new file over the existing one. Then compile the plugins as usual with ./configure and make. Finally, copy the new check_http plugin binary from nagios-plugins-1.4.14/plugins/check_http to your <nagios-home>/libexec, preferably first making a backup of the previous plugin binary check_http. To identify which binary you have, run check_http -V, the new version reports itself as v2 with a output string "check_http v2 v1.4.14 (nagios-plugins 1.4.14)". Make sure you compile with SSL support, you need to have the libssl-devel package installed.

As far as I can tell from a number of checks, the new plugin behaves exactly like the old one, only with the addition of the new CONNECT functionality. The new function is triggered by using the arguments -I, -S and -j CONNECT together. For example, call the plugin as follows:

./check_http -I <proxy-ip> -p <proxy-port> -u https://xxx.yyy.zzz/xxx -S 
-j CONNECT -H xxx.yyy.zzz

.. and voila, the plugin works by using the CONNECT method, as the packettrace example below shows.


I hope this is helping others in immediate need and this quick fix improves the check_http functionality in future releases. It would be great to bring check_http to the same level as, say, the curl command. Website monitoring is crucial for us, and the checks complexity and numbers will increase over time. I would consider this version just a quick band-aid as it supports only HTTPS GET's. Perhaps introducing a new option, say -x for proxies would be a better solution to address this issue within the code and for greater clarity with Nagios users.

Credits and Sources