0%

Osquery检测框架初探

一、起源

大四第一次实习期间曾在公司项目中接触过这个东西,当时还不太了解应用场景,只当成是一个查询主机信息(query os)的普通跨平台开源项目,觉得它用sql进行查询的设计方式很奇怪;第三次实习期间实验室老大手把手教着写安全模型,其中模型计算所用的数据就是osquery在vpc里采集来的,那时才对osquery这类主机数据采集的应用场景有了些了解;后来真正投身主机安全领域才慢慢了解到osquery应用场景还是挺广泛的,目前国内也有很多甲方厂商在安全建设中用直接用它来做数据采集(包括一些知名厂子),而此项目之所以受到甲方安全欢迎,很大程度上包含以下几点原因:

1、轮子

2、稳定

3、扩展

首先很多甲方安全部门可能人比较少,甚至存在一个人的安全部,直接用轮子相比从头自研工作量小踩坑少见效快,只要环境不是太过特殊,或者对安全有非常高的要求,其实没有必要定制化;其次,osquery这个项目从2014年开源起已经过去很久了,加上不那么侵入的技术选型和各种优化,它的稳定性还是有一个比较好的保障(技术特性+时间考验+大众审计+业界反馈),而稳定恰恰是甲方最关心的一点,安全不能影响业务,不能因为安全问题带来业务问题;最后,osquery功能的可扩展性也是一个点,osquery是不带server的,这使得osquery其实无法直接成为一个hids,而只能是一个数据采集框架,也是因为这点,甲方安全人员可以基于数据采集进行各种扩展和场景适配,同时osquery本身带有一些心跳监控和日志记录等较灵活的功能,甲方人员可以基于osquery本身较强和灵活的功能特点对osquery的后续做框架拼接,做消息缓存,做实时检测,做离线计算等,利用osquery良好的兼容性和稳定性在甲方特有的较大量级(百万级)资产场景下部署并完成每一台主机的细粒度监控、处置

之所以写这篇文章是因为考虑一两年两三年后可能也会去甲方也做类似的主机安全建设,所以先提前记录一波,顺带着思考一下应用场景、需求、能力、价值、架构设计等等(可能以上列举的跟真实的甲方安全需求并不完全一致,期待后续能真正参与到像美团那样量级的hids安全建设中学习一下)

二、基本使用

介绍

osquery是facebook开源的一款基于sql引擎的跨平台主机信息查询和监控框架;osquery的设计思想比较奇特,其将主机比作一个数据库,将主机产生的日志信息当成库表,支持使用sql语法对表中存储的主机日志信息进行查询;osquery支持查询的信息几乎涵盖主机产生的所有类型的日志数据,查询方式支持实时和调度,非常灵活

安装

osquery项目主页上可以进行下载,支持源码安装和安装包安装,这边在ubuntu16.04下进行源码安装:

1
2
3
4
5
export OSQUERY_KEY=1484120AC4E9F8A1A577AEEE97A80C63C9D8B80B
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys $OSQUERY_KEY
sudo add-apt-repository 'deb [arch=amd64] https://pkg.osquery.io/deb deb main'
sudo apt-get update
sudo apt-get install osquery

可以通过运行osqueryi查看是否安装成功

运行

osqueryi

内置命令

osqueryi和osqueryd是两个完全分离的程序,osqueryi支持用户终端界面基于sql做交互查询,osqueryd是osquery守护进程,运行后会在后台静默部署以服务形式基于配置文件采集数据,一般如果是测试可以用osqueryi,实际环境下都是用osqueryd;运行osqueryi,进入交互模式后可以先看下内置命令,这边注释都很清晰:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
➜  ~ osqueryi
Using a virtual database. Need help, type '.help'
osquery> .help
Welcome to the osquery shell. Please explore your OS!
You are connected to a transient 'in-memory' virtual database.

.all [TABLE] Select all from a table
.bail ON|OFF Stop after hitting an error
.echo ON|OFF Turn command echo on or off
.exit Exit this program
.features List osquery's features and their statuses
.headers ON|OFF Turn display of headers on or off
.help Show this message
.mode MODE Set output mode where MODE is one of:
csv Comma-separated values
column Left-aligned columns see .width
line One value per line
list Values delimited by .separator string
pretty Pretty printed SQL results (default)
.nullvalue STR Use STRING in place of NULL values
.print STR... Print literal STRING
.quit Exit this program
.schema [TABLE] Show the CREATE statements
.separator STR Change separator used by output mode
.socket Show the osquery extensions socket path
.show Show the current values for various settings
.summary Alias for the show meta command
.tables [TABLE] List names of tables
.types [SQL] Show result of getQueryColumns for the given query
.width [NUM1]+ Set column widths for "column" mode
.timer ON|OFF Turn the CPU timer measurement on or off

