Osquery如何在Linux上监控文件的完整性?

导读 如何安装Osquery应用程序是对操作系统的许多方面(进程和用户等)执行的“表格抽象”;如何运行基本查询是数据存储在表中,可以使用SQL语法、直接通过osqueryi外壳或通过osqueryd守护程序来查询以及如何在Linux系统管理工作中使用FIM(文件完整性监控)。

Osquery如何在Linux上监控文件的完整性?
本教程将介绍:
如何安装Osquery
如何列出可用表
如何从osqueryi外壳执行查询
如何使用osqueryd守护程序监控文件完整性
对SQL概念有基本知识
拥有执行管理任务的root权限
软件需求和Linux命令行约定
Osquery如何在Linux上监控文件的完整性?

安装

我们基本上有两种方法来安装Osquery:第一种是从官方网站下载适合我们系统的软件包;第二种(通常是优选方法)是将Osquery存储库添加到发行版软件源。如图:

Osquery如何在Linux上监控文件的完整性?

通过软件包安装

可以从Osquery官方网站(https://osquery.io/downloads/official)下载签名的deb和rpm软件包,或下载更通用的打包文件。我们先选择要安装的版本,然后下载软件包。

建议选择最新的可用版本(截至发稿时4.1.2)。下载软件包后,我们可以使用发行版软件包管理器来安装。比如想在Fedora系统上安装该软件(假设软件包在当前的工作目录中),我们将运行:

 $ sudo dnf install ./osquery-4.1.2-1.linux.x86_64.rpm
使用存储库

我们还可以将rpm或deb存储库添加到发行版中。如果我们使用基于rpm的发行版,可以运行以下命令来完成任务:

 $ curl -L https://pkg.osquery.io/rpm/GPG | sudo tee
/etc/pki/rpm-gpg/RPM-GPG-KEY-osquery
$ sudo yum-config-manager --add-repo https://pkg.osquery.io/rpm/osquery-s3-rpm.repo
$ sudo yum-config-manager --enable osquery-s3-rpm-repo
$ sudo yum install osquery

借助上述Linux命令,我们可以将用来签名软件包的gpg公钥添加到系统中,然后添加存储库。最后,我们安装Osquery软件包。注意,在近期版本的Fedora和CentOS/RHEL中,yum只是dnf的符号链接,所以我们调用前者时,使用的却是后者。

如果你运行基于Debian的发行版,可以将deb存储库添加到软件源中,只要运行:

$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys
1484120AC4E9F8A1A577AEEE97A80C63C9D8B80B
$ sudo add-apt-repository 'deb [arch=amd64] https://pkg.osquery.io/deb deb main'
$ sudo apt-get update
$ sudo apt-get install osquery

一旦软件包安装完毕,我们可以看一下软件的基本用法。

基本用法

Osquery让我们可以监控采用“表格抽象”的操作系统的不同方面,使用类似sqlite数据库上所用语法的SQL语法。针对表执行查询,表对操作系统的不同方面(比如进程和服务)进行抽象处理。

我们可以直接使用osqueryi交互式外壳来运行查询,也可以通过osqueryd守护程序来安排查询。下面这个例子显示了列出所有可用表的查询(还可以在此处https://osquery.io/schema/4.1.2#processes看到附有表描述的完整列表):

$ osqueryi
osquery> .tables
=> acpi_tables
=> apt_sources
=> arp_cache
=> atom_packages
=> augeas
=> authorized_keys
=> block_devices
=> carbon_black_info
=> carves
=> chrome_extensions
=> cpu_time
=> cpuid
=> crontab
=> curl
=> curl_certificate
=> deb_packages
=> device_file
=> device_hash
=> device_partitions
=> disk_encryption
=> dns_resolvers
=> docker_container_labels
=> docker_container_mounts
=> docker_container_networks
=> docker_container_ports
=> docker_container_processes
=> docker_container_stats
=> docker_containers
=> docker_image_labels
=> docker_images
=> docker_info
=> docker_network_labels
=> docker_networks
=> docker_version
=> docker_volume_labels
=> docker_volumes
=> ec2_instance_metadata
=> ec2_instance_tags
=> elf_dynamic
=> elf_info
=> elf_sections
=> elf_segments
=> elf_symbols
=> etc_hosts
=> etc_protocols
=> etc_services
=> file
=> file_events
=> firefox_addons
=> groups
=> hardware_events
=> hash
=> intel_me_info
=> interface_addresses
=> interface_details
=> interface_ipv6
=> iptables
=> kernel_info
=> kernel_integrity
=> kernel_modules
=> known_hosts
=> last
=> listening_ports
=> lldp_neighbors
=> load_average
=> logged_in_users
=> magic
=> md_devices
=> md_drives
=> md_personalities
=> memory_array_mapped_addresses
=> memory_arrays
=> memory_device_mapped_addresses
=> memory_devices
=> memory_error_info
=> memory_info
=> memory_map
=> mounts
=> msr
=> npm_packages
=> oem_strings
=> opera_extensions
=> os_version
=> osquery_events
=> osquery_extensions
=> osquery_flags
=> osquery_info
=> osquery_packs
=> osquery_registry
=> osquery_schedule
=> pci_devices
=> platform_info
=> portage_keywords
=> portage_packages
=> portage_use
=> process_envs
=> process_events
=> process_file_events
=> process_memory_map
=> process_namespaces
=> process_open_files
=> process_open_sockets
=> processes
=> prometheus_metrics
=> python_packages
=> routes
=> rpm_package_files
=> rpm_packages
=> selinux_events
=> shadow
=> shared_memory
=> shell_history
=> smart_drive_info
=> smbios_tables
=> socket_events
=> ssh_configs
=> sudoers
=> suid_bin
=> syslog_events
=> system_controls
=> system_info
=> time
=> ulimit_info
=> uptime
=> usb_devices
=> user_events
=> user_groups
=> user_ssh_keys
=> users
=> yara
=> yara_events
=> yum_sources

运行osqueryi命令,我们进入交互式外壳;我们可以从该外壳执行查询或指令。这是查询的另一个例子,这回列出所有运行中进程的pid和name。对process表执行查询(为便于阅读,查询的输出已截短):

 osquery> SELECT pid, name FROM processes;

+——-+————————————+
| pid | name |
+——-+————————————+
| 1 | systemd |
| 10 | rcu_sched |
| 10333 | kworker/u16:5-events_unbound |
| 10336 | kworker/2:0-events |
| 11 | migration/0 |
| 11002 | kworker/u16:1-kcryptd/253:0 |
| 11165 | kworker/1:1-events |
| 11200 | kworker/1:3-events |
| 11227 | bash |
| 11368 | osqueryi |
| 11381 | kworker/0:0-events |
| 11395 | Web Content |
| 11437 | kworker/0:2-events |
| 11461 | kworker/3:2-events_power_efficient |
| 11508 | kworker/2:2 |
| 11509 | kworker/0:1-events |
| 11510 | kworker/u16:2-kcryptd/253:0 |
| 11530 | bash |
[…] |
+——-+————————————+
甚至可以使用JOIN语句对连接表执行查询,就像我们在关系数据库中操作那样。在下面例子中,我们对processes表执行查询,通过uid列与users表进行连接:

 osquery> SELECT processes.pid, processes.name, users.username FROM processes JOIN
users ON processes.uid = users.uid;

+——-+——————————-+——————+
| pid | name | username |
+——-+——————————-+——————+
| 1 | systemd | root |
| 10 | rcu_sched | root |
| 11 | migration/0 | root |
| 11227 | bash | egdoc |
| 11368 | osqueryi | egdoc |
| 13 | cpuhp/0 | root |
| 14 | cpuhp/1 | root |
| 143 | kintegrityd | root |
| 144 | kblockd | root |
| 145 | blkcg_punt_bio | root |
| 146 | tpm_dev_wq | root |
| 147 | ata_sff | root |
[…]
| 9130 | Web Content | egdoc |
| 9298 | Web Content | egdoc |
| 9463 | gvfsd-metadata | egdoc |
| 9497 | gvfsd-network | egdoc |
| 9518 | gvfsd-dnssd | egdoc |
+——-+——————————-+——————+

文件完整性监控(FIM)

前面我们使用交互式外壳osqueryi来使用Osquery。想使用FIM(文件完整性监控),我们改用osqueryd守护程序。通过配置文件,我们列出了想要监控的文件。file_events 表中记录了涉及指定文件和目录的事件,比如属性变化。守护程序在指定的时间间隔后对该表运行查询,并在日志中通知何时发现新记录。不妨看看配置示例。

配置结构

Osquery的主配置文件是/etc/osquery/osquery.conf。该文件默认情况下不存在,于是我们要创建它。配置以JSON格式来提供。假设我们想要监控/etc下的所有文件和目录;下面显示了我们如何配置该应用程序:

{
"options": {
"disable_events": "false"
},
"schedule": {
"file_events": {
"query": "SELECT * FROM file_events;",
"interval": 300
}
},
"file_paths": {
"etc": [
"/etc/%%"
],
},
}

不妨分析上述配置。首先在options部分,我们将disable_events设为“false”,以便启用文件事件。

之后我们创建schedule部分:在该部分,我们可以描述和创建各种命名的调度查询。我们在本文中创建了一个查询,以便从file_events表选择所有列,这意味着每300秒(5分钟)执行一次。

安排查询后,我们创建了file_paths部分,在该部分指定要监控的文件。在该部分,每个键代表要监控一组文件的名称(Osquery术语中的类别)。这里“etc”键引用仅含有一个条目/etc/%%的列表。

%符号代表什么?指定文件路径时,我们可以使用标准通配符(*)或SQL通配符(%)。如果提供单通配符,它​将选择位于指定级别的所有文件和目录。如果提供双通配符,它​​将递归选择所有文件和文件夹。比如说,/etc/%表达式匹配/etc下面一级的所有文件和文件夹,而/etc/%%递归匹配/etc下的所有文件和文件夹。

如果需要,我们还可以使用配置文件中的exclude_paths部分,从提供的路径中排除特定文件。在该部分,我们只能引用file_paths部分中定义的类别(本例中是“etc”)。我们提供了要排除的文件列表:

"exclude_paths": {
"etc": [
"/etc/aliases"
]
}
仅作为例子,我们从列表中排除了/etc/aliases文件。下面是最终配置的样子:

{
"options": {
"disable_events": "false"
},
"schedule": {
"file_events": {
"query": "SELECT * FROM file_events;",
"interval": 20
}
},
"file_paths": {
"etc": [
"/etc/%%"
]
},
"exclude_paths": {
"etc": [
"/etc/aliases"
]
}
}
开启守护程序

配置已到位,我们可以开启osqueryd守护程序:

 $ sudo systemctl start osqueryd

为了使守护程序在系统启动时自动开启,我们要运行:

 $ sudo systemctl enable osqueyd

一旦守护程序运行,我们可以核实配置有效。仅举个例子,我们将修改/etc/fstab文件的许可权,将它们从644改为600:

 $ sudo chmod 600 /etc/fstab

现在我们可以核实文件更改以记录下来,只需阅读/var/log/osquery/osqueryd.results.log文件。下面是该文件的最后一行:

{
"name":"file_events",
"hostIdentifier":"fingolfin",
"calendarTime":"Mon Dec 30 19:57:31 2019 UTC",
"unixTime":1577735851,
"epoch":0,
"counter":0,
"logNumericsAsNumbers":false,
"columns": {
"action":"ATTRIBUTES_MODIFIED",
"atime":"1577735683",
"category":"etc",
"ctime":"1577735841",
"gid":"0",
"hashed":"0",
"inode":"262147",
"md5":"",
"mode":"0600",
"mtime":"1577371335",
"sha1":"",
"sha256":"",
"size":"742",
"target_path":"/etc/fstab",
"time":"1577735841",
"transaction_id":"0",
"uid":"0"
},
"action":"added"
}
结论

在上述日志中,我们可以清楚地看到在target_path “/etc/fstab”(第23行)上进行了ATTRIBUTES_MODIFIED操作(第10行),/etc/fstab是“etc”类别(第12行)的一部分。有必要注意这点:如果我们从osqueryi外壳查询file_events表,由于osqueryd守护程序和osqueryi无法联系,因此看不到任何行。

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/122477.html

(0)
上一篇 2021年8月28日
下一篇 2021年8月28日

相关推荐

发表回复

登录后才能评论