Allowing nagios plugin check_dhcp to work without setuid root

SO_BINDTODEVICE requires CAP_NET_RAW. check_dhcp also wants to bind to port 68, which requires CAP_NET_BIND_SERVICE. See capabilities(7) for detailed descriptions of the available capabilities.

These two capabilities can be granted to the executable with setcap, like this:

setcap 'cap_net_raw,cap_net_bind_service=+ep' /usr/lib/nagios/plugins/check_dhcp

This should allow any user to run check_dhcp successfully, without possibly (if they can exploit check_dhcp) giving them full root privileges.

The plugin will still (rather stupidly) emit a warning:

$ ./check_dhcp 
Warning: This plugin must be either run as root or setuid root.
To run as root, you can use a tool like sudo.
To set the setuid permissions, use the command:
    chmod u+s yourpluginfile
OK: Received 2 DHCPOFFER(s), max lease time = 259200 sec.

To address this, you could:

  • Ignore it. Nagios will still look at the exit status to get the plugin state.
  • Remove the call to np_warn_if_not_root and recompile.
  • Use the monitoring-plugins.org fork of the Nagios plugins, which has fixed this issue. debmon.org has Debian packages available.
  • Modify the Nagios command definition to run the plugin through grep, removing the warning. Of course you must now take care to not alter the plugin's exit code, so maybe you want to wrap that up in a script:
#!/bin/bash
/usr/lib/nagios3/plugins/check_dhcp | egrep -v 'run as root|^To |chmod u\+s'
exit "${PIPESTATUS[0]}"

With most of the standard (written in C) plugins, there are alternative (not C) implementations on Nagios Exchange.

For example, there's a perl check_dhcp that's really just a wrapper around dhcping. Of course, the dhcping binary demands to be run via root/sudo/setuid-root too, but perhaps that binary is less of a security concern for you than the stock check_dhcp plugin.