比较常用的几个如下:

1
2
3
4
5
.mode: sql查询结果的显示模式
.schema: 后面跟表名输出表结构
.show: 输出osqueryi当前的配置
.features: 列出osquery的功能和开启状态
.tables: 列出当前osquery支持的所有表名

sql语法

官方文档里说明了osqueryi修改自sqlite shell,所以其支持原生sqlite的sql查询语法:

osqueryi is a modified version of the SQLite shell. It accepts several meta-commands, prefixed with a ‘.’:

具体支持的表的类型、结构、描述都在官网有说明,文档非常清晰,不得不说osquery在项目文档这块做的是真的好;带evented_table标识的表示此表事件来自于(auditd)实时收集:

image-20201029111821393

osqueryd

启动

安装后自动注册systemctl:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
➜  ~ systemctl status osqueryd.service
● osqueryd.service - The osquery Daemon
Loaded: loaded (/usr/lib/systemd/system/osqueryd.service; disabled; vendor preset: enabled)
Active: inactive (dead)
➜ ~ systemctl restart osqueryd.service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to restart 'osqueryd.service'.
Authenticating as: xdw,,, (xdw)
Password:
==== AUTHENTICATION COMPLETE ===
➜ ~ systemctl status osqueryd.service
● osqueryd.service - The osquery Daemon
Loaded: loaded (/usr/lib/systemd/system/osqueryd.service; disabled; vendor preset: enabled)
Active: active (running) since Thu 2020-10-29 11:30:49 CST; 2s ago
Process: 20897 ExecStartPre=/bin/sh -c if [ -f $LOCAL_PIDFILE ]; then mv $LOCAL_PIDFILE $PIDFILE; fi (code=e
Process: 20881 ExecStartPre=/bin/sh -c if [ ! -f $FLAG_FILE ]; then touch $FLAG_FILE; fi (code=exited, statu
Main PID: 20900 (osqueryd)
Tasks: 13
Memory: 7.4M
CPU: 37ms
CGroup: /system.slice/osqueryd.service
├─20900 /usr/bin/osqueryd --flagfile /etc/osquery/osquery.flags --config_path /etc/osquery/osquery.
└─20917 /usr/bin/osqueryd

Oct 29 11:30:49 ubuntu systemd[1]: Stopped The osquery Daemon.
Oct 29 11:30:49 ubuntu systemd[1]: Starting The osquery Daemon...
Oct 29 11:30:49 ubuntu systemd[1]: Started The osquery Daemon.
Oct 29 11:30:49 ubuntu osqueryd[20900]: osqueryd started [version=4.5.1]
Oct 29 11:30:49 ubuntu osqueryd[20900]: W1029 11:30:49.270629 20917 init.cpp:587] Error reading config: config
Oct 29 11:30:49 ubuntu osqueryd[20900]: I1029 11:30:49.270979 20917 events.cpp:867] Event publisher not enable
Oct 29 11:30:49 ubuntu osqueryd[20900]: I1029 11:30:49.271317 20917 events.cpp:867] Event publisher not enable
➜ ~

配置

osqueryd两个配置文件路径默认都在/etc/osquery/目录下,分别为osquery.conf,osquery.flags,前者存储osqueryd运行后的一些配置,后者则为标志位存储文件,即用标志位表示程序启动时的功能启停设置,具体标志位详情见Command Line Flags;另外之前试过把osquery.flags中的内容放到osquery.conf中,效果和分开存储是一样的,就跟spoock师傅说的一样,其实osquery.conf可以说是osquery.flags的一个超集;

osquery.conf

