Linux 提供了许多命令来帮助用户收集关于其主机操作系统的信息:列出文件或目录以检查属性;查询以查看安装了哪些软件包、正在运行哪些进程以及哪些服务在启动时启动;或者了解系统的硬件。
每个命令都使用自己的输出格式来列出这些信息。你需要使用诸如 grep
、sed
和 awk
之类的工具来过滤结果以找到特定信息。此外,很多此类信息会频繁更改,从而导致系统状态发生变化。
如果能以数据库 SQL 查询输出的格式查看所有这些信息,将会很有帮助。想象一下,你可以像查询具有相似名称的 SQL 数据库表一样查询 ps
和 rpm
命令的输出。
幸运的是,有一个工具可以做到这一点,甚至更多:Osquery 是一个 开源 的“SQL 驱动的操作系统检测、监控和分析框架”。
许多处理安全性、DevOps、合规性和库存管理(仅举几例)的应用程序都依赖于 Osquery 提供的核心功能。
安装 Osquery
Osquery 适用于 Linux、macOS、Windows 和 FreeBSD。按照其安装说明安装适用于你操作系统的最新版本。(在这些示例中,我将使用 4.7.0 版本。)
安装后,验证其是否正常工作
$ rpm -qa | grep osquery
osquery-4.7.0-1.linux.x86_64
$
$ osqueryi --version
osqueryi version 4.7.0
$
Osquery 组件
Osquery 有两个主要组件
- osqueryi 是一个交互式 SQL 查询控制台。它是一个独立的实用程序,不需要超级用户权限(除非你正在查询需要该级别访问权限的表)。
- osqueryd 就像安装它的主机的监控守护进程。此守护进程可以安排查询以定期执行,从而收集来自基础设施的信息。
你可以在不运行 osqueryd 守护进程的情况下运行 osqueryi 实用程序。另一个实用程序 osqueryctl 控制守护进程的启动、停止和检查状态。
$ rpm -ql osquery-4.8.0-1.linux.x86_64 | grep bin
/usr/bin/osqueryctl
/usr/bin/osqueryd
/usr/bin/osqueryi
$
使用 osqueryi 交互式提示符
你与 Osquery 的交互方式很像使用 SQL 数据库。实际上,osqueryi 是 SQLite shell 的修改版本。运行 osqueryi
命令会使你进入一个交互式 shell,你可以在其中运行特定于 Osquery 的命令,这些命令通常以 .
开头。
$ osqueryi
Using a virtual database. Need help, type '.help'
osquery>
要退出交互式 shell,请运行 .quit
命令以返回到操作系统的 shell
osquery>
osquery> .quit
$
找出有哪些可用的表
如前所述,Osquery 将数据作为 SQL 查询的输出提供。数据库中的信息通常保存在表中。但是,如果你不知道表名,如何查询这些表呢?你可以运行 .tables
命令来列出你可以查询的所有表。如果你是长期的 Linux 用户或系统管理员,你将会熟悉这些表名,因为你一直在使用操作系统命令来获取此信息
osquery> .tables
=> acpi_tables
=> apparmor_events
=> apparmor_profiles
=> apt_sources
<< snip >>
=> arp_cache
=> user_ssh_keys
=> users
=> yara
=> yara_events
=> ycloud_instance_metadata
=> yum_sources
osquery>
检查各个表的模式
现在你知道了表名,你可以查看每个表提供的信息。例如,选择 processes
,因为 ps
命令经常用于获取此信息。运行 .schema
命令,后跟表名,以查看此表中保存的信息。如果你想检查结果,你可以快速运行 ps -ef
或 ps aux
并将输出与表的内容进行比较
osquery> .schema processes
CREATE TABLE processes(`pid` BIGINT, `name` TEXT, `path` TEXT, `cmdline` TEXT, `state` TEXT, `cwd` TEXT, `root` TEXT, `uid` BIGINT, `gid` BIGINT, `euid` BIGINT, `egid` BIGINT, `suid` BIGINT, `sgid` BIGINT, `on_disk` INTEGER, `wired_size` BIGINT, `resident_size` BIGINT, `total_size` BIGINT, `user_time` BIGINT, `system_time` BIGINT, `disk_bytes_read` BIGINT, `disk_bytes_written` BIGINT, `start_time` BIGINT, `parent` BIGINT, `pgroup` BIGINT, `threads` INTEGER, `nice` INTEGER, `is_elevated_token` INTEGER HIDDEN, `elapsed_time` BIGINT HIDDEN, `handle_count` BIGINT HIDDEN, `percent_processor_time` BIGINT HIDDEN, `upid` BIGINT HIDDEN, `uppid` BIGINT HIDDEN, `cpu_type` INTEGER HIDDEN, `cpu_subtype` INTEGER HIDDEN, `phys_footprint` BIGINT HIDDEN, PRIMARY KEY (`pid`)) WITHOUT ROWID;
osquery>
为了强调这一点,请使用以下命令查看 RPM 软件包的模式,并将信息与 rpm -qa
和 rpm -qi
操作系统命令进行比较
osquery>
osquery> .schema rpm_packages
CREATE TABLE rpm_packages(`name` TEXT, `version` TEXT, `release` TEXT, `source` TEXT, `size` BIGINT, `sha1` TEXT, `arch` TEXT, `epoch` INTEGER, `install_time` INTEGER, `vendor` TEXT, `package_group` TEXT, `pid_with_namespace` INTEGER HIDDEN, `mount_namespace_id` TEXT HIDDEN, PRIMARY KEY (`name`, `version`, `release`, `arch`, `epoch`, `pid_with_namespace`)) WITHOUT ROWID;
osquery>
你可以在 Osquery 的表文档中了解更多信息。
使用 PRAGMA 命令
如果模式信息对你来说太晦涩难懂,还有另一种以详细的表格格式打印表信息的方法:PRAGMA
命令。例如,我将使用 PRAGMA
以友好的格式查看 rpm_packages
表的信息
osquery> PRAGMA table_info(rpm_packages);
这种表格信息的一个好处是,你可以专注于你想查询的字段,并查看它提供的信息类型
osquery> PRAGMA table_info(users);
+-----+-------------+--------+---------+------------+----+
| cid | name | type | notnull | dflt_value | pk |
+-----+-------------+--------+---------+------------+----+
| 0 | uid | BIGINT | 1 | | 1 |
| 1 | gid | BIGINT | 0 | | 0 |
| 2 | uid_signed | BIGINT | 0 | | 0 |
| 3 | gid_signed | BIGINT | 0 | | 0 |
| 4 | username | TEXT | 1 | | 2 |
| 5 | description | TEXT | 0 | | 0 |
| 6 | directory | TEXT | 0 | | 0 |
| 7 | shell | TEXT | 0 | | 0 |
| 8 | uuid | TEXT | 1 | | 3 |
+-----+-------------+--------+---------+------------+----+
osquery>
运行你的第一个查询
现在你已经从表、模式和要查询的项目中获得了所有必要的信息,运行你的第一个 SQL 查询以查看信息。下面的查询返回系统中存在的用户以及每个用户的用户 ID、组 ID、主目录和默认 shell。Linux 用户可以通过查看 /etc/passwd
文件的内容并执行一些 grep
、sed
和 awk
技巧来获得此信息。
osquery>
osquery> select uid,gid,directory,shell,uuid FROM users LIMIT 7;
+-----+-----+----------------+----------------+------+
| uid | gid | directory | shell | uuid |
+-----+-----+----------------+----------------+------+
| 0 | 0 | /root | /bin/bash | |
| 1 | 1 | /bin | /sbin/nologin | |
| 2 | 2 | /sbin | /sbin/nologin | |
| 3 | 4 | /var/adm | /sbin/nologin | |
| 4 | 7 | /var/spool/lpd | /sbin/nologin | |
| 5 | 0 | /sbin | /bin/sync | |
| 6 | 0 | /sbin | /sbin/shutdown | |
+-----+-----+----------------+----------------+------+
osquery>
在不进入交互模式的情况下运行查询
如果你想在不进入 osqueryi 交互模式的情况下运行查询怎么办?如果你正在围绕它编写 shell 脚本,这将非常有用。在这种情况下,你可以 echo
SQL 查询并直接从 Bash shell 将其管道传输到 osqueryi
$ echo "select uid,gid,directory,shell,uuid FROM users LIMIT 7;" | osqueryi
+-----+-----+----------------+----------------+------+
| uid | gid | directory | shell | uuid |
+-----+-----+----------------+----------------+------+
| 0 | 0 | /root | /bin/bash | |
| 1 | 1 | /bin | /sbin/nologin | |
| 2 | 2 | /sbin | /sbin/nologin | |
| 3 | 4 | /var/adm | /sbin/nologin | |
| 4 | 7 | /var/spool/lpd | /sbin/nologin | |
| 5 | 0 | /sbin | /bin/sync | |
| 6 | 0 | /sbin | /sbin/shutdown | |
+-----+-----+----------------+----------------+------+
$
了解启动时启动哪些服务
Osquery 还可以返回设置为在启动时启动的所有服务。例如,要查询 startup_items
表并获取启动时运行的前五个服务的名称、状态和路径
osquery> SELECT name,type,status,path FROM startup_items LIMIT 5;
name = README
type = Startup Item
status = enabled
path = /etc/rc.d/init.d/README
name = anamon
type = Startup Item
status = enabled
path = /etc/rc.d/init.d/anamon
name = functions
type = Startup Item
status = enabled
path = /etc/rc.d/init.d/functions
name = osqueryd
type = Startup Item
status = enabled
path = /etc/rc.d/init.d/osqueryd
name = AT-SPI D-Bus Bus
type = Startup Item
status = enabled
path = /usr/libexec/at-spi-bus-launcher --launch-immediately
osquery>
查找二进制文件的 ELF 信息
假设你想了解更多关于 ls
二进制文件的详细信息。通常,你会使用 readelf -h
命令,后跟 ls
命令的路径来执行此操作。你可以使用 Osquery 查询 elf_info
表并获得相同的信息
osquery> SELECT * FROM elf_info WHERE path="/bin/ls";
class = 64
abi = sysv
abi_version = 0
type = dyn
machine = 62
version = 1
entry = 24064
flags = 0
path = /bin/ls
osquery>
现在你已经体验了如何使用 osqueryi 查找你感兴趣的信息。但是,此信息存储在大量表中;我查询的一个系统有 156 个不同的表,这可能会让人感到不知所措
$ echo ".tables" | osqueryi | wc -l
156
$
为了简化操作,你可以从以下表开始获取关于你的 Linux 系统的信息
系统信息表
osquery> select * from system_info;
系统限制信息
osquery> select * from ulimit_info;
各种进程打开的文件
osquery> select * from process_open_files;
系统上的开放端口
osquery> select * from listening_ports;
正在运行的进程信息
osquery> select * from processes;
已安装的软件包信息
osquery> select * from rpm_packages;
用户登录信息
osquery> select * from last;
系统日志信息
osquery> select * from syslog_events;
了解更多
Osquery 是一个强大的工具,它提供了大量主机信息,可用于解决各种用例。你可以通过阅读其文档来了解更多关于 Osquery 的信息。
2 条评论