A pfSense-routed, k3s-managed SOC lab on VMware Workstation 17 Pro (Windows 11).
- Overview
- Quick Start
- Project Structure
- Documentation
- Development
- Appendix A β pfSense install walk-through
- Appendix B β 1-page printable quick-start
- pfSense (edge)
- ContainerHost (k3s + Portainer + Traefik + MetalLB)
- Windows victim
- optional Nessus VM
- Wazuh
- TheHive
- Cortex
- CALDERA
- DVWA
- Kali (CLI)
- Nessus Essentials
The project now uses a modular architecture with reusable PowerShell modules and dedicated builder scripts:
git clone <repo-url> E:\SOC-9000\SOC-9000
cd E:\SOC-9000\SOC-9000
Copy-Item .env.example .env # Configure your paths
# Build all VMs (interactive menu or CLI)
.\setup-soc9000.ps1 -All -Verbose
# Or build selectively
.\setup-soc9000.ps1 -Ubuntu -Windows -Verbose
# Or build individual VMs
.\ubuntu-build.ps1 -Verbose
.\windows-build.ps1 -VerboseAvailable Commands:
.\setup-soc9000.ps1- Main orchestrator (interactive menu or CLI parameters).\ubuntu-build.ps1- Build Ubuntu container host VM.\windows-build.ps1- Build Windows 11 victim VM.\nessus-build.ps1- Build Nessus VM (fully automated).\pfsense-build.ps1- Build pfSense VM (fully automated)
Key Features:
- β Fully automated VM builds - Ubuntu, Windows, pfSense, Nessus
- β
Modular PowerShell modules (
modules/SOC9000.*.psm1) - β
Centralized configuration (
config/soc9000.config.psd1) - β Individual builder scripts at repo root
- β
Comprehensive tests - 39 Pester tests (
tests/) - β Zero manual VM creation - Everything via Packer
- β
Backwards compatibility via
legacy/build-packer.ps1
- docs/ - Comprehensive guides (setup, deployment, operations)
- CHANGELOG.md - Version history and implementation details
- MIGRATION.md - Migration guide from older versions
Before building, ensure you have:
- PowerShell 7.2+
- VMware Workstation 17+
- Packer
- kubectl
- Git
- WSL2 with Ubuntu
Quick install:
.\scripts\setup\install-prereqs.ps1Configure VMware virtual networks:
.\scripts\setup\configure-vmnet.ps1
.\scripts\utils\verify-networking.ps1End-to-end bring-up (VMs, k3s, apps, telemetry):
.\scripts\utils\lab-up.ps1
.\scripts\utils\lab-status.ps1SOC-9000/
βββ setup-soc9000.ps1 # Main orchestrator (interactive/CLI)
βββ ubuntu-build.ps1 # Ubuntu container host builder
βββ windows-build.ps1 # Windows 11 victim builder
βββ nessus-build.ps1 # Nessus VM builder (automated)
βββ pfsense-build.ps1 # pfSense VM builder (automated)
βββ build.ps1 # Build helper (linting + tests)
βββ deploy.ps1 # Deployment helper (validation + deploy)
β
βββ modules/ # PowerShell modules
β βββ SOC9000.Utils.psm1 # Logging, validation, paths
β βββ SOC9000.Utils.psd1 # Module manifest
β βββ SOC9000.Build.psm1 # Packer/VMware helpers
β βββ SOC9000.Build.psd1 # Module manifest
β βββ SOC9000.Platform.psm1 # OS checks, prereqs
β βββ SOC9000.Platform.psd1 # Module manifest
β
βββ config/ # Configuration
β βββ soc9000.config.psd1 # Centralized settings
β
βββ scripts/ # Organized scripts
β βββ setup/ # Setup scripts
β β βββ install-prereqs.ps1
β β βββ download-isos.ps1
β β βββ configure-vmnet.ps1
β β βββ wsl-prepare.ps1
β β βββ ...
β βββ build/ # Build scripts
β β βββ nessus-vm-build-and-config.ps1
β β βββ clean-packer-cache.ps1
β β βββ ...
β βββ deploy/ # Deployment scripts
β β βββ apply-k8s.ps1
β β βββ wazuh-vendor-and-deploy.ps1
β β βββ vmrun-lib.ps1
β β βββ ...
β βββ utils/ # Utility scripts
β βββ lab-up.ps1
β βββ lab-down.ps1
β βββ lab-status.ps1
β βββ ...
β
βββ tests/ # Pester tests
β βββ SOC9000.Utils.Tests.ps1
β βββ SOC9000.Build.Tests.ps1
β βββ SOC9000.Platform.Tests.ps1
β βββ ...
β
βββ legacy/ # Backwards compatibility
β βββ build-packer.ps1 # Deprecation shim
β
βββ packer/ # Packer templates
βββ ansible/ # Ansible playbooks
βββ k8s/ # Kubernetes manifests
β
βββ .gitignore # Comprehensive ignore rules
βββ PSScriptAnalyzerSettings.psd1 # Code quality settings
βββ README.md # This file
βββ MIGRATION.md # Migration guide
βββ REFACTORING-SUMMARY.md # Refactoring documentation
configure-vmnet.ps1 creates or updates VMnet8 and VMnet20β23 with the correct subnets. verify-networking.ps1 performs quick assertions and reports success when adapters, services, and hosts entries look good.
During the bring-up process you will still perform a short manual pfSense install (ChunkΒ 3); the scripts then autoβconfigure it.
- https://portainer.lab.local:9443
- https://wazuh.lab.local
- https://thehive.lab.local
- https://cortex.lab.local
- https://caldera.lab.local
- https://dvwa.lab.local
- https://nessus.lab.local:8834 (container or VM)
flowchart LR
INET(Internet) --> VMnet8[VMnet8 NAT]
VMnet8 --> PFS[pfSense]
subgraph Segments
PFS ---|VMnet20| MGMT[172.22.10.0/24]
PFS ---|VMnet21| SOC[172.22.20.0/24]
PFS ---|VMnet22| VICTIM[172.22.30.0/24]
PFS ---|VMnet23| RED[172.22.40.0/24]
end
CH[(ContainerHost\nk3s+Portainer+Traefik+MetalLB)] --- MGMT
CH --- SOC
CH --- VICTIM
CH --- RED
WIN[(Windows Victim)] --- VICTIM
NESSUS[(Nessus VM - optional)] --- SOC
subgraph k3s Apps
WZ[Wazuh]:::svc
TH[TheHive]:::svc
CX[Cortex]:::svc
CA[CALDERA]:::svc
DV[DVWA]:::svc
KL[Kali CLI]:::svc
end
classDef svc fill:#eef,stroke:#66f
CH -->|Ingress/TLS| WZ & TH & CX & CA & DV & KL
Run linting and tests before committing:
.\build.ps1 # Run PSScriptAnalyzer + Pester tests
.\build.ps1 -Fix # Auto-fix PSScriptAnalyzer issues
.\build.ps1 -SkipAnalyzer # Run tests only# Run all tests
Invoke-Pester .\tests\
# Run specific test suite
Invoke-Pester .\tests\SOC9000.Utils.Tests.ps1 -Output Detailed
# Run module tests only
Invoke-Pester .\tests\SOC9000.*.Tests.ps1Modules are located in modules/ with manifests (.psd1) and source (.psm1):
- SOC9000.Utils - Logging, validation, paths, retries
- SOC9000.Build - Packer/VMware build automation
- SOC9000.Platform - OS detection, prerequisites, installers
Import modules in your scripts:
Import-Module (Join-Path $PSScriptRoot 'modules' 'SOC9000.Utils.psm1') -ForceConfiguration is loaded in this order:
- Command-line parameters
- Environment variables
.envfileconfig/soc9000.config.psd1- Hard-coded fallbacks
See docs/00-prereqs.md β 08-atomic-caldera-wazuh.md for full documentation and docs/releases.md for guidance on GitHub releases. The repo is chunked so you can run pieces or the whole thing.
Goal: create the pfSense VM, install, and enable SSH so the repo can auto-configure everything afterward.
Minimum hardware:
- 2 vCPU
- 2 GB RAM
- 20β40 GB disk
- Mount
pfsense.iso
Add five NICs in this order:
- ethernet0 β VMnet8 (WAN)
- ethernet1 β VMnet20 (MGMT)
- ethernet2 β VMnet21 (SOC)
- ethernet3 β VMnet22 (VICTIM)
- ethernet4 β VMnet23 (RED)
Tip: use vmxnet3 for each NIC.
- Boot β Install pfSense
- Keymap β Accept default β Continue
- Partitioning β choose Auto (UFS) (or ZFS if you prefer) β Install
- Wait for files to copy β Reboot (eject ISO if prompted)
Youβll see the pfSense console menu (numbered options). Do this:
- Option 14) Enable Secure Shell β Yes to enable SSH
- When asked which user can SSH: select admin (or allow both admin/root)
- Note the LAN IP shown in the banner.
Immediately after install, pfSense may show 192.168.1.1 on LAN. Our automation reassigns LAN to 172.22.10.1 during the config import.
- If the installer asked for a password, use what you set.
- If not: default is
admin/pfsense. - The repo expects
.envβPFSENSE_ADMIN_USER=admin,PFSENSE_ADMIN_PASS=.... - If your password differs, update
.envbefore continuing.
Return to your PowerShell window (where lab-up.ps1 paused) and press Enter.
The playbooks will SSH in, import config (interfaces, DHCP, rules, syslog),
and reboot pfSense automatically.
Expected final IPs:
- MGMT/LAN = 172.22.10.1
- SOC = 172.22.20.1
- VICTIM = 172.22.30.1
- RED = 172.22.40.1
Host: Windows 11 + VMware Workstation 17 Pro
winget install Git.Git HashiCorp.Packer Kubernetes.kubectl Helm.Helm OpenSSL.Win64 -e
wsl --install -d Ubuntu-22.04
# In Ubuntu:
sudo apt update && sudo apt -y install ansible git jq curlE:\SOC-9000\isos\(ubuntu-22.04.iso, win11-eval.iso, pfsense.iso, [optional] nessus_latest_amd64.deb)E:\SOC-9000\artifacts\E:\SOC-9000\temp\
Use scripts/configure-vmnet.ps1 to create or update the required host-only networks and scripts/verify-networking.ps1 to confirm adapter and DHCP settings. The configuration script uses VMware's vnetlib.exe (or vmnetcfg.exe/vmnetcfgcli.exe when available) and falls back to launching Virtual Network Editor (vmnetcfg.exe) if automation fails:
- VMnet20 = 172.22.10.0/24 (MGMT)
- VMnet21 = 172.22.20.0/24 (SOC)
- VMnet22 = 172.22.30.0/24 (VICTIM)
- VMnet23 = 172.22.40.0/24 (RED)
- Keep VMnet8 = NAT (WAN).
git clone <repo-url> E:\SOC-9000\SOC-9000
cd E:\SOC-9000\SOC-9000
Copy-Item .env.example .env
# Edit .env to match your ISO filenames & network names if neededpwsh -File .\scripts\lab-up.ps1- Create VM with 5 NICs: WANβVMnet8, MGMTβVMnet20, SOCβVMnet21, VICTIMβVMnet22, REDβVMnet23
- Install: Install pfSense β default keymap β Auto (UFS) β Reboot
- Console menu: 14) Enable Secure Shell, allow admin, note LAN IP
- Back in PowerShell: press Enter to continue
- Portainer https://portainer.lab.local:9443
- Wazuh https://wazuh.lab.local
- TheHive https://thehive.lab.local
- Cortex https://cortex.lab.local
- CALDERA https://caldera.lab.local
- DVWA https://dvwa.lab.local
- Nessus https://nessus.lab.local:8834
If names fail: run scripts\hosts-refresh.ps1 as Admin.
- Set
NESSUS_ACTIVATION_CODEin.env(or you'll be prompted duringscripts\nessus-vm-build-and-config.ps1). - Place the Nessus
.debinISO_DIR(defaults to.\isos) and ensureNESSUS_DEBmatches the filename. - URL: https://nessus.lab.local:8834 after deployment.
- Cortex: create Admin + API key
- TheHive β Admin β Cortex β add
http://cortex.soc.svc:9001+ API key
- Wazuh: Agents β containerhost & victim-win should be connected
- pfSense logs query:
log.file.path:/var/log/pfsense/pfsense.log
pwsh -File scripts/lab-status.ps1# show IPs/URLspwsh -File scripts/backup-run.ps1# snapshot state + PV tarball (E:\SOC-9000\backups)pwsh -File scripts/smoke-test.ps1# reachability checkpwsh -File scripts/reset-lab.ps1# soft reset (reapply apps)pwsh -File scripts/reset-lab.ps1 -Hard# also wipes PV data on ContainerHostpwsh -File scripts/lab-down.ps1# stop VMs