Search code examples
inotifyosquery

Using osquery wildcards for multi-level patterns


I am using osquery v4.1.1 to monitor file events on a ubuntu box.

$ osqueryi --line "SELECT version, build, platform FROM os_version;"
version = 16.04.3 LTS (Xenial Xerus)
build =
platform = ubuntu
$ osqueryi --line "SELECT version from osquery_info;"
version = 4.1.1

I am trying to watch all the files within the /etc/ directory, recursively, which has the extension .conf using the following wildcard: /etc/%%/%.conf. But, it also reports any files under /etc/. If I create a file /etc/foo, it created a file event for the CREATED event and others with it.

Minimal config to re-produce:

{
  "schedule": {
    "file_events": {
      "query": "SELECT * FROM file_events",
      "interval": "5",
      "removed": "false"
    }
  },
  "file_paths": {
    "sys": ["/etc/%%/%.conf"]
  }
}

These are the file events that I get when I do touch /etc/foo.

{"name":"file_events","hostIdentifier":"<hostname>","calendarTime":"Mon Dec 30 13:56:03 2019 UTC","unixTime":1577714163,"epoch":0,"counter":0,"numerics":false,"columns":{"action":"CREATED","atime":"1577714161","category":"sys","ctime":"1577714161","gid":"0","inode":"389945","mode":"0644","mtime":"1577714161","size":"0","target_path":"/etc/foo","time":"1577714161","uid":"0"},"action":"added"}
{"name":"file_events","hostIdentifier":"<hostname>","calendarTime":"Mon Dec 30 13:56:03 2019 UTC","unixTime":1577714163,"epoch":0,"counter":0,"numerics":false,"columns":{"action":"ATTRIBUTES_MODIFIED","atime":"1577714161","category":"sys","ctime":"1577714161","gid":"0","inode":"389945","mode":"0644","mtime":"1577714161","size":"0","target_path":"/etc/foo","time":"1577714161","uid":"0"},"action":"added"}
{"name":"file_events","hostIdentifier":"<hostname>","calendarTime":"Mon Dec 30 13:56:03 2019 UTC","unixTime":1577714163,"epoch":0,"counter":0,"numerics":false,"columns":{"action":"UPDATED","atime":"1577714161","category":"sys","ctime":"1577714161","gid":"0","inode":"389945","mode":"0644","mtime":"1577714161","size":"0","target_path":"/etc/foo","time":"1577714161","uid":"0"},"action":"added"}

Questions :

  • Is /etc/%%/%.conf even a valid and usable wildcard ?
  • If not, is there a way to achieve the required watch ?
  • If yes, why is it not filtering the events based on the glob ?

I could find the following function: filesystem.cpp#replaceGlobWildcards() but could not understand what exactly it's trying to do apart from trying to extract the base path with no wildcards.

Also, I know that it uses fnmatch but how does it convert the SQL like pattern to fnmatch compatible expression.


Solution

  • The FIM section of the configuration is a fairly broad set of rules about how to setup the inotify watches. You cannot infix a recursive expansion, this is called out in the documentation

    You could use something like /etc/%/%.conf, but that would only get you a single level of search.

    I think you have 2 mechanisms to get the result you like.

    You could setup FIM to watch all of /etc/%% and then have your query include an appropriate WHERE clause. Perhaps SELECT * FROM file_events WHERE target_path like "%.conf"

    Or you could look at the file_paths_query options, and use a sql query to expand the search list. This is also in the documentation