2014-12-18 18:50:47 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2014, Facebook, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
2015-01-02 05:55:10 +00:00
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
2014-12-18 18:50:47 +00:00
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*
|
|
|
|
*/
|
2014-08-05 23:13:55 +00:00
|
|
|
|
2014-12-16 20:04:43 +00:00
|
|
|
#include <syslog.h>
|
|
|
|
|
2015-01-02 05:55:10 +00:00
|
|
|
#include <osquery/config.h>
|
2014-12-03 23:14:02 +00:00
|
|
|
#include <osquery/core.h>
|
2015-01-30 18:44:25 +00:00
|
|
|
#include <osquery/events.h>
|
2014-12-03 23:14:02 +00:00
|
|
|
#include <osquery/flags.h>
|
|
|
|
#include <osquery/filesystem.h>
|
2015-01-12 20:53:05 +00:00
|
|
|
#include <osquery/logger.h>
|
2014-12-03 23:14:02 +00:00
|
|
|
#include <osquery/registry.h>
|
2014-08-05 23:13:55 +00:00
|
|
|
|
2014-08-15 07:25:30 +00:00
|
|
|
namespace osquery {
|
2014-08-05 23:13:55 +00:00
|
|
|
|
2014-10-28 00:37:36 +00:00
|
|
|
const std::string kDescription =
|
|
|
|
"your operating system as a high-performance "
|
|
|
|
"relational database";
|
2014-10-27 16:34:13 +00:00
|
|
|
const std::string kEpilog = "osquery project page <http://osquery.io>.";
|
2014-09-02 00:13:04 +00:00
|
|
|
|
2015-02-05 00:54:44 +00:00
|
|
|
DEFINE_osquery_flag(bool, debug, false, "Enable debug messages");
|
2014-11-13 01:13:15 +00:00
|
|
|
|
|
|
|
DEFINE_osquery_flag(bool,
|
|
|
|
verbose_debug,
|
|
|
|
false,
|
2015-02-05 00:54:44 +00:00
|
|
|
"Enable verbose debug messages");
|
2014-11-13 01:13:15 +00:00
|
|
|
|
2015-02-05 00:54:44 +00:00
|
|
|
DEFINE_osquery_flag(bool, disable_logging, false, "Disable ERROR/INFO logging");
|
2014-11-13 01:13:15 +00:00
|
|
|
|
2014-10-27 18:55:28 +00:00
|
|
|
DEFINE_osquery_flag(string,
|
|
|
|
osquery_log_dir,
|
|
|
|
"/var/log/osquery/",
|
2015-02-05 00:54:44 +00:00
|
|
|
"Directory for ERROR/INFO and results logging");
|
2014-10-27 18:55:28 +00:00
|
|
|
|
2015-02-06 17:42:03 +00:00
|
|
|
DEFINE_osquery_flag(bool,
|
|
|
|
config_check,
|
|
|
|
false,
|
|
|
|
"Check the format of an osquery config");
|
|
|
|
|
|
|
|
#ifndef __APPLE__
|
|
|
|
namespace osquery {
|
|
|
|
DEFINE_osquery_flag(bool, daemonize, false, "Run as daemon (osqueryd only)");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-12-16 20:04:43 +00:00
|
|
|
namespace fs = boost::filesystem;
|
|
|
|
|
|
|
|
void printUsage(const std::string& binary, int tool) {
|
|
|
|
// Parse help options before gflags. Only display osquery-related options.
|
|
|
|
fprintf(stdout, "osquery " OSQUERY_VERSION ", %s\n", kDescription.c_str());
|
|
|
|
if (tool == OSQUERY_TOOL_SHELL) {
|
|
|
|
// The shell allows a caller to run a single SQL statement and exit.
|
|
|
|
fprintf(
|
|
|
|
stdout, "Usage: %s [OPTION]... [SQL STATEMENT]\n\n", binary.c_str());
|
|
|
|
} else {
|
|
|
|
fprintf(stdout, "Usage: %s [OPTION]...\n\n", binary.c_str());
|
|
|
|
}
|
|
|
|
fprintf(stdout,
|
|
|
|
"The following options control the osquery "
|
|
|
|
"daemon and shell.\n\n");
|
|
|
|
|
|
|
|
Flag::printFlags(Flag::get().flags());
|
|
|
|
|
|
|
|
if (tool == OSQUERY_TOOL_SHELL) {
|
|
|
|
// Print shell flags.
|
|
|
|
fprintf(stdout, "\nThe following options control the osquery shell.\n\n");
|
|
|
|
Flag::printFlags(Flag::get().shellFlags());
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(stdout, "\n%s\n", kEpilog.c_str());
|
|
|
|
}
|
|
|
|
|
2015-02-06 17:42:03 +00:00
|
|
|
void announce() {
|
2014-12-16 20:04:43 +00:00
|
|
|
syslog(LOG_NOTICE, "osqueryd started [version=" OSQUERY_VERSION "]");
|
2014-09-09 22:35:34 +00:00
|
|
|
}
|
|
|
|
|
2014-11-09 04:27:28 +00:00
|
|
|
void initOsquery(int argc, char* argv[], int tool) {
|
2014-12-16 20:04:43 +00:00
|
|
|
std::string binary(fs::path(std::string(argv[0])).filename().string());
|
2014-10-27 18:55:28 +00:00
|
|
|
std::string first_arg = (argc > 1) ? std::string(argv[1]) : "";
|
|
|
|
|
2015-01-02 05:55:10 +00:00
|
|
|
// osquery implements a custom help/usage output.
|
2014-11-09 04:27:28 +00:00
|
|
|
if ((first_arg == "--help" || first_arg == "-h" || first_arg == "-help") &&
|
|
|
|
tool != OSQUERY_TOOL_TEST) {
|
2014-12-16 20:04:43 +00:00
|
|
|
printUsage(binary, tool);
|
2014-10-27 16:34:13 +00:00
|
|
|
::exit(0);
|
2014-09-09 22:35:34 +00:00
|
|
|
}
|
|
|
|
|
2014-09-02 00:13:04 +00:00
|
|
|
FLAGS_alsologtostderr = true;
|
|
|
|
FLAGS_logbufsecs = 0; // flush the log buffer immediately
|
|
|
|
FLAGS_stop_logging_if_full_disk = true;
|
2014-11-17 19:38:42 +00:00
|
|
|
FLAGS_max_log_size = 10; // max size for individual log file is 10MB
|
2015-01-26 18:44:27 +00:00
|
|
|
|
|
|
|
// if you'd like to change the default logging plugin, compile osquery with
|
|
|
|
// -DOSQUERY_DEFAULT_CONFIG_PLUGIN=<new_default_plugin>
|
|
|
|
#ifdef OSQUERY_DEFAULT_CONFIG_PLUGIN
|
2015-02-05 00:54:44 +00:00
|
|
|
FLAGS_config_plugin = STR(OSQUERY_DEFAULT_CONFIG_PLUGIN);
|
2015-01-26 18:44:27 +00:00
|
|
|
#endif
|
2014-10-27 01:39:03 +00:00
|
|
|
|
2014-11-09 00:55:19 +00:00
|
|
|
// Set version string from CMake build
|
|
|
|
__GFLAGS_NAMESPACE::SetVersionString(OSQUERY_VERSION);
|
|
|
|
|
2014-10-27 18:55:28 +00:00
|
|
|
// Let gflags parse the non-help options/flags.
|
2014-11-09 04:27:28 +00:00
|
|
|
__GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, false);
|
2014-10-27 01:39:03 +00:00
|
|
|
|
2014-11-13 01:13:15 +00:00
|
|
|
// The log dir is used for glogging and the filesystem results logs.
|
2014-10-27 18:55:28 +00:00
|
|
|
if (isWritable(FLAGS_osquery_log_dir.c_str()).ok()) {
|
|
|
|
FLAGS_log_dir = FLAGS_osquery_log_dir;
|
2014-10-27 01:39:03 +00:00
|
|
|
}
|
2014-10-27 16:34:13 +00:00
|
|
|
|
2014-11-13 01:13:15 +00:00
|
|
|
if (FLAGS_verbose_debug) {
|
2014-11-18 03:31:30 +00:00
|
|
|
// Turn verbosity up to 1.
|
|
|
|
// Do log DEBUG, INFO, WARNING, ERROR to their log files.
|
|
|
|
// Do log the above and verbose=1 to stderr.
|
2014-11-13 01:13:15 +00:00
|
|
|
FLAGS_debug = true;
|
|
|
|
FLAGS_v = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!FLAGS_debug) {
|
2014-11-18 03:31:30 +00:00
|
|
|
// Do NOT log INFO, WARNING, ERROR to stderr.
|
|
|
|
// Do log to their log files.
|
|
|
|
FLAGS_minloglevel = 0; // INFO
|
|
|
|
FLAGS_alsologtostderr = false;
|
2014-11-13 01:13:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (FLAGS_disable_logging) {
|
2014-11-18 03:31:30 +00:00
|
|
|
// Do log ERROR to stderr.
|
|
|
|
// Do NOT log INFO, WARNING, ERROR to their log files.
|
2014-11-13 01:13:15 +00:00
|
|
|
FLAGS_logtostderr = true;
|
2014-11-18 03:31:30 +00:00
|
|
|
FLAGS_minloglevel = 2; // ERROR
|
2014-11-13 01:13:15 +00:00
|
|
|
}
|
|
|
|
|
2015-02-06 17:42:03 +00:00
|
|
|
// Start the logging, and announce the daemon is starting.
|
2014-10-27 18:55:28 +00:00
|
|
|
google::InitGoogleLogging(argv[0]);
|
2015-02-06 17:42:03 +00:00
|
|
|
VLOG(1) << "osquery initializing [version=" OSQUERY_VERSION "]";
|
2015-01-02 05:55:10 +00:00
|
|
|
|
2015-02-06 17:42:03 +00:00
|
|
|
// Run the setup for all non-lazy registries.
|
|
|
|
Registry::setUp();
|
|
|
|
// And finally load the config.
|
2015-02-13 20:32:54 +00:00
|
|
|
auto& config = Config::getInstance();
|
|
|
|
config.load();
|
2015-02-06 17:42:03 +00:00
|
|
|
|
|
|
|
if (FLAGS_config_check) {
|
|
|
|
auto s = Config::checkConfig();
|
|
|
|
if (!s.ok()) {
|
|
|
|
std::cerr << "Error reading config: " << s.toString() << "\n";
|
|
|
|
}
|
|
|
|
::exit(s.getCode());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void initOsqueryDaemon() {
|
|
|
|
#ifndef __APPLE__
|
|
|
|
// OSX uses launchd to daemonize.
|
|
|
|
if (osquery::FLAGS_daemonize) {
|
|
|
|
if (daemon(0, 0) == -1) {
|
|
|
|
::exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Print the version to SYSLOG.
|
|
|
|
announce();
|
|
|
|
|
|
|
|
// Create a process mutex around the daemon.
|
|
|
|
auto pid_status = createPidFile();
|
|
|
|
if (!pid_status.ok()) {
|
|
|
|
LOG(ERROR) << "osqueryd initialize failed: " << pid_status.toString();
|
|
|
|
::exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check the backing store by allocating and exitting on error.
|
|
|
|
if (!DBHandle::checkDB()) {
|
|
|
|
LOG(ERROR) << "osqueryd initialize failed: Could not create DB handle";
|
|
|
|
::exit(EXIT_FAILURE);
|
|
|
|
}
|
2014-08-05 23:13:55 +00:00
|
|
|
}
|
2015-02-01 08:35:44 +00:00
|
|
|
|
|
|
|
void shutdownOsquery() {
|
|
|
|
// End any event type run loops.
|
2015-02-06 17:42:03 +00:00
|
|
|
EventFactory::end();
|
2015-02-01 08:35:44 +00:00
|
|
|
|
|
|
|
// Hopefully release memory used by global string constructors in gflags.
|
|
|
|
__GFLAGS_NAMESPACE::ShutDownCommandLineFlags();
|
|
|
|
}
|
2014-08-15 07:25:30 +00:00
|
|
|
}
|