Merge pull request #584 from theopolis/config_example

Provide example config, improve pid check
This commit is contained in:
Teddy Reed 2015-01-07 16:05:42 -08:00
commit 454fb01e98
4 changed files with 130 additions and 63 deletions

View File

@ -106,76 +106,67 @@ std::vector<fs::path> getHomeDirectories() {
return results;
}
Status checkStalePid(const std::string& pidfile_content) {
int pid;
try {
pid = stoi(pidfile_content);
} catch (const std::invalid_argument& e) {
return Status(1, std::string("Could not parse pidfile: ") + e.what());
}
int status = kill(pid, 0);
if (status != ESRCH) {
// The pid is running, check if it is an osqueryd process by name.
std::stringstream query_text;
query_text << "SELECT name FROM processes WHERE pid = " << pid << ";";
auto q = SQL(query_text.str());
if (!q.ok()) {
return Status(1, "Error querying processes: " + q.getMessageString());
}
if (q.rows().size() >= 1 && q.rows().front()["name"] == "osqueryd") {
// If the process really is osqueryd, return an "error" status.
return Status(1,
std::string("osqueryd (") + pidfile_content +
") is already running");
} else {
LOG(INFO) << "Found stale process for osqueryd (" << pidfile_content
<< ") removing pidfile.";
}
}
// Now the pidfile is either the wrong pid or the pid is not running.
try {
boost::filesystem::remove(FLAGS_pidfile);
} catch (boost::filesystem::filesystem_error& e) {
// Unable to remove old pidfile.
LOG(WARNING) << "Unable to remove the osqueryd pidfile.";
}
return Status(0, "OK");
}
Status createPidFile() {
// check if pidfile exists
auto exists = pathExists(FLAGS_pidfile);
if (exists.ok()) {
// if it exists, check if that pid is running
// if it exists, check if that pid is running.
std::string content;
auto read_status = readFile(FLAGS_pidfile, content);
if (!read_status.ok()) {
return Status(1, "Could not read pidfile: " + read_status.toString());
}
int osqueryd_pid;
try {
osqueryd_pid = stoi(content);
} catch (const std::invalid_argument& e) {
return Status(
1,
std::string("Could not convert pidfile content to an int: ") +
std::string(e.what()));
auto stale_status = checkStalePid(content);
if (!stale_status.ok()) {
return stale_status;
}
}
if (kill(osqueryd_pid, 0) == 0) {
// if the pid is running, check if it's osqueryd
std::stringstream query_text;
query_text << "SELECT name FROM processes WHERE pid = " << osqueryd_pid
<< ";";
auto q = SQL(query_text.str());
if (!q.ok()) {
return Status(
1, "Error querying the processes table: " + q.getMessageString());
}
try {
if (q.rows().size() == 1 && q.rows().front()["name"] == "osqueryd") {
// if the process really is osqueryd, return an "error" status
return Status(1, "osqueryd is already running");
} else {
// if it's not osqueryd, some other process has the pid. delete it
// anyway
LOG(INFO) << "found process running with same pid but it's not "
<< "osqueryd, deleting it";
goto delete_pidfile;
}
} catch (const std::exception& e) {
return Status(1,
"An exception was thrown checking the query results: " +
std::string(e.what()));
}
} else if (errno == ESRCH) {
// if the pid isn't running, overwrite the pidfile
delete_pidfile:
try {
boost::filesystem::remove(FLAGS_pidfile);
} catch (boost::filesystem::filesystem_error& e) {
// Unable to remove old pidfile.
LOG(WARNING) << "Unable to remove the old pidfile";
}
goto write_new_pidfile;
} else {
return Status(
1,
std::string(
"An unknown error occured checking if the pid is running: ") +
std::string(strerror(errno)));
}
} else {
// if it doesn't exist, write a pid file and return a "success" status
write_new_pidfile:
auto current_pid = boost::lexical_cast<std::string>(getpid());
LOG(INFO) << "Writing pid (" << current_pid << ") to " << FLAGS_pidfile;
auto write_status = writeTextFile(FLAGS_pidfile, current_pid, 0755);
return write_status;
}
// If no pidfile exists or the existing pid was stale, write, log, and run.
auto pid = boost::lexical_cast<std::string>(getpid());
LOG(INFO) << "Writing osqueryd pid (" << pid << ") to " << FLAGS_pidfile;
auto status = writeTextFile(FLAGS_pidfile, pid, 0644);
return status;
}
}