osquery项目提供了一份配置样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
{
// Configure the daemon below:
"options": {
// Select the osquery config plugin.
"config_plugin": "filesystem",

// Select the osquery logging plugin.
"logger_plugin": "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.
//"logger_path": "/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",

// 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",

// A filesystem path for disk-based backing storage used for events and
// query results differentials. See also 'use_in_memory_database'.
//"database_path": "/var/osquery/osquery.db",

// Comma-delimited list of table names to be disabled.
// This allows osquery to be launched without certain tables.
//"disable_tables": "foo_bar,time",

// Comma-delimited list of table names to be enabled.
// This allows osquery to be launched with certain tables only.
//"enable_tables": "foo_bar,time",

"utc": "true"
},

// Define a schedule of queries:
"schedule": {
// This is a simple example query that outputs basic system information.
"system_info": {
// The exact query to run.
"query": "SELECT hostname, cpu_brand, physical_memory FROM system_info;",
// The interval in seconds to run this query, not an exact interval.
"interval": 3600
}
},

// Decorators are normal queries that append data to every query.
"decorators": {
"load": [
"SELECT uuid AS host_uuid FROM system_info;",
"SELECT user AS username FROM logged_in_users ORDER BY time DESC LIMIT 1;"
]
},

// Add default osquery packs or install your own.
//
// There are several 'default' packs installed with 'make install' or via
// packages and/or Homebrew.
//
// Linux: /usr/share/osquery/packs
// OS X: /var/osquery/packs
// Homebrew: /usr/local/share/osquery/packs
// make install: {PREFIX}/share/osquery/packs
//
"packs": {
// "osquery-monitoring": "/usr/share/osquery/packs/osquery-monitoring.conf",
// "incident-response": "/usr/share/osquery/packs/incident-response.conf",
// "it-compliance": "/usr/share/osquery/packs/it-compliance.conf",
// "osx-attacks": "/usr/share/osquery/packs/osx-attacks.conf",
// "vuln-management": "/usr/share/osquery/packs/vuln-management.conf",
// "hardware-monitoring": "/usr/share/osquery/packs/hardware-monitoring.conf",
// "ossec-rootkit": "/usr/share/osquery/packs/ossec-rootkit.conf",
// "windows-hardening": "C:\\Program Files\\osquery\\packs\\windows-hardening.conf",
// "windows-attacks": "C:\\Program Files\\osquery\\packs\\windows-attacks.conf"
},

// Provides feature vectors for osquery to leverage in simple statistical
// analysis of results data.
//
// Currently this configuration is only used by Windows in the Powershell
// Events table, wherein character_frequencies is a list of doubles
// representing the aggregate occurrence of character values in Powershell
// Scripts. A default configuration is provided which was adapated from
// Lee Holmes cobbr project:
// https://gist.github.com/cobbr/acbe5cc7a186726d4e309070187beee6
//
"feature_vectors": {
"character_frequencies": [
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.00045, 0.01798,
0.0, 0.03111, 0.00063, 0.00027, 0.0, 0.01336, 0.0133,
0.00128, 0.0027, 0.00655, 0.01932, 0.01917, 0.00432, 0.0045,
0.00316, 0.00245, 0.00133, 0.001029, 0.00114, 0.000869, 0.00067,
0.000759, 0.00061, 0.00483, 0.0023, 0.00185, 0.01342, 0.00196,
0.00035, 0.00092, 0.027875, 0.007465, 0.016265, 0.013995, 0.0490895,
0.00848, 0.00771, 0.00737, 0.025615, 0.001725, 0.002265, 0.017875,
0.016005, 0.02533, 0.025295, 0.014375, 0.00109, 0.02732, 0.02658,
0.037355, 0.011575, 0.00451, 0.005865, 0.003255, 0.005965, 0.00077,
0.00621, 0.00222, 0.0062, 0.0, 0.00538, 0.00122, 0.027875,
0.007465, 0.016265, 0.013995, 0.0490895, 0.00848, 0.00771, 0.00737,
0.025615, 0.001725, 0.002265, 0.017875, 0.016005, 0.02533, 0.025295,
0.014375, 0.00109, 0.02732, 0.02658, 0.037355, 0.011575, 0.00451,
0.005865, 0.003255, 0.005965, 0.00077, 0.00771, 0.002379, 0.00766,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0
]
}
}

其中主要包含如下几个字段:

1
2
3
4
5
6
options
config_plugin
logger_plugin
schedule
decorators
packs

options

官方文档给出的描述如下,那些不是用来控制启动配置的flags被归类为options内:

