
This article provides a guide describing how to install Osquery on Ubuntu VPS.
What is Osquery?
Osquery is a lightweight, SQL-powered agent that lets you query your Linux system like a database. Need to list running processes, open ports, installed packages, or detect file changes? You can do it all with plain SELECT
statements and automate them on a schedule.
Below is a production-ready, step-by-step guide tailored for Ubuntu VPS servers.
What You’ll Need
- An Ubuntu VPS (Ubuntu 20.04/Ubuntu 22.04/Ubuntu 24.04 LTS) with sudo/root access
- Internet connectivity (to fetch packages)
- ~100MB disk space for binaries + logs (more if you log verbosely)
How to Install Osquery on Ubuntu VPS
To install Osquery on Ubuntu VPS, follow the steps below:
-
Update the system & install helpers
sudo apt update sudo apt -y install curl gpg ca-certificates lsb-release
-
Add the official Osquery APT repository
Why the repo? Ubuntu’s built-in package can lag behind. The official repo ships current, security-patched builds for amd64/arm64.
Create a keyring and source list:
# Import GPG key into a dedicated keyring (no deprecated apt-key) curl -fsSL https://pkg.osquery.io/deb/pubkey.gpg \ | sudo gpg --dearmor -o /usr/share/keyrings/osquery-archive-keyring.gpg # Add the repository (auto-detect architecture) ARCH=$(dpkg --print-architecture) echo "deb [arch=${ARCH} signed-by=/usr/share/keyrings/osquery-archive-keyring.gpg] https://pkg.osquery.io/deb deb main" \ | sudo tee /etc/apt/sources.list.d/osquery.list sudo apt update
-
Install Osquery
sudo apt -y install osquery
Verify:
osqueryi --version # osqueryi version x.y.z
-
Know the file layout (Ubuntu/Debian packages)
- Binaries:
- Interactive shell:
/usr/bin/osqueryi
- Daemon (service):
/usr/bin/osqueryd
- Config directory:
/etc/osquery/
- Default config file:
/etc/osquery/osquery.conf
(you create it) - Optional flags file:
/etc/osquery/osquery.flags
- Packs (ready-made queries):
/usr/share/osquery/packs/
- State/DB:
/var/osquery/
- Logs:
/var/log/osquery/
- Systemd unit:
osqueryd.service
-
Create a minimal, production-safe config
Create
/etc/osquery/osquery.conf
:sudo tee /etc/osquery/osquery.conf >/dev/null <<'JSON' { "options": { "host_identifier": "hostname", "config_refresh": 300, "schedule_splay_percent": 10, "pidfile": "/var/osquery/osquery.pid", "database_path": "/var/osquery/osquery.db", "logger_plugin": "filesystem", "logger_path": "/var/log/osquery", "utc": true, "disable_events": false, "events_expiry": 3600 }, "schedule": { "system_info_hourly": { "query": "SELECT hostname, cpu_brand, physical_memory FROM system_info;", "interval": 3600 }, "os_version_hourly": { "query": "SELECT name, version, major, minor, patch FROM os_version;", "interval": 3600 }, "listening_ports_5m": { "query": "SELECT pid, port, address, protocol, state FROM listening_ports;", "interval": 300 }, "installed_packages_6h": { "query": "SELECT name, version, revision, arch FROM deb_packages;", "interval": 21600 }, "fim_events": { "query": "SELECT * FROM file_events;", "interval": 60, "removed": false } }, "file_paths": { "etc": ["/etc/%%"], "binaries": ["/bin/%%", "/sbin/%%", "/usr/bin/%%", "/usr/sbin/%%"], "logs": ["/var/log/%%"], "web": ["/var/www/%%"] }, "exclude_paths": { "logs": ["/var/log/journal/%%"] }, "decorators": { "load": [ "SELECT uuid AS host_uuid FROM system_info;", "SELECT hostname AS host FROM system_info;" ] }, "packs": { "osquery-monitoring": "/usr/share/osquery/packs/osquery-monitoring.conf" } } JSON
What this does
- Writes logs to
/var/log/osquery/
in UTC - Splays (randomizes) schedules to avoid thundering herd on fleets
- Enables eventing and FIM (file event) collection
- Schedules a few safe, useful queries
- Loads the built-in “osquery-monitoring” pack for self-health checks
Note:
file_events
needsdisable_events=false
(already set). It tracks changes under thefile_paths
categories you defined. - Writes logs to
-
(Optional) Flags file for early-boot options
Some settings are better as flags. Create
/etc/osquery/osquery.flags
:sudo tee /etc/osquery/osquery.flags >/dev/null <<'FLAGS' --config_path=/etc/osquery/osquery.conf --logger_path=/var/log/osquery --pidfile=/var/osquery/osquery.pid --database_path=/var/osquery/osquery.db FLAGS
If you later integrate with a central manager (Fleet/Kolide), you’ll add TLS flags here (see the optional section below).
-
Enable & start the service
sudo systemctl daemon-reload sudo systemctl enable --now osqueryd sudo systemctl status osqueryd --no-pager
Check logs:
sudo ls -l /var/log/osquery/ sudo tail -n 100 /var/log/osquery/osqueryd.results.log sudo journalctl -u osqueryd -n 50 --no-pager
-
Try interactive queries
Use the shell for ad-hoc questions:
# Open the interactive shell sudo osqueryi # Examples inside osqueryi: SELECT * FROM system_info; SELECT name, version FROM deb_packages WHERE name LIKE 'openssh%'; SELECT pid, name, path FROM processes WHERE name='sshd'; SELECT address, port, protocol, pid FROM listening_ports ORDER BY port; .quit
For machine-readable output:
sudo osqueryi --json "SELECT hostname, cpu_brand, physical_memory FROM system_info;"
-
File Integrity Monitoring (FIM) check
With the config above, Osquery watches common paths. Generate a test event:
sudo touch /etc/test-osquery-fim.txt sudo rm /etc/test-osquery-fim.txt sudo tail -n 200 /var/log/osquery/osqueryd.results.log | grep file_events | tail -n 5
You should see
file_events
entries for create/delete.If you’re also running
auditd
and decide to use Osquery’s audit framework deeply, avoid conflicting configurations. For typical FIM viafile_events
, the default Osquery setup is fine. -
(Optional) Log to syslog/journald
If you prefer central log shipping via rsyslog/journal collectors, set:
sudo sed -n '1,200p' /etc/osquery/osquery.conf | sudo tee /tmp/osq.tmp >/dev/null sudo jq '.options.logger_plugin="filesystem,syslog"' /tmp/osq.tmp | sudo tee /etc/osquery/osquery.conf >/dev/null sudo systemctl restart osqueryd
Check syslog:
sudo tail -n 100 /var/log/syslog | grep osquery
-
(Optional) Enroll with Fleet (central management)
If you use [FleetDM] or a similar manager, add TLS flags. Replace values with your server details:
# Enroll secret (place provided secret here) echo "YOUR-ENROLL-SECRET" | sudo tee /etc/osquery/enroll_secret >/dev/null sudo chmod 600 /etc/osquery/enroll_secret # Server CA (public cert for your Fleet server) # Save your PEM to /etc/osquery/fleet.pem # sudo nano /etc/osquery/fleet.pem # Add TLS flags sudo tee -a /etc/osquery/osquery.flags >/dev/null <<'FLAGS' --enroll_secret_path=/etc/osquery/enroll_secret --tls_hostname=fleet.example.com:443 --tls_server_certs=/etc/osquery/fleet.pem # Use TLS for configuration and logging (keep filesystem too for local copies) --config_plugin=tls --logger_plugin=tls,filesystem --config_tls_endpoint=/api/osquery/config --enroll_tls_endpoint=/api/osquery/enroll --logger_tls_endpoint=/api/osquery/log --disable_distributed=false --distributed_tls_read_endpoint=/api/osquery/distributed/read --distributed_tls_write_endpoint=/api/osquery/distributed/write FLAGS sudo systemctl restart osqueryd
-
Hardening & performance tips
- Least privilege: Osquery can run as non-root, but many tables require elevated permissions. If you run it as root (default), tightly control who can edit
/etc/osquery/
and read/var/log/osquery/
. - Splay your schedules: Already enabled to reduce spikes (
schedule_splay_percent
). - Tune intervals: Increase
interval
for heavy queries (e.g.,deb_packages
) to reduce I/O. - Log rotation: Ensure your log manager rotates
/var/log/osquery/*
to prevent disk growth. - Packs: Explore
/usr/share/osquery/packs/
(e.g., incident-response, it-compliance) and enable only what you need.
- Least privilege: Osquery can run as non-root, but many tables require elevated permissions. If you run it as root (default), tightly control who can edit
-
Troubleshooting
- Validate config syntax:
sudo osqueryi --config_path=/etc/osquery/osquery.conf --enable_monitor=true --verbose
- Service/logs:
sudo systemctl status osqueryd --no-pager sudo journalctl -u osqueryd -e --no-pager sudo tail -n 200 /var/log/osquery/osqueryd.INFO
- Common issues:
- No
file_events
data: Make sure"disable_events": false
is set and you scheduled a query againstfile_events
. - Repo fetch errors: Re-download the GPG key and confirm
/etc/apt/sources.list.d/osquery.list
matches your architecture. - High CPU from heavy queries: Increase intervals, remove unneeded packs, or narrow queries.
-
Upgrades & removal
- Upgrade with normal apt flows:
sudo apt update && sudo apt -y upgrade
- Remove (keeping config/data):
sudo systemctl disable --now osqueryd sudo apt -y remove osquery
- Purge (removes config):
sudo apt -y purge osquery sudo rm -rf /var/osquery /var/log/osquery /etc/osquery
Quick-install one-liner (optional)
sudo bash -c ' set -e apt update && apt -y install curl gpg ca-certificates curl -fsSL https://pkg.osquery.io/deb/pubkey.gpg | gpg --dearmor -o /usr/share/keyrings/osquery-archive-keyring.gpg ARCH=$(dpkg --print-architecture) echo "deb [arch=${ARCH} signed-by=/usr/share/keyrings/osquery-archive-keyring.gpg] https://pkg.osquery.io/deb deb main" > /etc/apt/sources.list.d/osquery.list apt update && apt -y install osquery systemctl enable --now osqueryd osqueryi --version '
You’re done!
You now know how to install Osquery on Ubuntu VPS. You now have Osquery installed, scheduled, logging, and ready for deeper monitoring.