So überwachen Sie die Dateiintegrität unter Linux mit Osquery
Das Grundkonzept bei der Verwendung der osquery-Anwendung ist die "tabellarische Abstraktion" vieler Aspekte des Betriebssystems, wie z.B. Prozesse, Benutzer usw. Die Daten werden in Tabellen gespeichert, die mit SQL-Syntax, direkt über die osqueryi-Shell oder über den osqueryd-Daemon abgefragt werden können.
In diesem Tutorial erfahren Sie, wie Sie die Anwendung installieren, wie Sie grundlegende Abfragen ausführen und wie Sie FIM (File Integrity Monitoring) als Teil Ihrer Linux-Systemadministrationsaufgabe verwenden.
In diesem Tutorial lernen Sie:
- So installieren Sie osquery
- So listen Sie die verfügbaren Tabellen auf
- Ausführen von Abfragen über die osqueryi-Shell
- So verwenden Sie den osqueryd-Daemon zum Überwachen der Dateiintegrität
So überwachen Sie die Dateiintegrität unter Linux mit Osquery
Verwendete Softwareanforderungen und Konventionen
- Grundkenntnisse in SQL-Konzepten
- Root-Berechtigungen zum Ausführen von Verwaltungsaufgaben
Installation
Wir haben grundsätzlich zwei Möglichkeiten, osquery zu installieren: Die erste besteht darin, das entsprechende Paket für unser System von der offiziellen Website herunterzuladen; Die zweite, in der Regel bevorzugte Methode besteht darin, das osquery-Repository zu unseren Distributionssoftware-Quellen hinzuzufügen. Hier gehen wir kurz auf beide Optionen ein.
Es wird empfohlen, die neueste verfügbare Version (4.1.2 zum Zeitpunkt des Schreibens) auszuwählen. Sobald das Paket heruntergeladen ist, können wir es mit unserem Distributionspaket-Manager installieren. Um die Software beispielsweise auf einem Fedora-System zu installieren (vorausgesetzt, das Paket befindet sich in unserem aktuellen Arbeitsverzeichnis), würden wir Folgendes ausführen:
sudo dnf install ./osquery-4.1.2-1.linux.x86_64.rpmVerwenden eines Repositorys
Als Alternative können wir das rpm- oder deb-Repository zu unserer Distribution hinzufügen. Wenn wir eine RPM-basierte Distribution verwenden, können wir die folgenden Befehle ausführen, um die Aufgabe zu erfüllen:
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 osqueryMit den obigen Linux-Befehlen fügen wir den gpg pulic-Schlüssel hinzu, der zum Signieren der Pakete auf unserem System verwendet wird, und fügen dann das Repository hinzu. Schließlich installieren wir das osquery-Paket. Beachten Sie, dass yum in den neueren Versionen von Fedora und CentOS/RHEL nur ein symbolischer Link zu dnf ist, so dass beim Aufruf von ersterem stattdessen letzteres verwendet wird.
Wenn wir eine Debian-basierte Distribution betreiben, können wir stattdessen das deb-Repository zu unseren Softwarequellen hinzufügen, indem wir Folgendes ausführen:
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 osquerySobald wir das Paket installiert haben, können wir einen Blick auf die grundlegende Nutzung der Software werfen.
Grundlegende Verwendung
Osquery ermöglicht es uns, verschiedene Aspekte eines Betriebssystems zu überwachen, das eine "tabellarische Abstraktion" anwendet, indem wir eine SQL-Syntax verwenden, die derjenigen ähnelt, die für SQLite-Datenbanken verwendet wird. Die Abfragen werden auf Tabellen ausgeführt, die verschiedene Betriebssystemaspekte wie Prozesse und Dienste abstrahieren.
Wir können die Abfragen direkt über die interaktive osqueryi-Shell ausführen oder sie über den osqueryd-Daemon planen. Hier ist ein Beispiel für eine Abfrage, um alle verfügbaren Tabellen aufzulisten (die vollständige Liste mit der Tabellenbeschreibung finden Sie auch online
):
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_sourcesWenn wir den Befehl osqueryi ausführen, betreten wir die interaktive Shell; Von dort aus können wir unsere Anfragen und Anweisungen erteilen. Hier ist ein weiteres Beispiel für eine Abfrage, diesmal um alle laufenden Prozesse pid und name aufzulisten. Die Abfrage wird in der Prozesstabelle ausgeführt (die Ausgabe der Abfrage wurde der Einfachheit halber abgeschnitten):
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 |
[...] |
+-------+------------------------------------+
Es ist sogar möglich, Abfragen für verknüpfte Tabellen mit der JOIN-Anweisung durchzuführen, genau wie wir es in relationalen Datenbanken tun. Im folgenden Beispiel führen wir eine Abfrage in der Prozesstabelle durch, die mit der Benutzertabelle über die Spalte uid verbunden ist:
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 |
+-------+-------------------------------+------------------+
Überwachung der Dateiintegrität (FIM)
Bisher haben wir osquery über die interaktive Shell osqueryi verwendet. Um FIM (File Integrity Monitoring) zu verwenden, möchten wir stattdessen den osqueryd-Daemon verwenden. Über die Konfigurationsdatei stellen wir eine Liste der Dateien zur Verfügung, die wir überwachen möchten. Ereignisse, wie z. B. Attributänderungen, die die angegebenen Dateien und Verzeichnisse betreffen, werden in der file_events Tabelle aufgezeichnet. Der Daemon führt nach einem bestimmten Zeitintervall eine Abfrage für diese Tabelle aus und benachrichtigt in den Protokollen, wenn neue Datensätze gefunden werden. Sehen wir uns ein Konfigurationsbeispiel an.
Einrichtung der Konfiguration
Die Hauptkonfigurationsdatei für osquery ist /etc/osquery/osquery.conf. Die Datei existiert standardmäßig nicht, also müssen wir sie erstellen. Die Konfiguration wird im Json-Format bereitgestellt. Angenommen, wir möchten alle Dateien und Verzeichnisse unter /etc überwachen. So würden wir die Anwendung konfigurieren:
{
"options": {
"disable_events": "false"
},
"schedule": {
"file_events": {
"query": "SELECT * FROM file_events;",
"interval": 300
}
},
"file_paths": {
"etc": [
"/etc/%%"
],
},
}
Lassen Sie uns die obige Konfiguration analysieren. Zunächst setzen wir disable_events im Optionsbereich auf "false", um Dateiereignisse zu aktivieren.
Danach haben wir den schedule-Abschnitt erstellt: In diesem Abschnitt können wir verschiedene benannte geplante Abfragen beschreiben und erstellen. In unserem Fall haben wir eine Abfrage erstellt, die alle Spalten aus der file_events Tabelle auswählt, die alle 300 Sekunden (5 Minuten) ausgeführt werden soll.
Nachdem wir die Abfrage geplant hatten, erstellten wir den Abschnitt file_paths, in dem wir die zu überwachenden Dateien angegeben haben. In diesem Abschnitt stellt jeder Schlüssel den Namen einer Gruppe von Dateien dar, die überwacht werden sollen (eine Kategorie im osquery-Jargon). In diesem Fall verweist der Schlüssel »etc« auf eine Liste mit nur einem Eintrag, /etc/%%.
Wofür steht das %-Symbol? Bei der Angabe von Dateipfaden können wir Standard- (*) oder SQL- (%) Platzhalter verwenden. Wenn ein einzelner Platzhalter angegeben wird, werden alle Dateien und Verzeichnisse ausgewählt, die auf der angegebenen Ebene vorhanden sind. Wenn ein doppelter Platzhalter bereitgestellt wird, werden alle Dateien und Ordner rekursiv ausgewählt. Zum Beispiel stimmt der /etc/%-Ausdruck mit allen Dateien und Ordnern eine Ebene unter /etc überein, während /etc/%% rekursiv mit allen Dateien und Ordnern unter /etc übereinstimmt.
Bei Bedarf können wir auch bestimmte Dateien aus dem von uns angegebenen Pfad ausschließen, indem wir den Abschnitt exclude_paths in der Konfigurationsdatei verwenden. In diesem Abschnitt können wir nur auf Kategorien verweisen, die im Abschnitt file_paths definiert sind ("etc" in diesem Fall). Wir stellen die Liste der auszuschließenden Dateien zur Verfügung:
"exclude_paths": {
"etc": [
"/etc/aliases"
]
}Nur als Beispiel: Wir haben die Datei /etc/aliases aus der Liste ausgeschlossen. So sieht unsere endgültige Konfiguration aus:
{
"options": {
"disable_events": "false"
},
"schedule": {
"file_events": {
"query": "SELECT * FROM file_events;",
"interval": 20
}
},
"file_paths": {
"etc": [
"/etc/%%"
]
},
"exclude_paths": {
"etc": [
"/etc/aliases"
]
}
}Starten des Daemons
Mit unserer Konfiguration können wir den osqueryd-Daemon starten:
sudo systemctl start osquerydDamit der Daemon beim Booten automatisch startet, müssen wir Folgendes ausführen:
sudo systemctl enable osqueyd
Sobald der Daemon ausgeführt wird, können wir überprüfen, ob unsere Konfiguration funktioniert. Nur als Beispiel werden wir die Berechtigungen der Datei /etc/fstab ändern, indem wir sie von 644 auf 600 ändern:
sudo chmod 600 /etc/fstabWir können nun überprüfen, ob die Änderung an der Datei aufgezeichnet wurde, indem wir die Datei /var/log/osquery/osqueryd.results.log lesen. Hier ist die letzte Zeile der Datei (verschönert):
{
"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"
}Im obigen Protokoll können wir deutlich sehen, dass eine ATTRIBUTES_MODIFIED Aktion (Zeile 10) auf dem target_path "/etc/fstab" (Zeile 23) aufgetreten ist, der Teil der Kategorie "etc" ist (Zeile 12). Es ist wichtig zu beachten, dass, wenn wir die file_events Tabelle über die osqueryi-Shell abfragen, wir keine Zeilen sehen, da der osqueryd-Daemon und osqueryi nicht kommunizieren.
Schlüsse
In diesem Tutorial haben wir die grundlegenden Konzepte gesehen, die mit der Verwendung der osquery-Anwendung verbunden sind, die verschiedene Betriebssystemkonzepte mit tabellarischen Daten abstrahiert, die wir mit SQL-Syntax abfragen können. Wir haben gesehen, wie man die Anwendung installiert, wie man grundlegende Abfragen mit der osqueryi-Shell durchführt und schließlich, wie man die Dateiüberwachung mit dem osqueryd-Daemon einrichtet. Wir haben nur an der Oberfläche dessen gekratzt, was die Anwendung leisten kann. Wie immer ist es ratsam, einen Blick in die Projektdokumentation zu werfen, um tiefere Kenntnisse zu erhalten.