View File

@ -40,7 +40,7 @@ int main(int argc, char* argv[]) {
auto pid_status = osquery::createPidFile();
if (!pid_status.ok()) {
LOG(ERROR) << "Could not create osquery pidfile: " << pid_status.toString();
LOG(ERROR) << "Could not start osqueryd: " << pid_status.toString();
::exit(EXIT_FAILURE);
}

View File

@ -16,11 +16,10 @@
#include <boost/algorithm/string.hpp>
#include <glog/logging.h>
#include <osquery/core.h>
#include <osquery/tables.h>
#include <osquery/filesystem.h>
#include <osquery/logger.h>
#include <osquery/tables.h>
namespace osquery {
namespace tables {
@ -224,6 +223,12 @@ QueryData genProcesses(QueryContext &context) {
r["pid"] = INTEGER(pid);
r["name"] = getProcName(pid);
r["path"] = getProcPath(pid);
if (r["name"] == "") {
// The name was not available, use the basename of the path.
r["name"] = boost::filesystem::path(r["path"]).filename().string();
}
// The command line invocation including arguments.
r["cmdline"] = boost::algorithm::join(getProcArgs(pid, argmax), " ");
proc_cred cred;

View File

@ -0,0 +1,71 @@
{
/* Configure the daemon below */
"options": {
// Select the osquery config plugin.
"config_retriever": "filesystem",
// Select the osquery logging plugin.
"log_receiver": "filesystem",
// The log directory stores info, warning, and errors.
// If the daemon uses the 'filesystem' logging retriever then the log_dir
// will also contain the query results.
//"osquery_log_dir": "/var/log/osquery",
// Set 'disable_logging' to true to prevent writing any info, warning, error
// logs. If a logging plugin is selected it will still write query results.
//"disable_logging": "false",
// Query differential results are logged as change-events to assist log
// aggregation operatinos like searching and transactons.
// Set 'log_results_events' to log differentials as transactions.
//"log_result_events": "true",
// Splay the scheduled interval for queries.
// This is very helpful to prevent system performance impact when scheduling
// large numbers of queries that run a smaller or similar intervals.
//"schedule_splay_percent": "10",
// Use the system hostname as an identifier for results.
// If hostnames change with DHCP a more static option is 'uuid'.
//"host_identifier": "hostname",
// Write the pid of the osqueryd process to a pidfile/mutex.
//"pidfile": "/var/osquery/osquery.pidfile",
// Disable the osquery event pubsub functionallity.
// Many tables depend on internal OS API events.
//"event_pubsub": "true",
// Clear events from the osquery backing store after a number of seconds.
"event_pubsub_expiry": "86000",
// A filesystem path for disk-based backing storage used for events and
// and query results differentials. See also 'use_in_memory_database'.
//"db_path": "/var/osquery/osquery.db",
// If using a third-party backing store you may want to run completely in
// memory. Currently rocksdb must use disk-based storage.
//"use_in_memory_database": "false",
// Enable debug or verbose debug output when logging.
"debug": "false",
"verbose_debug": "false",
// The number of threads for concurrent query schedule execution.
"worker_threads": "4"
},
/* Define a schedule of queries */
"scheduledQueries": [
// This is a simple example query that outputs information about osquery.
{
// More complicated queries benefit from a name such as 'my_processes'.
"name": "info",
// The exact query to run, include a semi-colon.
"query": "SELECT * FROM osquery_info;",
// The interval in seconds to run this query, not an exact interval.
"interval": 3600
}
]
}