The purpose of this blog post is to provide multiple methods on how to install/setup FleetDM, how to deploy Osquery, and demonstrate how to use features of FleetDM + FleetCTL. This blog post generated an Ansible playbook, Docker-composes for Swarm and non-swarm, Vagrant to create a VM, and manual instructions for installing FleetDM on Ubuntu 20.04. Additionally, there are Ansible playbooks for deploying the Osquery agent on Windows and Ubuntu with manual instructions as well. Lastly, I will end by demonstrating how to use the FleetDM WebGUI and FleetCTL tool to manage FleetDM and interact with your Osquery agents.
Goals
- Setup FleetDM with Docker
- Setup FleetDM with Ansible
- Setup FleetDM with Vagrant
- Setup FleetDM with manual instructions
- Install/Setup Osquery on Windows 10
- Install/Setup Osquery on Ubuntu 20.04
- Install/Setup Osquery on macOS Big
- Create a live query on Fleet with UI and FleetCTL CLI tool
- Create a saved query on Fleet with UI and FleetCTL CLI tool
- Create a query pack on Fleet with UI and FleetCTL CLI tool
Update log
- July 15th 2021 – Updated Docker from Fleet v3.7.1 to v4.0.1
- August 29th 2021 – Updated Docker from Fleet v4.0.1 to v4.2.3
- August 29th 2021 – Added instructions to install/setup Osquery on macOS Big Sur
- September 24th 2021 – Added Vagrant to spin up Fleet on Ubuntu 20.04 and updated Ansible playbook to use TARs
- September 24th 2021 – Updated Docker and Ansible from Fleet v4.2.3 to v4.3.1
- December 18th 2021 – Updated Docker and Ansible from Fleet v4.3.1 to v4.7.0
- March 20th 2022 – Updated Docker and Ansible from Fleet v4.7.0 to v4.11.0
Background
What is Fleet FleetDM?
Fleet is the most widely used open source osquery manager. Deploying osquery with Fleet enables programmable live queries, streaming logs, and effective management of osquery across 50,000+ servers, containers, and laptops. It’s especially useful for talking to multiple devices at the same time.
Important note: Common name match for Osquery cert check
This blog post will assume you have the knowledge and capability to create a DNS A record that points to where FleetDM is being hosted. When the Osquery agent connects to FleetDM it will verify that the common name in the public certificate being served by FleetDM matches the common name specified in the
osquery.flags
file: --tls_hostname=<FleetDM FQDN>
. Below I have included a screen to demonstrate what I mean. Not only does the common name have to match but the public certificate being served by FleetDM and the local certificate saved on the endpoint must match as well. If this criterion is not met then Osquery will generate the following error: Request error: certificate verify failed
.
Install FleetDM with Docker-compose v2.x
WARNING
The Docker-compose v2.x setup is for development use ONLY. The setup contains hard-coded credentials in configs and environment variables. For a more secure Docker deployment please skip to the next section to use Docker Swarm which implements Docker secrets.
WARNING
- openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout conf/tls/fleet.key -out conf/tls/fleet.crt
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout conf/tls/fleet.key -out conf/tls/fleet.crt
- Generate TLS private key and public certificate
- git clone https://github.com/CptOfEvilMinions/FleetDM-Automation
git clone https://github.com/CptOfEvilMinions/FleetDM-Automation
- cd FleetDM-Automation
cd FleetDM-Automation
- vim .env
vim .env
and set- FLEETDM_VERSION
FLEETDM_VERSION
– Version of FleetDM to use – Only change if you want to use a different version - FLEETDM_MYSQL_USER
FLEETDM_MYSQL_USER
– Name of the MySQL user for FleetDM - FLEETDM_MYSQL_PASSWORD
FLEETDM_MYSQL_PASSWORD
– Password for the MySQL user for FleetDM - FLEETDM_MYSQL_DATABASE
FLEETDM_MYSQL_DATABASE
– Name of the MySQL database for FleetDM - FLEETDM_MYSQL_PASSWORD
FLEETDM_MYSQL_PASSWORD
– Password for the MySQL root user - FLEETDM_JWT_KEY
FLEETDM_JWT_KEY
– The JWT token- Generate a random key with openssl rand -base64 32
openssl rand -base64 32
- Generate a random key with
- docker-compose build
docker-compose build
- docker-compose run --rm fleet fleet prepare db --config /etc/fleet/fleet.yml
docker-compose run --rm fleet fleet prepare db --config /etc/fleet/fleet.yml
- docker-compose up -d
docker-compose up -d
Install FleetDM with Docker-compose v3.x (Swarm)
Unfortunately, Docker-compose version 3.X (DockerSwarm) doesn’t interact with the
.env
file the same as v2.X. The trade-off is a more secure deployment of the FleetDM stack because secrets are not hardcoded in configs or stored in environment variables. Below we create Docker secrets that will contain these sensitive secrets to be used by the Docker containers.
Furthermore, any changes such as changing the container version or the MySQL database name in the
.env
file will have no effect. These settings need to be changed in the docker-compose-swarn.yml
file and the same changes may need to be carried over to the FleetDM config located: conf/docker/fleetdm/fleetdm-swarm.yml
. Lastly, another benefit of Docker Swarm is we can have multiple instances (replicas) of FleetDM running for high-availability.
- git clone https://github.com/CptOfEvilMinions/FleetDM-Automation
git clone https://github.com/CptOfEvilMinions/FleetDM-Automation
- cd FleetDM-Automation
cd FleetDM-Automation
- openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout conf/tls/fleet.key -out conf/tls/fleet.crt
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout conf/tls/fleet.key -out conf/tls/fleet.crt
- Generate TLS private key and public certificate
- openssl rand -base64 32 | tr -cd '[:alnum:]' | docker secret create fleetdm-jwt-key -
openssl rand -base64 32 | tr -cd '[:alnum:]' | docker secret create fleetdm-jwt-key -
- Generate a JWT key and create a secret named fleetdm-jwt-key
fleetdm-jwt-key
- Generate a JWT key and create a secret named
- openssl rand -base64 32 | tr -cd '[:alnum:]' | docker secret create mysql-root-password -
openssl rand -base64 32 | tr -cd '[:alnum:]' | docker secret create mysql-root-password -
- Generate random password containing only alphanumeric characters for the MySQL root password
- openssl rand -base64 32 | tr -cd '[:alnum:]' | docker secret create mysql-fleetdm-password -
openssl rand -base64 32 | tr -cd '[:alnum:]' | docker secret create mysql-fleetdm-password -
- Generate random password containing only alphanumeric characters for the MySQL FleetDM user password
- docker stack deploy -c docker-compose-swarm.yml fleetdm
docker stack deploy -c docker-compose-swarm.yml fleetdm
- docker service logs -f fleetdm_fleet
docker service logs -f fleetdm_fleet
- The first time these containers are started they will error out until the MySQL database initializes
- The first time these containers are started they will error out until the MySQL database initializes
Install FleetDM on Ubuntu 20.04 with Ansible
Init playbook
- git clone https://github.com/CptOfEvilMinions/FleetDM-Automation
git clone https://github.com/CptOfEvilMinions/FleetDM-Automation
- cd FleetDM-Automation
cd FleetDM-Automation
- openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout conf/tls/fleet.key -out conf/tls/fleet.crt
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout conf/tls/fleet.key -out conf/tls/fleet.crt
- Generate TLS private key and public certificate
- pip3 install ansible
pip3 install ansible
- vim hosts.ini
vim hosts.ini
and add IP address under[fleetdm][fleetdm]
- vim all.yml
vim all.yml
and set:- base_domain
base_domain
– The domain for your network and the base domain of the FQDN - timezone
timezone
– OPTIONAL – Change the default timezone of UTC +0
-
openssl rand -base64 32
openssl rand -base64 32
- Copy the output from the command
- vim fleetdm.yml
vim fleetdm.yml
and set:-
fleetdm_jwt
fleetdm_jwt
– Set this to the random string generated by the OpenSSL command -
mysql_root_password
mysql_root_password
– Set the root password for MySQL -
mysql_fleetdm_password
mysql_fleetdm_password
– Set the password for FleetDM MySQL user
-
Run playbook
- ansible-playbook -i hosts.ini deploy_fleetdm.yml -u <user> -K
ansible-playbook -i hosts.ini deploy_fleetdm.yml -u <user> -K
- Enter the password for the user
- Enter the password for the user
Install FleetDM on Ubuntu 20.04 with Vagrant
The Vagrantfile provided relies on the Ansible playbook above to setup Fleet on the Ubuntu VM.
- git clone https://github.com/CptOfEvilMinions/FleetDM-Automation
git clone https://github.com/CptOfEvilMinions/FleetDM-Automation
- cd FleetDM-Automation
cd FleetDM-Automation
- Please follow the instructions outlined in the Ansible section above specifically the “Init playbook” section
- vagrant up
vagrant up
- vagrant ssh
vagrant ssh
Manual install of FleetDM 3.6.0 on Ubuntu 20.04
Init host
- ssh into VM
- sudo su
sudo su
- timedatectl set-timezone Etc/UTC
timedatectl set-timezone Etc/UTC
- Set the system timezone to UTC +0
- apt update -y && apt upgrade -y && apt install net-tools git wget unzip -y && reboot
apt update -y && apt upgrade -y && apt install net-tools git wget unzip -y && reboot
- Update system and reboot
Install/Setup Redis 5.5.0
- apt install redis-server=5:5.0.7-2
apt install redis-server=5:5.0.7-2
- systemctl enable redis-server
systemctl enable redis-server
- systemctl start redis-server
systemctl start redis-server
- netstat -tnlp | grep redis
netstat -tnlp | grep redis
Install/Setup MySQL 8.0
- apt install mysql-server-8.0 python3-mysqldb python3-pip -y
apt install mysql-server-8.0 python3-mysqldb python3-pip -y
- systemctl start mysql
systemctl start mysql
- netstat -tnlp | grep mysqld
netstat -tnlp | grep mysqld
- Check that MySQL is listening on port 3306
- secure_installation
secure_installation
- Enter “y”
- Enter “2” for a strong password
- Enter a strong password
- Enter “y” to continue with the password provided
- Enter “y” to remove anonymous user
- Enter “y” to disallow root login remotely
- Enter “y” to remove the test database
- Enter “y” to reload privileged tables
- systemctl enable mysql
systemctl enable mysql
- Create another secure password
- mysql -u root -p
mysql -u root -p
- Enter the password from above
- CREATE DATABASE fleetdm;
CREATE DATABASE fleetdm;
- Create FleetDM database
- CREATE USER 'fleetdm'@'localhost' IDENTIFIED BY '<Password>';
CREATE USER 'fleetdm'@'localhost' IDENTIFIED BY '<Password>';
- Create FleetDM MySQL user
- GRANT ALL PRIVILEGES ON fleetdm.* TO 'fleetdm'@'localhost';
GRANT ALL PRIVILEGES ON fleetdm.* TO 'fleetdm'@'localhost';
- Provide FleetDM the permissions to interact with the FleetDM database
- exit
exit
- wget https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/ansible/mysql/fleetdm.cnf -O /etc/mysql/conf.d/fleetdm.cnf
wget https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/ansible/mysql/fleetdm.cnf -O /etc/mysql/conf.d/fleetdm.cnf
- Download MySQL settings config
- systemctl restart mysql
systemctl restart mysql
Install/Setup FleetDM 3.6.0
- adduser fleetdm --system --no-create-home
adduser fleetdm --system --no-create-home
- Create a user
- groupadd fleetdm
groupadd fleetdm
- Create a group
- usermod -aG fleetdm fleetdm
usermod -aG fleetdm fleetdm
- Add the fleetdm
fleetdm
user as a member of thefleetdmfleetdm
group
- Add the
- cd /tmp/ && wget https://github.com/fleetdm/fleet/releases/download/3.6.0/fleet.zip
cd /tmp/ && wget https://github.com/fleetdm/fleet/releases/download/3.6.0/fleet.zip
- unzip fleet.zip
unzip fleet.zip
- mv linux/fleet /usr/local/bin/fleet
mv linux/fleet /usr/local/bin/fleet
- Move FleetDM binary to the local bin directory
- mkdir /etc/fleetdm
mkdir /etc/fleetdm
- chown root:root -R /etc/fleetdm
chown root:root -R /etc/fleetdm
- Create a config directory for FleetDM
- mkdir /var/log/osquery
mkdir /var/log/osquery
- chown fleetdm:fleetdm -R /var/log/osquery
chown fleetdm:fleetdm -R /var/log/osquery
- Create a directory to record the results of Osquery endpoints
- openssl req -newkey rsa:2048 -nodes -keyout /etc/ssl/private/fleetdm.key -x509 -days 365 -out /etc/ssl/certs/fleetdm.crt
openssl req -newkey rsa:2048 -nodes -keyout /etc/ssl/private/fleetdm.key -x509 -days 365 -out /etc/ssl/certs/fleetdm.crt
- Generate self-signed private key and public certificate for FleetDM
- wget https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/ansible/fleetdm/fleetdm.yml -O /etc/fleetdm/fleetdm.yml
wget https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/ansible/fleetdm/fleetdm.yml -O /etc/fleetdm/fleetdm.yml
- Download FleetDM config
- chown root:fleetdm /etc/fleetdm/fleetdm.yml
chown root:fleetdm /etc/fleetdm/fleetdm.yml
- chmod 640 /etc/fleetdm/fleetdm.yml
chmod 640 /etc/fleetdm/fleetdm.yml
- sed -i "s/{{ fleetdm_jwt }}/$(openssl rand -base64 32 | tr -cd '[:alnum:]')/g" /etc/fleetdm/fleetdm.yml
sed -i "s/{{ fleetdm_jwt }}/$(openssl rand -base64 32 | tr -cd '[:alnum:]')/g" /etc/fleetdm/fleetdm.yml
- Generate a random JWT key and set the value in the FleetDM config
- sed -i "s/{{ fleetdm_db_name }}/<FleetDM database name>/g" /etc/fleetdm/fleetdm.yml
sed -i "s/{{ fleetdm_db_name }}/<FleetDM database name>/g" /etc/fleetdm/fleetdm.yml
- Set the database name
- sed -i "s/{{ fleetdm_username }}/<FleetDM username>/g" /etc/fleetdm/fleetdm.yml
sed -i "s/{{ fleetdm_username }}/<FleetDM username>/g" /etc/fleetdm/fleetdm.yml
- Set the MySQL username
- sed -i "s/{{ fleetdm_password }}/<FleetDM password>/g" /etc/fleetdm/fleetdm.yml
sed -i "s/{{ fleetdm_password }}/<FleetDM password>/g" /etc/fleetdm/fleetdm.yml
- Set the MySQL password
- Set the MySQL password
- /usr/local/bin/fleet prepare db --config /etc/fleetdm/fleetdm.yml
/usr/local/bin/fleet prepare db --config /etc/fleetdm/fleetdm.yml
- Init FleetDM database
- Init FleetDM database
- wget https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/ansible/fleetdm/fleetdm-systemd.service -O /etc/systemd/system/fleetdm.service
wget https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/ansible/fleetdm/fleetdm-systemd.service -O /etc/systemd/system/fleetdm.service
- Download SystemD config for FleetDM
- systemctl enable fleetdm
systemctl enable fleetdm
- systemctl start fleetdm
systemctl start fleetdm
- netstat -tnlp | grep fleet
netstat -tnlp | grep fleet
- Check that MySQL is listening on port 8080
Install NGINX
- apt install nginx -y
apt install nginx -y
- wget https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/ansible/nginx/nginx.conf -O /etc/nginx/nginx.conf
wget https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/ansible/nginx/nginx.conf -O /etc/nginx/nginx.conf
- wget https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/ansible/nginx/nginx_fleetdm.conf -O /etc/nginx/conf.d/fleetdm.conf
wget https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/ansible/nginx/nginx_fleetdm.conf -O /etc/nginx/conf.d/fleetdm.conf
- Download NGINX configs
- systemctl enable nginx
systemctl enable nginx
- systemctl restart nginx
systemctl restart nginx
- netstat -tnlp | grep nginx
netstat -tnlp | grep nginx
- Check that MySQL is listening on port 80 and 443
Setup UFW
- ufw allow OpenSSH
ufw allow OpenSSH
- ufw allow 'Nginx HTTP'
ufw allow 'Nginx HTTP'
- ufw allow 'Nginx HTTPS'
ufw allow 'Nginx HTTPS'
- ufw enable
ufw enable
Setup FleetDM via WebGUI
- Open a web browser to FleetDM
- Setup user
- Enter a <username>
<username>
into Username - Enter a <password>
<password>
into Password - Enter an <e-mail>
<e-mail>
for the admin user - Select “Next”
- Enter a
- Organization details
- Enter organization name
- Enter the organization URL
- Select “Next”
- Set Fleet URL
- Accept the default Fleet URL, unless you need to change it
- Select “Submit”
- Accept the default Fleet URL, unless you need to change it
- Select “Finish”
Deploy Osquery v4.6.0 agent
Osquery.flags vs. Osquery.conf
A common struggle for new Osquery users is knowing when a config option should be set in
osquery.flags
or osquery.conf
. First, I would like to provide this Youtube video which is a recording of an Osquery office hours meeting where I asked this question to the core developers of Osquery and the discussion that followed. @zwass started the discussion by stating that osqueryd --help
outputs two sections of config options. The first set of config options must be placed into the osquery.flags
file and the second set can be specified in both config files. @teddyreedv stated that the osquery.flags
file is meant to define the start-up behavior of Osquery. Therefore, the config options that are specified in osquery.flags
are static throughout the Osquery runtime but the config options specified in osquery.conf
are dynamic throughout the runtime. For example, in the osqeury.flags
file you would specify which user the Osquery agent should run as, which is not something you can change during runtime.
Furthermore, there are additional considerations to understand when connecting Osquery to a fleet manager/TLS endpoint like FleetDM. The first consideration is the fleet manager can not modify the
osquery.flags
file; however, if a config option can be set in both config files the value specified in osquery.conf
will override the value in osquery.flags
. What this ultimately means is in this scenario, the server gets the final say in how Osquery operates. For example, you can specify the --max_read
option to 1MB in osquery.flags
but the server could override this setting by setting this value to 5MB in osquery.conf
. To conceptualize this, @zwass made a good comment that the order of operations when loading a config starts with osquery.flags
and then osquery.conf
is loaded, which overrides any settings specified by osquery.flags
To this point, the discussion has only provided how Osquery operates and did not provide specific guidance on how to construct config files for new users. It’s important to understand how Osquery ingests these config options to create the optimal configs for your environment. My guidance for new users for constructing Osquery configs is to create separate configs that target specific environments (QA vs. prod vs. cloud) and for each target OS (Linux, macOS, and Windows). First, start with constructing the
osquery.flags
file and keep it as small as possible, which means only specifying the necessary flags to start Osquery in the desired state. For example, if Osquery is connecting to a fleet manager you need to specify the necessary flags such as: --enroll_secret
, --tls_server_cert
, and --tls_hostname
to connect to a fleet manager to for further instructions.
For constructing
osquery.conf
I still recommend generating a config file for each environment and OS flavor. My reasoning for this is you may want to monitor multiple sets of machines differently. For example, the data you might collect from a set of Windows user endpoints is not the same set of data you would collect from Linux machines in AWS. Additionally, not all Osquery tables are cross-platform so on Windows you may collect the domain information with the ntdomains
table, which does not exist for Linux. Conversely, on Linux, you may collect all the configured sudo users with the sudoers
table. In addition to targeting the OS, the environment type may also play a factor in deciding how you monitor the machine. In a production environment, you may need to squeeze all the performance you can out of a system to keep your platform fast. Therefore, in a production environment, you may set strict Osquery watchdog settings so Osquery doesn’t impact system performance. Lastly, one of the ways I learned to construct my Osquery.conf
is by looking at examples on Github such as this repo: palantir/osquery-configuration.
Manual Osquery install on Ubuntu
- SSH into UbuntuVM
- export OSQUERY_KEY=1484120AC4E9F8A1A577AEEE97A80C63C9D8B80B
export OSQUERY_KEY=1484120AC4E9F8A1A577AEEE97A80C63C9D8B80B
- sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys $OSQUERY_KEY
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys $OSQUERY_KEY
- sudo add-apt-repository 'deb [arch=amd64] https://pkg.osquery.io/deb deb main'
sudo add-apt-repository 'deb [arch=amd64] https://pkg.osquery.io/deb deb main'
- sudo apt-get update -y
sudo apt-get update -y
- sudo apt-get install osquery -y
sudo apt-get install osquery -y
- openssl s_client -showcerts -connect <FleetDM FQDN>:443 2>/dev/null </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /etc/osquery/fleetdm.crt
openssl s_client -showcerts -connect <FleetDM FQDN>:443 2>/dev/null </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /etc/osquery/fleetdm.crt
- Write the FleetDM public certificate to disk
- Open a web browser to FleetDM and Login
- Select “Add new host” in the top right
- Copy the enrollment secret
- echo '<FleetDM enroll secret>' > /etc/osquery/osquery.key
echo '<FleetDM enroll secret>' > /etc/osquery/osquery.key
- wget https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/osquery/osquery_linux.flags -O /etc/osquery/osquery.flags
wget https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/osquery/osquery_linux.flags -O /etc/osquery/osquery.flags
- Download Osquery.flags
Osquery.flags
config
- Download
- sed -i 's/{{ fleetdm_fqdn }}/<FleetDM FQDN>/g' /etc/osquery/osquery.flags
sed -i 's/{{ fleetdm_fqdn }}/<FleetDM FQDN>/g' /etc/osquery/osquery.flags
- sed -i 's/{{ fleetdm_port }}/<FleetDM port - default 443>/g' /etc/osquery/osquery.flags
sed -i 's/{{ fleetdm_port }}/<FleetDM port - default 443>/g' /etc/osquery/osquery.flags
- systemctl restart osqueryd
systemctl restart osqueryd
- systemctl status osqueryd
systemctl status osqueryd
- Make sure there are no errors
- Make sure there are no errors
Manual Osquery install on Windows
- Login into Windows
- Open Powershell as Administrator
- Invoke-WebRequest -Uri https://pkg.osquery.io/windows/osquery-4.6.0.msi -OutFile $ENV:TEMP\osquery-4.6.0.msi -MaximumRedirection 3
Invoke-WebRequest -Uri https://pkg.osquery.io/windows/osquery-4.6.0.msi -OutFile $ENV:TEMP\osquery-4.6.0.msi -MaximumRedirection 3
- Download Osquery
- Start-Process $ENV:TEMP\osquery-4.6.0.msi -ArgumentList '/quiet' -Wait
Start-Process $ENV:TEMP\osquery-4.6.0.msi -ArgumentList '/quiet' -Wait
- Install Osquery
- Install Osquery
- Open a web browser to FleetDM and Login
- Click “Add new host” in the top right
- Click “Download” under Enroll secret
- Click “Download” under Server Certificate
- Click “Download” under Flagfile
- cd ~/Downloads
cd ~/Downloads
- mv .\secret.txt 'C:\Program Files\osquery\secret.txt'
mv .\secret.txt 'C:\Program Files\osquery\secret.txt'
- mv .\fleet.pem 'C:\Program Files\osquery\fleet.pem'
mv .\fleet.pem 'C:\Program Files\osquery\fleet.pem'
- rm 'C:\Program Files\osquery\osquery.flags'
rm 'C:\Program Files\osquery\osquery.flags'
- mv .\flagfile.txt 'C:\Program Files\osquery\osquery.flags'
mv .\flagfile.txt 'C:\Program Files\osquery\osquery.flags'
- Restart-Service -Name osqueryd
Restart-Service -Name osqueryd
Manual Osquery v4.9.0 install on macOS
- Login into macOS
- Open terminal as sudo
- curl https://pkg.osquery.io/darwin/osquery-4.9.0.pkg --output /tmp/osquery-4.9.0.pkg
curl https://pkg.osquery.io/darwin/osquery-4.9.0.pkg --output /tmp/osquery-4.9.0.pkg
- Download Osquery
- sudo installer -pkg /tmp/osquery-4.9.0.pkg -target /
sudo installer -pkg /tmp/osquery-4.9.0.pkg -target /
- Install Osquery
- openssl s_client -showcerts -connect <FleetDM FQDN>:443 2>/dev/null </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /var/osquery/fleetdm.crt
openssl s_client -showcerts -connect <FleetDM FQDN>:443 2>/dev/null </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /var/osquery/fleetdm.crt
- Write the FleetDM public certificate to disk
- Write the FleetDM public certificate to disk
- Open a web browser to FleetDM and Login
- Select “Add new host” in the top right
- Copy the enrollment secret
- echo '<FleetDM enroll secret>' > /var/osquery/osquery.key
echo '<FleetDM enroll secret>' > /var/osquery/osquery.key
- curl https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/osquery/osquery_macos.flags --output /var/osquery/osquery.flags
curl https://raw.githubusercontent.com/CptOfEvilMinions/FleetDM-Automation/main/conf/osquery/osquery_macos.flags --output /var/osquery/osquery.flags
- Download osquery.flags
osquery.flags
config
- Download
- sed -i '' "s/{{ fleetdm_fqdn }}/<FleetDM FQDN>/g" /var/osquery/osquery.flags
sed -i '' "s/{{ fleetdm_fqdn }}/<FleetDM FQDN>/g" /var/osquery/osquery.flags
- sed -i '' "s/{{ fleetdm_port }}/<FleetDM port>/g" /var/osquery/osquery.flags
sed -i '' "s/{{ fleetdm_port }}/<FleetDM port>/g" /var/osquery/osquery.flags
- Set FleetDM FQDN and port for Osquery to report too
- cp /var/osquery/com.facebook.osqueryd.plist /Library/LaunchDaemons/com.facebook.osqueryd.plist
cp /var/osquery/com.facebook.osqueryd.plist /Library/LaunchDaemons/com.facebook.osqueryd.plist
- Copy LaunchDaemon
- In the top-right select the Apple icon then “System Preferences”
- Security & Privacy > Privacy > Full Disk Access
- Select the the lock in the bottom left
- Press Shift + Command + G
- Enter /usr/local/bin/osqueryd
/usr/local/bin/osqueryd
- Drag and drop osqueryd
osqueryd
from Finder to Full Disk Access section - Make sure osqueryd
osqueryd
is checked - Press the lock in the bottom left to lock these settings from being modified
- sudo launchctl load /Library/LaunchDaemons/com.facebook.osqueryd.plist
sudo launchctl load /Library/LaunchDaemons/com.facebook.osqueryd.plist
- Start LaunchDaemon for Osquery
- sudo osqueryctl start
sudo osqueryctl start
- sudo osqueryctl status
sudo osqueryctl status
Automated Osquery install with Ansible on Windows and Ubuntu
Deploy on Ubuntu
Init playbook for Ubuntu
- export FLEETDM_TOKEN=$(curl -k -X POST https://<FleetDM FQDN>:<Port>/api/v1/fleet/login -d '{"Email": "<admin username>", "Password": "<admin password>"}' | jq -r '.token')
export FLEETDM_TOKEN=$(curl -k -X POST https://<FleetDM FQDN>:<Port>/api/v1/fleet/login -d '{"Email": "<admin username>", "Password": "<admin password>"}' | jq -r '.token')
- Request a FleetDM JWT authentication token
- Store the JWT authentication token in an environment variable named FLEETDM_TOKEN
FLEETDM_TOKEN
- For more information on this process see my blog post here: DEMYSTIFYING THE KOLIDE FLEET API WITH CURL, PYTHON, FLEETCTL, AND ANSIBLE
- vim group_vars/fleetdm.yml
vim group_vars/fleetdm.yml
and set:- fleetdm_fqdn
fleetdm_fqdn
– Set this value to the FQDN of FleetDM - fleetdm_port
fleetdm_port
– Set the port that FleetDM is exposed on – default port 443
- vim group_vars/osquery.yml
vim group_vars/osquery.yml
and set:- osquery_version
osquery_version
– OPTIONAL – Set the version of Osquery you want to install – default 4.6.1
- vim hosts.ini
vim hosts.ini
add IP addresses for Linux hosts under[osquery_linux][osquery_linux]
Run playbook
- ansible-playbook -i hosts.ini deploy_osquery_linux.yml -u <user> -K
ansible-playbook -i hosts.ini deploy_osquery_linux.yml -u <user> -K
- Enter password
- Enter password
Deploy on Windows
Init playbook for Windows
- export FLEETDM_TOKEN=$(curl -k -X POST https://<FleetDM FQDN>:<Port>/api/v1/fleet/login -d '{"Email": "<admin username>", "Password": "<admin password>"}' | jq -r '.token')
export FLEETDM_TOKEN=$(curl -k -X POST https://<FleetDM FQDN>:<Port>/api/v1/fleet/login -d '{"Email": "<admin username>", "Password": "<admin password>"}' | jq -r '.token')
- vim group_vars/fleetdm.yml
vim group_vars/fleetdm.yml
and set:- fleetdm_fqdn
fleetdm_fqdn
– Set this value to the FQDN of FleetDM - fleetdm_port
fleetdm_port
– Set the port that FleetDM is exposed on – default port 443
- vim group_vars/osquery.yml
vim group_vars/osquery.yml
and set:- osquery_version
osquery_version
– OPTIONAL – Set the version of Osquery you want to install
- vim group_vars/windows.yml
vim group_vars/windows.yml
and set:- ansible_user
ansible_user
– Set this to a Windows username - ansible_password
ansible_password
– Set this to a Windows password
- vim hosts.ini
vim hosts.ini
add IP addresses for Linux hosts under[osquery_windows][osquery_windows]
Init Windows VM for Ansible
- Log into Windows VM
- Open Powershell as Administrator
- Set-ExecutionPolicy Unrestricted
Set-ExecutionPolicy Unrestricted
- Enter “y”
- powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1'))"
powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1'))"
Run playbook
- ansible-playbook -i hosts.ini deploy_osquery_windows.yml
ansible-playbook -i hosts.ini deploy_osquery_windows.yml
Create a Live query
WebGUI
- Login into FleetDM
- Select “Queries” on the left
- Select “Create new query” in the top right
- Enter Get processes
Get processes
into the Query title field - Enter SELECT * FROM processes
SELECT * FROM processes
into the SQL field - Select MS Windows
MS Windows
for Select targets - Select “Run” and wait
- Enter
FleetCTL
- cd /tmp && wget https://github.com/kolide/fleet/releases/download/3.2.0/fleet.zip
cd /tmp && wget https://github.com/kolide/fleet/releases/download/3.2.0/fleet.zip
- unzip fleet.zip
unzip fleet.zip
- mv <OS - macOS:darwin, linux:linux>/fleetctl /usr/local/bin/fleetctl
mv <OS - macOS:darwin, linux:linux>/fleetctl /usr/local/bin/fleetctl
- fleetctl config set --address https://<FleetDM FQDN>:<port> --tls-skip-verify
fleetctl config set --address https://<FleetDM FQDN>:<port> --tls-skip-verify
- Set the Fleet API address
- Only specify --tls-skip-verify
--tls-skip-verify
, if you have a self-signed certificate
- fleet login
fleet login
- Enter Fleet user e-mail
- Enter Fleet user password
- fleetctl query --query "<Osquery query>" --hosts <Fleet friendly name>
fleetctl query --query "<Osquery query>" --hosts <Fleet friendly name>
Create a saved query
WebGUI
- Login into FleetDM
- Select “Queries” on the left
- Select “Create a new query”
- Enter Netstat
Netstat
into Quer title - Enter SELECT DISTINCT process.name, listening.port, listening.address, process.pid FROM processes AS process JOIN listening_ports AS listening ON process.pid = listening.pid;
SELECT DISTINCT process.name, listening.port, listening.address, process.pid FROM processes AS process JOIN listening_ports AS listening ON process.pid = listening.pid;
into SQL - Select All hosts
All hosts
for Select targets - Select Save > Save As New
- Enter
- Select “Queries” on the left
Create a query pack
FleetCTL
- wget https://raw.githubusercontent.com/osquery/osquery/master/packs/ossec-rootkit.conf
wget https://raw.githubusercontent.com/osquery/osquery/master/packs/ossec-rootkit.conf
- fleetctl convert -f ossec-rootkit.conf > ossec-rootkit--pack-fleet.yaml
fleetctl convert -f ossec-rootkit.conf > ossec-rootkit--pack-fleet.yaml
- Convert JSON to YAML
- Convert JSON to YAML
- fleetctl apply -f ossec-rootkit--pack-fleet.yaml
fleetctl apply -f ossec-rootkit--pack-fleet.yaml
- Login into FleetDM
- Select “Queries” on the left
WebGUI
- Login into FleetDM
- Select “Queries” on the left
- Select “Create new pack”
- Enter Collect sys info
Collect sys info
for Query pack title - Select All hosts for Select targets
- Select “Save query pack”
- Enter
- Select the drop-down in the top right
- Select “Netstat”
- Enter settings for query
- Select “Save”
- Enter settings for query
FleetDM file carving with FleetCTL
- fleetctl query --hosts mac-workstation --query 'SELECT * FROM carves WHERE carve = 1 AND path = "C:\Windows\System32\drivers\etc\hosts"'
fleetctl query --hosts mac-workstation --query 'SELECT * FROM carves WHERE carve = 1 AND path = "C:\Windows\System32\drivers\etc\hosts"'
- fleetctl get carves
fleetctl get carves
- fleetctl get carve 1 --outfile <outfile name>.tar
fleetctl get carve 1 --outfile <outfile name>.tar
- tar -xvf <outfile name>.tar
tar -xvf <outfile name>.tar
Lessons learned
I am currently reading a book called “Cracking the Coding Interview” and it is a great book. One interesting part of the book is their matrix to describe projects you worked on and the matrix contains the following sections which are: challenges, mistakes/failures, enjoyed, leadership, conflicts, and what would you do differently. I am going to try and use this model at the end of my blog posts to summarize and reflect on the things I learn. I don’t blog to post things that I know, I blog to learn new things and to share the knowledge of my security research.
New skills/knowledge
- Learned how to utilize the FleetDM API
- Learned new features of FleetDM
Enjoyed
- Committing code upstream to the FleetDM project to support passwords via Docker secrets
- Committing code upstream to the FleetDM project to run the Docker container as a non-root user
Challenges
- Inconsistency of features between docker-compose v2.x and v3.x
References
- How To Set or Change Timezone on Ubuntu 18.04
- Check package version using apt-get/aptitude?
- How To Install and Secure Redis on Ubuntu 18.04
- How To Install MySQL 8.0 on Ubuntu 20.04
- How to Create MySQL Users Accounts and Grant Privileges
- Setting up a UFW Secured Nginx Reverse Proxy with HTTP Authentication and TLS Certificates from Let’s Encrypt
- Generating a self-signed certificate using OpenSSL
- Fleet releases
- Linux: How to Create a Group in Ubuntu Linux Server 14.04 LTS
- How to create a Linux user that cannot log in
- POC: USING KSQL TO ENRICH ZEEK LOGS WITH OSQUERY AND SYSMON DATA
- Using openssl to get the certificate from a server
- Installing Chocolatey
- PowerTip: Use PowerShell to Find the Temp Folder Path
- Out-File
- DEMYSTIFYING THE KOLIDE FLEET API WITH CURL, PYTHON, FLEETCTL, AND ANSIBLE
- Introduction to osquery for Threat Detection and DFIR
- Youtube – osquery Office Hours 2020 12 22
- Osquery docs – Command-line flags
- Github – palantir/osquery-configuration
Have you been able to get a Windows system setup with the polylogyx extension while being connected to fleetdm? If so do you have a writeup that might help with that integration? Your blogs are fantastic btw…great work all around!
Hey Fred,
I don’t have a blog post that shows how to use Osquery + Polygolyx + FleetDM but I do have a blog post (linked below) on setting up Osquery + Polygolyx. I think this blog post on FleetDM and the blog post below should provide all the relevant bits to get everything running.
https://holdmybeersecurity.com/2020/06/08/poc-using-ksql-to-enrich-zeek-logs-with-osquery-and-sysmon-data/
Seems that the nginx conf is not relevant anymore now fleet is not kolide, the paths don’t match up
Hey Jason,
Thanks for letting me know, I have updated the FletDM-Automation repo. Please pull down the latest changes for a working NGINX config.