For details on how osqueryd schedules queries and loads information from a config, see the configuration deployment guide.

You may distribute configurations in your environment differently than Facebook. To support all environments, the way that osqueryd goes about retrieving configurations is completely pluggable and configurable. By default, osqueryd will look for a JSON file on disk using the default config plugin: filesystem. If you distribute configurations via something like Zookeeper or etcd, you need to write a C++ function that can acquire a string of JSON. This developer tutorial will walk through the default filesystem config plugin as a demonstration for creating new config inputs.

Example: Filesystem config

The following code is more-or-less the filesystem config plugin. This is the default config plugin, it simply reads JSON data from a flat file. Let's walk through the implementation:

  1. // Note 1: REQUIRED includes
  2. #include <osquery/config.h>
  3. #include <osquery/flags.h>
  4. namespace osquery {
  5. // Note 2: Setup any invocation arguments
  6. FLAG(string, config_path, "osquery.conf", "Path to config");
  7. // Note 3: Inherit from ConfigPlugin
  8. class FilesystemConfigPlugin : public ConfigPlugin {
  9. public:
  10. osquery::Status genConfig(std::map<std::string, std::string>& config) {
  11. std::string content;
  12. std::ifstream content_stream(FLAGS_config_path);
  13. content_stream.seekg(0, std::ios::end);
  14. content.reserve(config_stream.tellg());
  15. content_stream.seekg(0, std::ios::beg);
  16. content.assign((std::istreambuf_iterator<char>(content_stream)),
  17. std::istreambuf_iterator<char>());
  18. // Note 4: Return an osquery Status and JSON encoded config.
  19. config["default_source"] = std::move(content);
  20. return Status(0, "OK");
  21. }
  22. };
  23. // Note 5: Register the plugin
  24. REGISTER(FilesystemConfigPlugin, "config", "filesystem");
  25. }

There are 5 parts of a config plugin:

  • Include the plugin macros as well as command line argument macros.
  • If your config requires customization expose it as arguments.
  • Inherit from ConfigPlugin and implement: osquery::Status genConfig(std::map<std::string, std::string>&)**.
  • Return an osquery Status and map of config sources to JSON-encoded strings.
  • Register the plugin using a string-identifier.The filesystem plugin is very very simple the config plugin architecture expects config plugins to yield valid JSON.

Additional overloads

Packs may be retrieved subsequently after a configuration is read. If pack content is not provided inline with the configuration the string value is passed to the plugin. The config plugin in question must implement the virtualmethod:

  1. Status genPack(const std::string& name, const std::string& value, std::string& pack);

Using the plugin

Now when starting osqueryd you may use —config_plugin=yourconfigpluginname where the name is the string identifier used in REGISTER.