Flags that do not control startup settings may be included as “options” within configuration. Essentially, any flag needed to help osquery determine and discover a configuration must be supplied via command-line arguments. Google Flags enhances this to allow flags to be set within environment variables or via a “master” flag file.

config_plugin

配置相关的选项,默认是从本地磁盘上读取配置的,即filesystem选项,一旦配置为filesystem,则从config_path指向的路径读取配置;除了filesystem,osquery还支持tls读取配置,不过由于暂时未涉及,暂时不深入,猜测是用于集群环境下的批量配置部署:

–config_plugin=filesystem

Config plugin name. The type of configuration retrieval, the default filesystem plugin reads a configuration JSON from disk.

Built-in options include: filesystem, tls

–config_path=/etc/osquery/osquery.conf

logger_plugin

日志记录相关的配置,默认将osquery产生的日志保存在文件上(filesystem),除了本地文件存储,osquery还支持tls、syslog、kafka_producer等传输日志消息;支持多日志记录插件配置:

–logger_plugin=filesystem

Logger plugin name. The default logger is filesystem. This writes the various log types as JSON to specific file paths.

Multiple logger plugins may be used simultaneously, effectively copying logs to each interface. Separate plugin names with a comma when specifying the configuration (–logger_plugin=filesystem,syslog).

Built-in options include: filesystem, tls, syslog, and several Amazon/AWS options.

–disable_logging=false

osquery includes logger plugins that support configurable logging to a variety of interfaces. The built in logger plugins are filesystem (default), tls, syslog (for POSIX), windows_event_log (for Windows), kinesis, firehose, and kafka_producer. Multiple logger plugins may be used simultaneously, effectively copying logs to each interface. To enable multiple loggers set the –logger_plugin option to a comma separated list, do not include spaces, of the requested plugins.

For information on configuring logger plugins, see logging/results flags. Developing new logger plugins is explored in the development docs. We recommend setting the logger plugin and logger settings via the osquery flagfile.

日志入kafka

配置如下,具体见文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
ubuntu@VM-0-17-ubuntu:~$ cat /etc/osquery/osquery.conf
{
"options": {
"config_plugin": "filesystem",
"logger_plugin": "kafka_producer",
"logger_path": "/var/log/osquery",
"disable_logging": "false",
"log_result_events": "true",
"schedule_splay_percent": "10",
"pidfile": "/var/osquery/osquery.pidfile",
"events_expiry": "3600",
"database_path": "/var/osquery/osquery.db",
"verbose": "false",
"worker_threads": "6",
"enable_monitor": "true",
"disable_events": "false",
"disable_audit": "false",
"audit_allow_config": "true",
"host_identifier": "hostname",
"enable_syslog": "true",
"audit_allow_sockets": "true",
"schedule_default_interval": "3600",
"logger_kafka_brokers": "127.0.0.1:9092",
"logger_kafka_topic": "process-port",
"logger_kafka_acks": "1"
},
"schedule": {
"process": {
"query": "SELECT * FROM process_events;",
"interval": 3600
}
},
"decorators": {
"load": [
"SELECT uuid AS host_uuid FROM system_info;",
"SELECT user AS username FROM logged_in_users ORDER BY time DESC LIMIT 1;"
]
},
"packs": {
"osquery-monitoring": "/usr/share/osquery/packs/osquery-monitoring.conf",
"incident-response": "/usr/share/osquery/packs/incident-response.conf",
"it-compliance": "/usr/share/osquery/packs/it-compliance.conf",
"vuln-management": "/usr/share/osquery/packs/vuln-management.conf",
"system-snapshot": {
"queries": {
"processes_by_port": {
"query": "select * from process_events",
"interval": 3600,
"snapshot": false
}
}
}
},
"kafka_topics": {
"process-port": [
"pack_system-snapshot_processes_by_port"
]
}
}

image-20201029152149095

schedule

osquery调度相关,query里是查询语句,interval代表调度周期,其它一些比较重要的可选字段如removed,snapshot等都在文档中有解释;其中snapshot这个字段比较重要,它表示查询结果是增量模式还是快照模式,若为快照模式,则输出当时查询的全量结果,若为增量模式,则每次查询只输出与上次查询有差异的部分(增量),这个要注意一下:

1
2
3
4
5
6
7
8
9
"schedule": {
// This is a simple example query that outputs basic system information.
"system_info": {
// The exact query to run.
"query": "SELECT hostname, cpu_brand, physical_memory FROM system_info;",
// The interval in seconds to run this query, not an exact interval.
"interval": 3600
}
},
1
2
3
4
5
6
7
8
9
10
The basic scheduled query specification includes:

