Post

FleetDM and osquery

Comprehensive guide to FleetDM and osquery. Learn how to deploy FleetDM with Docker, manage osquery agents, and integrate with your cybersecurity monitoring stack for enhanced visibility and defense.

FleetDM and osquery

Hi! Today I’ll walk you through deploying and using FleetDM with osquery to gain deep visibility into endpoints for monitoring and cybersecurity defense. FleetDM is an open-source platform for managing osquery at scale, allowing you to query, collect, and analyze endpoint data across your infrastructure. Let’s dive in!

This post focuses on FleetDM deployment and usage. For a deep dive into osquery itself, check out the official osquery documentation official osquery documentation for background.

What is FleetDM?

FleetDM is an open-source osquery management platform that lets security teams deploy osquery agents, collect telemetry, run live queries, and build policies at scale. It acts as a central management server where endpoints securely send query results.

Key Features of FleetDM

  • Centralized osquery management
  • Live query execution across thousands of endpoints
  • Scheduled queries and policies
  • Flexible deployment (Docker, Kubernetes, bare metal)
  • Integrations with SIEMs, EDRs, and other security tools

Deployment Setup (FleetDM + Docker)

For this demonstration, we’ll deploy FleetDM using Docker Compose.

Prerequisites

  • A Linux server (Ubuntu/Debian recommended)
  • Docker and Docker Compose installed
  • At least 2 GB RAM and 2 CPU cores

Docker Compose File

Here’s a basic docker-compose.yml with MySQL and Redis (replace environment values as needed):

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
services:
  mysql:
    image: mysql:latest
    volumes:
      - mysql:/var/lib/mysql
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=$ROOT_PASSWORD
      - MYSQL_DATABASE=fleet
      - MYSQL_USER=fleet
      - MYSQL_PASSWORD=$USER_PASSWORD
    ports:
      - "3306:3306"
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-p$ROOT_PASSWORD"]
      interval: 10s
      timeout: 5s
      retries: 10

  redis:
    image: redis:latest
    volumes:
      - redis:/data
    ports:
      - "6379:6379"
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
volumes:
  mysql:
  redis:

check with docker ps

1
2
3
4
root@fleet-server:~/fleet# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                    PORTS                                                    NAMES
b37b2fa527b4   mysql:latest   "docker-entrypoint.s…"   15 seconds ago   Up 15 seconds (healthy)   0.0.0.0:3306->3306/tcp, [::]:3306->3306/tcp, 33060/tcp   fleet-mysql-1
2244e5c47ab9   redis:latest   "docker-entrypoint.s…"   15 seconds ago   Up 15 seconds (healthy)   0.0.0.0:6379->6379/tcp, [::]:6379->6379/tcp              fleet-redis-1

Fleet installation

  • Generate TLS certificates :

Use self-signed certificates for testing:

1
2
3
4
5
# generate a private key 
openssl ecparam -name prime256v1 -genkey -noout -out fleet.pem

# generate a self signed cert (CN= your sevrer hostname - for me fleet.b2hu.me)
openssl req -new -x509 -key fleet.pem -out fleet.cert -days 365
  • Creating service Accounts :
    1
    2
    3
    4
    
    sudo groupadd fleet
    sudo useradd -Mrg fleet fleet
    sudo chown fleet:fleet fleet.cert
    sudo chown fleet:fleet fleet.pem
    
  • download latest Fleet Packages
    1
    2
    3
    4
    
    wget https://github.com/fleetdm/fleet/releases/download/fleet-v4.72.1/fleetctl_v4.72.1_linux_amd64.tar.gz
    tar xvf fleetctl_v4.72.1_linux_amd64.tar.gz
    cp fleetctl_v4.72.1_linux_amd64/fleetctl /usr/bin
    # Repeat for fleet binary
    
  • Prepare Database
    1
    2
    3
    4
    5
    6
    
    # this might take a while 
    fleet prepare db \
    --mysql_address=127.0.0.1:3306 \
    --mysql_database=fleet \
    --mysql_username=root \
    --mysql_password=$ROOT_PASSWORD
    
  • Move Certificates & Configure Systemd
    1
    2
    
    mv fleet.cert /etc/ssl
    mv fleet.pem /etc/ssl
    

/etc/systemd/system/fleet.service:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[Unit]
Description=Fleet
After=network.target

[Service]
User=fleet
Group=fleet
LimitNOFILE=8192
ExecStart=/usr/bin/fleet serve \
  --mysql_address=127.0.0.1:3306 \
  --mysql_database=fleet \
  --mysql_username=root \
  --mysql_password=$ROOT_PASSWORD \
  --redis_address=127.0.0.1:6379 \
  --server_cert=/etc/ssl/fleet.cert \
  --server_key=/etc/ssl/fleet.pem \
  --logging_json

[Install]
WantedBy=multi-user.target

start the service :

1
2
systemctl darmon-reload 
systemctl enable --now feet.service

you can check if the service is running using :

1
netstat -nltp | grep 8080

Adding Hosts :

Install Fleet agents on hosts and enroll them. For self-signed certs. (NB: for production use an automated configuration management tool ex. Ansible) ensure the .cert file is present on the agent. Example:

1
2
3
4
5
6
7
8
# Add fleet server IP to hosts file
echo "$IP_FLEET fleet.example.com" | sudo tee -a /etc/hosts

# Enroll agent (get enroll secret for the GUI-> add host)
fleetctl package --type=deb --enable-scripts --fleet-desktop \
  --fleet-url=https://fleet.b2hu.me:8080 \
  --enroll-secret=$ENROLL_SECRET \
  --fleet-certificate=fleet.cert

Install the package on the agent, and you’re ready!

alt text

Query test

One of the simplest but most effective tricks attackers use is modifying the hosts file to override DNS resolution. For example, they might redirect traffic meant for security.example.com to a malicious IP under their control. This kind of change can silently disable security tools or reroute user traffic.

We can check the contents of /etc/hosts (Linux/macOS) or C:\Windows\System32\drivers\etc\hosts (Windows) across all enrolled endpoints with a simple osquery:

1
SELECT * FROM etc_hosts;

Running this as a live query in FleetDM will return all host file entries from your endpoints.

alt text


Thank you for Reading! feel free to contact me if you have a question.

This post is licensed under CC BY 4.0 by the author.