Installation Guide
Full setup from a bare Debian/Proxmox host to a running ThruntOps lab.
Table of contents
- 1. Install Ludus
- 2. Configure API Access
- 3. Build Templates
- 4. Install Ansible Roles
- 5. Deploy the Range
- 6. Verify
- Notes
1. Install Ludus
Full Ludus documentation at docs.ludus.cloud. Project home at ludus.cloud.
Prerequisites
- x86_64 CPU with VMX/SVM (hardware virtualization enabled in BIOS)
- Debian 12/13 or Proxmox 8/9
- Minimum 48 GB RAM, 200 GB storage (NVMe recommended)
- Wired ethernet (WiFi not supported)
- Root access + internet connectivity
- Docker must NOT be installed on the host
Install
curl --proto '=https' --tlsv1.2 -sSf https://ludus.cloud/install | bash
The installer will prompt for configuration values (defaults are fine) and reboot the machine. After reboot, monitor progress:
ludus-install-status
2. Configure API Access
Once Ludus is running, get your API key and configure the client:
ludus users apikey
Set the API URL and key in ~/.config/ludus/config.yml or via environment variables if accessing remotely.
3. Build Templates
List available templates and build the ones required by this lab:
ludus templates list
Build required templates (each can take 20–60 minutes):
ludus templates build -n debian-12-x64-server-template
ludus templates build -n win2022-server-x64-template
ludus templates build -n win11-22h2-x64-enterprise-template
Monitor build progress:
ludus templates logs -f
Wait for all templates to show BUILT before proceeding:
ludus templates list
4. Install Ansible Roles
Install the Galaxy roles and register all local roles with the included script:
# Elastic Stack
ludus ansible roles add badsectorlabs.ludus_elastic_container
ludus ansible roles add badsectorlabs.ludus_elastic_agent
# Splunk (if using Splunk profile)
# ludus ansible roles add -d roles/ludus_splunk
# ludus ansible roles add -d roles/ludus_splunk_uf
# All local roles (AD content, local users, etc.)
bash roles/install-roles.sh
After any change to a local role, re-sync with --force to overwrite the cached version:
ludus ansible roles add -d roles/<name> --force
Verify all roles are installed:
ludus ansible roles list
5. Deploy the Range
Each SIEM has its own script (elastic.sh, wazuh.sh, splunk.sh) that destroys any existing range, applies the config, and deploys in one step. Each accepts one of three profile flags:
--base— 1 AD + 1 workstation--dual— 2 AD + 2 workstations--adcs— 1 AD + ADCS + 1 workstation
bash elastic.sh --dual # ranges/elk-dual.yml
bash elastic.sh --adcs # ranges/elk-adcs.yml
bash wazuh.sh --dual # ranges/wazuh-dual.yml
bash splunk.sh --dual # ranges/splunk-dual.yml
Or step by step:
ludus range config set -f ranges/elk-dual.yml
ludus range deploy
ludus range logs -f
Monitor deployment:
ludus range logs -f
Check final status:
ludus range status
All VMs should show BUILT and the deployment status should be SUCCESS.
6. Verify
Elastic profile
Open Kibana at https://<range_ip>.20.1:5601 and navigate to:
Management → Fleet → Agents
All four VMs (DC01-2022, DC01-SEC, WIN11-22H2-1, WIN11-22H2-2) should show status Healthy.
Splunk profile
Check that all Universal Forwarders are connected via Splunk Web at http://<range_ip>.20.1:8000:
- Settings → Forwarding and receiving → Forwarder management — all forwarders should appear
- Search:
index=windows earliest=-15m— Windows Event Logs from all domain-joined VMs
Wazuh profile
Run the Wazuh agent status check:
bash tests/wazuh_status.sh
All agents should appear with status active.
Notes
- DCs do not support local SAM accounts — local user provisioning only applies to member machines
ludus ansible roles adddoes not overwrite an existing role — use--forceflag to update installed roles