query: the SQL query to run
interval: an interval in seconds to run the query (subject to splay/smoothing)
removed: a boolean to determine if "removed" actions should be logged, default true
snapshot: a boolean to set 'snapshot' mode, default false
platform: restrict this query to a given platform, default is 'all' platforms; you may use commas to set multiple platforms
version: only run on osquery versions greater than or equal-to this version string
shard: restrict this query to a percentage (1-100) of target hosts
denylist: a boolean to determine if this query may be denylisted (when stopped for excessive resource consumption), default true

decorators

decorators,为osquery查询结果增加额外的装饰器,大意就是配置装饰器将在查询前后执行装饰器内部定义的查询语句并将结果添加到osquery日志结果中去;装饰器支持几种模式,load是在每次配置加载时启动装饰器,always在schedule中的每条语句执行前运行装饰器,interval则是以调度模式启动装饰器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Decorator queries exist in osquery versions 1.7.3+ and are used to add additional "decorations" to results and snapshot logs. There are three types of decorator queries based on when and how you want the decoration data.

{
"decorators": {
"load": [
"SELECT version FROM osquery_info;",
"SELECT uuid AS host_uuid FROM system_info;"
],
"always": [
"SELECT user AS username FROM logged_in_users WHERE user <> '' ORDER BY time LIMIT 1;"
],
"interval": {
"3600": [
"SELECT total_seconds AS uptime FROM uptime;"
]
}
}
}
The types of decorators are:

load: run these decorators when the configuration loads (or is reloaded)
always: run these decorators before each query in the schedule
interval: a special key that defines a map of interval times, see below

Each decorator query should return at most 1 row. A warning will be generated if more than 1 row is returned as they will be forcefully ignored and constitute undefined behavior. Each decorator query should be careful not to emit column collisions, this is also undefined behavior.

The columns, and their values, will be appended to each log line as follows. Assuming the above set of decorators is used, and the schedule is execution for over an hour (3600 seconds):

目前只试过load:

1
2
3
4
5
6
"decorators": {
"load": [
"SELECT uuid AS host_uuid FROM system_info;",
"SELECT user AS username FROM logged_in_users ORDER BY time DESC LIMIT 1;"
]
},

image-20201029144955777

packs

打包好的sechdule查询语句,可以将同一类型的查询语句打包放在一个packs中,osquery项目自带了一些默认的packs集合:

The above section on packs almost covers all you need to know about query packs. The specification contains a few caveats since packs are designed for distribution. Packs use the packs key, a map where the key is a pack name and the value can be either a string or a dictionary (object). When a string is used the value is passed back into the config plugin and acts as a “resource” request.

1
2
3
4
5
6
7
8
9
10
11
"packs": {
// "osquery-monitoring": "/usr/share/osquery/packs/osquery-monitoring.conf",
// "incident-response": "/usr/share/osquery/packs/incident-response.conf",
// "it-compliance": "/usr/share/osquery/packs/it-compliance.conf",
// "osx-attacks": "/usr/share/osquery/packs/osx-attacks.conf",
// "vuln-management": "/usr/share/osquery/packs/vuln-management.conf",
// "hardware-monitoring": "/usr/share/osquery/packs/hardware-monitoring.conf",
// "ossec-rootkit": "/usr/share/osquery/packs/ossec-rootkit.conf",
// "windows-hardening": "C:\\Program Files\\osquery\\packs\\windows-hardening.conf",
// "windows-attacks": "C:\\Program Files\\osquery\\packs\\windows-attacks.conf"
},

/usr/share/osquery/packs/osquery-monitoring.conf

osquery自带的状态监控pack:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"queries": {
"schedule": {
"query": "select name, interval, executions, output_size, wall_time, (user_time/executions) as avg_user_time, (system_time/executions) as avg_system_time, average_memory, last_executed from osquery_schedule;",
"interval": 7200,
"removed": false,
"blacklist": false,
"version": "1.6.0",
"description": "Report performance for every query within packs and the general schedule."
},
"events": {
"query": "select name, publisher, type, subscriptions, events, active from osquery_events;",
"interval": 86400,
"removed": false,
"blacklist": false,
"version": "1.5.3",
"description": "Report event publisher health and track event counters."
},
"osquery_info": {
"query": "select i.*, p.resident_size, p.user_time, p.system_time, time.minutes as counter from osquery_info i, processes p, time where p.pid = i.pid;",
"interval": 600,
"removed": false,
"blacklist": false,
"version": "1.2.2",
"description": "A heartbeat counter that reports general performance (CPU, memory) and version."
}
}
}

