https://github.com/osquery/osquery logo
g

Gilad Reich

02/01/2023, 8:51 AM
Hello everyone! 👋 Maybe a quick question; is it possible to load a custom Osquery extension via the
osquery.conf
file? I was looking into some of the available `options` using
osqueryd --help
command. However I only see that
extensions_*
related flags are only possible to pass via CLI flags, not configuration flags. This is because possible flags are split into two sections: •
osquery command line flags
osquery configuration options (set by config or CLI flags)
I was checking other possible ways to load my extension via the osquery flags file, but unfortunately I'm quite limited in how I can pass arguments to Osquery due to limitation in Wazuh's Wodle design: https://github.com/wazuh/wazuh/issues/16062 If there is another way to load extensions (like maybe global configurations that Osquery always know about), this would solve my problem. Many thanks for your attention! 🙂
z

zwass

02/01/2023, 5:46 PM
If you want to autoload an extension, you need to specify that in the CLI flags. You could however just start up your extension process separately and have it try to connect to osquery. Might that work?
g

Gilad Reich

02/01/2023, 7:41 PM
Hi @zwass, many thanks for your help. The problem is that Wazuh starting Osquery as a child-process. So I need to tell Osquery somehow to auto-load my custom extension from a specific path in disk whenever it started. I saw the approach of starting the extension with a given path to Osquery’s socket, but the idea is that without touching anything, whenever Osquery process starts, it knows that it needs to load the extension.
Before I go down the long road, one possibility for me would be to implement that in Osquery codebase myself to load such configuration and make it load the extension. But then I would have to take care of packaging for macOS (signing & notarizing), Linux and Windows. I was thinking it would make sense to add to the
options
category in
osquery.conf
a new field to accept array of paths to extensions from disk:
Copy code
"options": {
    "extensions": [
      "path/to/extension1",
      "path/to/extension2"
    ],
  },
or alternative way would be to give it extension dir path and whatever extensions in that dir will be automatically loaded:
Copy code
"options": {
    "extensions_dir": "path/to/dir/with/extensions"
  },
But I’d rather not go down this rabbit hole and looking for alternatives.
Even ugly hacks will be welcomed!
Found one way to solve this. In
extensions.cpp
I found this:
Copy code
CLI_FLAG(string,
         extensions_autoload,
         OSQUERY_HOME "extensions.load",
         "Optional path to a list of autoloaded & managed extensions");
Looks like the paths are hardcoded to where
OSQUERY_HOME
is:
Copy code
#if defined(__linux__)
#define OSQUERY_HOME "/etc/osquery/"
#define OSQUERY_DB_HOME "/var/osquery/"
#define OSQUERY_SOCKET OSQUERY_DB_HOME
#define OSQUERY_PIDFILE "/var/run/"
#define OSQUERY_LOG_HOME "/var/log/osquery/"
#define OSQUERY_CERTS_HOME "/opt/osquery/share/osquery/certs/"
#elif defined(WIN32)
#define OSQUERY_HOME "\\Program Files\\osquery\\"
#define OSQUERY_DB_HOME OSQUERY_HOME
#define OSQUERY_SOCKET "\\\\.\\pipe\\"
#define OSQUERY_PIDFILE OSQUERY_DB_HOME
#define OSQUERY_LOG_HOME OSQUERY_HOME "log\\"
#define OSQUERY_CERTS_HOME OSQUERY_HOME "certs\\"
#elif defined(FREEBSD)
#define OSQUERY_HOME "/var/db/osquery/"
#define OSQUERY_DB_HOME OSQUERY_HOME
#define OSQUERY_SOCKET "/var/run/"
#define OSQUERY_PIDFILE "/var/run/"
#define OSQUERY_LOG_HOME "/var/log/osquery/"
#define OSQUERY_CERTS_HOME "/etc/ssl/"
#else
#define OSQUERY_HOME "/var/osquery/"
#define OSQUERY_DB_HOME OSQUERY_HOME
#define OSQUERY_SOCKET OSQUERY_DB_HOME
#define OSQUERY_PIDFILE OSQUERY_DB_HOME
#define OSQUERY_LOG_HOME "/var/log/osquery/"
#define OSQUERY_CERTS_HOME OSQUERY_HOME "certs/"
#endif
Kinda weird and I wish the devs wouldn’t use hardcoded preprocessor here and made it configureable. This is because I’m packaging Osquery in a single folder within the Wazuh agent installation in order to have everything in one place. So the “hack” here was to create
extensions.load
file within the custom osquery directory. Inside this file give it the path to where the actual extension to be loaded (as officially documented). Then creating a symbolic link to the path from where the custom packaged Osquery installation is to
/var/osquery
, e.g.:
Copy code
ln -s /My/Custom/Path/osquery /var/osquery
And osquery will auto-load the
extensions.load
file. IMHO it would have been much nicer to be able to configure this as suggested above.
z

zwass

02/01/2023, 9:46 PM
It needs to be done as part of the startup flags because there can be config extensions that need to be loaded for startup to complete.
g

Gilad Reich

