check and warn about capabilities misconfiguration
authorMarc Fournier <marc.fournier@camptocamp.com>
Tue, 26 Jan 2016 20:46:59 +0000 (21:46 +0100)
committerMarc Fournier <marc.fournier@camptocamp.com>
Wed, 10 Aug 2016 06:07:33 +0000 (08:07 +0200)
Add WARNING() statements to a bunch of plugins which require special
privileges to work properly. They would be emitted once at startup time,
if running as root with privileges dropped, or if running as a normal
users without the needed capabilities explicitly set.

Related to #1444

src/ceph.c
src/dns.c
src/exec.c
src/iptables.c
src/ping.c

index cbfdd22..e9bb960 100644 (file)
@@ -38,6 +38,9 @@
 #if HAVE_YAJL_YAJL_VERSION_H
 #include <yajl/yajl_version.h>
 #endif
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
 
 #include <limits.h>
 #include <poll.h>
@@ -1573,6 +1576,22 @@ static int ceph_read(void)
 static int ceph_init(void)
 {
     int ret;
+
+#ifdef HAVE_SYS_CAPABILITY_H
+  if (check_capability (CAP_DAC_OVERRIDE) != 0)
+  {
+    if (getuid () == 0)
+      WARNING ("ceph plugin: Running collectd as root, but the "
+          "CAP_DAC_OVERRIDE capability is missing. The plugin's read "
+          "function will probably fail. Is your init system dropping "
+          "capabilities ?");
+    else
+      WARNING ("ceph plugin: collectd doesn't have the CAP_DAC_OVERRIDE "
+          "capability. If you don't want to run collectd as root, try running "
+          "\"setcap cap_dac_override=ep\" on the collectd binary.");
+  }
+#endif
+
     ceph_daemons_print();
 
     ret = cconn_main_loop(ASOK_REQ_VERSION);
index 15fa15a..be6d0dc 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
 
 #include <pcap.h>
 
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
 /*
  * Private data types
  */
@@ -347,6 +351,20 @@ static int dns_init (void)
 
        listen_thread_init = 1;
 
+#ifdef HAVE_SYS_CAPABILITY_H
+       if (check_capability (CAP_NET_RAW) != 0)
+       {
+               if (getuid () == 0)
+                       WARNING ("dns plugin: Running collectd as root, but the CAP_NET_RAW "
+                                       "capability is missing. The plugin's read function will probably "
+                                       "fail. Is your init system dropping capabilities ?");
+               else
+                       WARNING ("dns plugin: collectd doesn't have the CAP_NET_RAW capability. "
+                                       "If you don't want to run collectd as root, try running \"setcap "
+                                       "cap_net_raw=ep\" on the collectd binary.");
+       }
+#endif
+
        return (0);
 } /* int dns_init */
 
index e90f83c..c51465b 100644 (file)
 #include <grp.h>
 #include <signal.h>
 
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
 #define PL_NORMAL        0x01
 #define PL_NOTIF_ACTION  0x02
 
@@ -806,6 +810,22 @@ static int exec_init (void) /* {{{ */
 
   sigaction (SIGCHLD, &sa, NULL);
 
+#ifdef HAVE_SYS_CAPABILITY_H
+  if ((check_capability (CAP_SETUID) != 0) ||
+      (check_capability (CAP_SETGID) != 0))
+  {
+    if (getuid () == 0)
+      WARNING ("exec plugin: Running collectd as root, but the CAP_SETUID "
+          "or CAP_SETGID capabilities are missing. The plugin's read function "
+          "will probably fail. Is your init system dropping capabilities ?");
+    else
+      WARNING ("exec plugin: collectd doesn't have the CAP_SETUID or "
+          "CAP_SETGID capabilities. If you don't want to run collectd as root, "
+          "try running \"setcap 'cap_setuid=ep cap_setgid=ep'\" on the "
+          "collectd binary.");
+  }
+#endif
+
   return (0);
 } /* int exec_init }}} */
 
index e035a88..a2ed4c7 100644 (file)
 #include "plugin.h"
 #include "configfile.h"
 
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
 #include <libiptc/libiptc.h>
 #include <libiptc/libip6tc.h>
 
@@ -499,10 +503,30 @@ static int iptables_shutdown (void)
     return (0);
 } /* int iptables_shutdown */
 
+static int iptables_init (void)
+{
+#ifdef HAVE_SYS_CAPABILITY_H
+    if (check_capability (CAP_NET_ADMIN) != 0)
+    {
+        if (getuid () == 0)
+            WARNING ("iptables plugin: Running collectd as root, but the "
+                  "CAP_NET_ADMIN capability is missing. The plugin's read "
+                  "function will probably fail. Is your init system dropping "
+                  "capabilities ?");
+        else
+            WARNING ("iptables plugin: collectd doesn't have the CAP_NET_ADMIN "
+                  "capability. If you don't want to run collectd as root, try "
+                  "running \"setcap cap_net_admin=ep\" on the collectd binary.");
+    }
+#endif
+    return (0);
+} /* int iptables_init */
+
 void module_register (void)
 {
     plugin_register_config ("iptables", iptables_config,
                              config_keys, config_keys_num);
+    plugin_register_init ("iptables", iptables_init);
     plugin_register_read ("iptables", iptables_read);
     plugin_register_shutdown ("iptables", iptables_shutdown);
 } /* void module_register */
index 4932bae..9b5d5ca 100644 (file)
 # include <netdb.h> /* NI_MAXHOST */
 #endif
 
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
 #include <oping.h>
 
 #ifndef NI_MAXHOST
@@ -448,6 +452,20 @@ static int ping_init (void) /* {{{ */
         "Will use a timeout of %gs.", ping_timeout);
   }
 
+#ifdef HAVE_SYS_CAPABILITY_H
+  if (check_capability (CAP_NET_RAW) != 0)
+  {
+    if (getuid () == 0)
+      WARNING ("ping plugin: Running collectd as root, but the CAP_NET_RAW "
+          "capability is missing. The plugin's read function will probably "
+          "fail. Is your init system dropping capabilities ?");
+    else
+      WARNING ("ping plugin: collectd doesn't have the CAP_NET_RAW capability. "
+          "If you don't want to run collectd as root, try running \"setcap "
+          "cap_net_raw=ep\" on the collectd binary.");
+  }
+#endif
+
   return (start_thread ());
 } /* }}} int ping_init */