Fim_monitor

/usr/share/osquery/packs下创建fim.conf,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"queries": {
"file_events": {
"query": "SELECT * FROM file_events;",
"removed": false,
"interval": 300
}
},
"file_paths": {
"homes": [
"/root/.ssh/%%",
"/home/%/.ssh/%%"
],
"etc": [
"/etc/%%"
],
"home": [
"/home/%%"
],
"tmp": [
"/tmp/%%"
],
"www": [
"/var/www/%%"
]
}
}

在osquery.conf中的packs段添加文件完整性监控配置:

1
2
3
4
"packs": {
"osquery-monitoring": "/usr/share/osquery/packs/osquery-monitoring.conf",
"fim": "/usr/share/osquery/packs/fim.conf"
}

osquery.flags

基本都在CommandLineFlags中,不再详述

log

本地日志存储在/var/log/osquery/目录下,几个软链接指向的都是当前最新修改的日志文件;其中osqueryi.xxxxx和osqueryd.xxxxxx分别存储osqueryi和osqueryd的相关日志输出,前面也说过二者是分离的;error存储osquery运行过程中的一些报错日志,warn存储告警日志,info存储运行日志,results.log存储增量日志,snapshot存储快照日志,具体放在哪个文件里由前面的配置决定:

image-20201029150410846

Snapshot logs
Snapshot logs are an alternate form of query result logging. A snapshot is an ‘exact point in time’ set of results, with no differentials. For instance if you always want a list of mounts, not the added and removed mounts, then use a snapshot. In the mounts case, where differential results are seldom emitted (assuming hosts do not often mount and unmount), a complete snapshot will log after every query execution. This will be a lot of data amortized across your fleet.

Data snapshots may generate a large amount of output. For log collection safety, output is written to a dedicated sink. The filesystem logger plugin writes snapshot results to /var/log/osquery/osqueryd.snapshots.log.

The osquery daemon uses a default filesystem logger plugin. Like the config, output from the filesystem plugin is written as JSON. Results from the query schedule are written to /var/log/osquery/osqueryd.results.log.

There are two types of logs:

Status logs (INFO, WARNING, ERROR)
Query schedule results logs, including logs from snapshot queries

三、问题

之前玩osquery的时候遇到过一些问题,记录一下:

1、auditd占用

用户态的原生的auditd应用在osqueryd启动时应该kill掉,由osquery自实现audit系统接管netlink,否则可能会因为netlink占用问题起冲突,一些由内核kauditd捕获的实时事件无法通过netlink传输到osquery audit审计系统,从而导致部分走auditd获取数据的表的sql查询输出为空,相关问题其实文档里已经有说明了,当时记得折腾了半天:

On Linux, osquery uses the Audit system to collect and process audit events from the kernel. It accomplishes this by monitoring the execve() syscall. auditd should not be running when using osquery’s process auditing, as it will conflict with osqueryd over access to the audit netlink socket. You should also ensure auditd is not configured to start at boot.

2、osqueryi和osqueryd同时运行

osqueryi和osqueryd若同时运行,先运行者会占用后运行者的auditd数据传输通道,从而导致只有前者能获取到数据而后者无法获取到

3.etc.

后续有发现继续记录

四、总结

针对osquery的使用结合自身的一些经历做了一个比较粗糙的分析,后续在使用上有了新的发现将继续在此篇进行补充,另外不得不提一下osquery的文档做的是真的好,细节说明非常清晰,各种配置、参数、使用方式、问题等都能在文档中找到,之后将继续对文档深入学习;随着对osquery的慢慢熟悉,后续将进行较深入一点的架构层次上的学习与分析;osquery相关的文章国内研究输出的好像不是非常多,这边都是参考spoock师傅的教程,写的是真的好,受益匪浅

五、参考链接

https://blog.spoock.com/2018/11/27/usage-of-osqueryd/

https://blog.spoock.com/2018/11/26/osquery-intro/