02/01/2023, 10:29 PM
From what I’ve seen in code, the options section is loaded first.
As another (maybe better) alternative; creating the
osquery.flags.default
file in the default paths and adding a startup flag in there to load the extension. e.g. content of `osquery.flags.default`:
Copy code
--extension=/path/to/ext/myext
since one can always append there more startup flags and not necessarily be doomed to the enforced logic of having to set my extension name with
.ext
suffix (unless I’m missing the rational behind it): https://osquery.slack.com/archives/CBMR0L7SM/p1675359720465939 But I’m still a bit unhappy by the fact that I have to create this symbolic link to trick it to think that it’s located in the default path.
s

seph

02/05/2023, 4:30 PM
options are split between config flags, and CLI-only flags mostly because of osquery startup sequencing. (And some concern about forcing features to be disabled outside of configuration) There may be flags that could move from one set to the other, but I would recommend discussion about it before making a PR.
I’m not sure I understand why you’re complaining about hardcoded defaults. At some level, these things need to be set for startup to succeed. So either they get hardcoded, or you block startup for bad or missing configuration. As documented in https://osquery.readthedocs.io/en/stable/installation/cli-flags/ there is a
--flagfile
argument that can be used to specify flags. It is further documented as:
Copy code
If no --flagfile is provided, osquery will try to find and use a "default" flagfile at /etc/osquery/osquery.flags.default. Both the shell and daemon will discover and use the defaults.
Though I’m not sure how that applies to windows.
At least partly, it sounds like wazuh should really expose things.
g

Gilad Reich

02/05/2023, 4:38 PM
options are split between config flags, and CLI-only flags mostly because of osquery startup sequencing. (And some concern about forcing features to be disabled outside of configuration)
Thanks @seph. Yeah, I realized while digging into the sequencing of loading things. There is still some inconsistency there though; like there are some options that are not documented as startup flags, but could be used in both scenarios. As an example, take a look at
logger_path
, which is documented as option, but could also be passed as startup flag.
s

seph

02/05/2023, 4:39 PM
One is a subset. There are FLAGS which can be in the config, or command line (or I assume flagfile, but I don’t know for sure) And there are CLI_FLAGS, which are cli or flag file only.
g

Gilad Reich

02/05/2023, 4:39 PM
The main trigger that motivated me to dig into this topic, is because of Wazuh limitation in the current design, which I created a proposal for them: https://github.com/wazuh/wazuh/issues/16085
s

seph

02/05/2023, 4:40 PM
osqueryd --help
splits them into sections: • osquery command line flags • osquery configuration options (set by config or CLI flags)
You may also need to think about when osquery needs to be restarted after those change. But I don’t know much about wazuh.
g

Gilad Reich

02/05/2023, 4:41 PM
I also wished Osquery had a startup flag to override the hardcoded preprocessor
OSQUERY_HOME
dir, so that I don’t have to override all possible flags to make my installation portable. e.g.:
osqueryd --home_dir my/custom/path
.
s

seph

02/05/2023, 4:42 PM
I also wished Osquery had a startup flag to override the hardcoded preprocessor OSQUERY_HOME dir.
yeah, I agree. that does seem reasonable. I have no idea how easy it would be to implement, It might be trivial, or it might have sprawling effects on startup
g

Gilad Reich

02/05/2023, 4:43 PM
osqueryd --help
splits them into sections:
• osquery command line flags
• osquery configuration options (set by config or CLI flags)
Exactly, and some flags are in the configuration options section, but I can also override them as in startup flags as the case with the
logger_path
.
s

seph

02/05/2023, 4:46 PM
I don’t understand the inconsistency you’re calling out.
g

Gilad Reich

02/05/2023, 4:56 PM
If we look at the two sections when running
osqueryd --help
, from what I understood; • command line flags (aka startup flags), are passed directly at startup to the
osqueryd
executable as arguments or via the
--flagfile
• Options are being set via
osquery.conf
file They are split into two sections because they can’t be used interchangeably to keep them separate from each other, right? Meaning that you can’t set command line flags in the
osquery.conf
, and same apply that you can’t set options as command line flags. If so far I’m understanding correctly, then I was able to set some options as command line flags whilst they’re not documented so. As an example the
logger_path
option, may be provided directly as command line flag:
osqueryd --logger_path my/custom/path
s

seph

02/05/2023, 5:09 PM
That sounds like the inverse. Most flags can be set in the config, or passed on the CLI. Since they can be set in the config, they are also controllable by a remote TLS server Some flags, either because they’re important for startup or because they’re deemed privacy sensitive, cannot be set by the TLS controlled server. But they can just as well be set on the command line.
(I’m going idle. I’ll catch up here eventually)
g

Gilad Reich

02/05/2023, 5:17 PM
I see, that makes sense.
Some flags, either because they’re important for startup or because they’re deemed privacy sensitive, cannot be set by the TLS controlled server. But they can just as well be set on the command line.
That’s exactly the part that could be documented better per option/flag, since checking the docs I was under the assumption that whatever I see in the options section can’t be provided as startup flags, until I tried out.
Many thanks for the insights and your time, @seph!