// stack
The actual stack.
Two Lenovo boxes, a Netgate firewall, and five years of figuring out what actually matters. This is what's running and why.
01. compute
Homelab nodes
Lenovo ThinkStation P920 Workstation
Primary Proxmox node. heavy compute, VMs, and resource-hungry workloads like Cisco CML and Security Onion.
The big box. Runs the demanding stuff.Lenovo ThinkCentre M710q Tiny
Second Proxmox node. always-on lightweight LXC containers and cluster quorum. Fanless, low power, permanently on.
The small always-on box.Buffalo NAS
Closed file-share appliance on the lab LAN. Not a backup server, not a hypervisor datastore, and not Proxmox Backup Server. Guest disks stay on local node storage.
A network file share. The hypervisors do not boot or back up from it.MacBook Pro 14" M3 Pro
Daily driver. SSH into the lab, write code, push to git, watch the Grafana dashboard.
The laptop I work from.02. networking
Edge, switching, wireless
Netgate 2100. pfSense Plus
Edge firewall and router. Runs FRRouting for the eBGP mesh, VLAN segmentation, Snort IDS, and pfBlockerNG DNS filtering. ARM-based, fanless.
The front door. Controls all traffic in and out of the network.Ubiquiti USW-Lite-8-PoE
8-port managed switch. VLAN trunking between the firewall, nodes, and AP. Powers the access point over Ethernet.
The network hub everything plugs into.Ubiquiti U7 Pro
Wi-Fi 7 AP managed through a self-hosted UniFi controller on the cluster. Separate SSIDs for trusted devices and IoT.
The wireless access point. Managed centrally like enterprise gear.Intel I350-T4V2 NIC
Quad-port NIC in the P920 for additional VLAN separation. SR-IOV capable. one physical card can appear as multiple virtual NICs to VMs.
Extra network ports for isolating different types of traffic.03. platform
Hypervisor & core services
Proxmox VE 9.2.2. kernel 7.0
Two-node HA cluster. Runs VMs and LXC containers with shared storage across both nodes. Everything treated as production. no sandbox exceptions.
The OS that runs on the servers and hosts all the other software.FRRouting. eBGP mesh
BGP running on both Proxmox nodes and the pfSense edge. three peers, two paths per subnet, zero static routes. Private ASNs per RFC 6996. Same routing protocol that runs the internet.
Makes all three boxes automatically learn each other's routes. If one goes down, traffic reroutes itself.nginx + acme.sh. wildcard TLS
Central reverse proxy for all internal services. Wildcard cert for *.lab.securebytes.net via Cloudflare DNS-01. Renewal automated. API token scoped strictly to the securebytes.net zone.
Routes web traffic to the right service. Gives every internal site a valid padlock.Cloudflare Tunnel + Access
Two services exposed publicly with zero open inbound ports. Tunnel daemon dials out to Cloudflare edge. Admin paths protected by email-OTP. No port forwarding, no public IP exposure.
Lets the internet reach two services without opening a hole in the firewall.Tailscale: WireGuard overlay
Deny-by-default ACLs as version-controlled policy. three tags, three tiers (admin / dns / monitor). pfSense is the subnet router, advertising the internal /24 so enrolled clients reach LAN hosts without Tailscale on every box.
Secure remote access to the lab from anywhere. No VPN server, no open ports.Unbound on pfSense
Internal DNS authority for every *.lab.securebytes.net hostname. Host overrides sync from a canonical target list via the pfSense REST API. DHCP hands out only the firewall as resolver.
DNS server and policy owner. Replaced the old Pi-hole VM after the Netgate cutover.Vaultwarden
Self-hosted Bitwarden-compatible password manager. Browser extension on every device. Vault stays on local hardware. no third-party cloud stores the credentials.
Password manager. Like 1Password, but running on my own server.Grid
Ops console hosted on the cluster at grid.securebytes.net. Product identity stays on Grid. Lab login stays Tailscale plus host MFA. Private source of truth is git in the internal repos, sanitized to public GitHub. The self-hosted git guest is retired.
The operations product that runs on this lab. Not how I SSH to the hypervisors.Security Onion
Network IDS on the cluster. Suricata and Zeek watch lab traffic, then forward to Splunk. The sensor stays a sensor.
Watches network traffic for anything suspicious and sends it to Splunk.04. observability
Monitoring & alerting
Grafana + Prometheus + Node Exporter
12-panel NOC dashboard. uptime, CPU, memory, disk, temperature, LAN/WAN throughput per node. Node Exporter on every host (~10 MB RAM). 60-second scrape interval. One consolidated view.
Live dashboard showing the health of every machine. Like a control room.Splunk Enterprise
Homelab SIEM on a dedicated VM. Edge firewall, UniFi, guest syslog, IDS, and CloudTrail land in separate indexes. Internal only. No public URL.
Where the firewall, IDS, and guest logs actually get searched.ntfy
Self-hosted push notification server. Prometheus Alertmanager fires to ntfy when a host goes down or a threshold trips. Push to phone. no polling.
Sends a notification to my phone when something breaks.Uptime Kuma
Public status page at status.securebytes.net. 14 monitors across every external and internal service.
Public uptime page. Green or red for every service.Docker Compose
Runs the entire observability stack: Prometheus, Grafana, Alertmanager. in one compose file. Named volumes persist all data through restarts and full recomposes.
Runs the monitoring tools as containers. Data survives reboots.05. simulation
Network design & lab work
Cisco Modeling Labs: 20-node license
Cisco modeling guest stays powered off unless there is a dedicated lab window. It is the largest RAM tenant on the cluster. Not part of the always-on platform.
Simulates real Cisco gear inside a VM. Left off unless I am actually using it.EVE-NG
Non-Cisco vendor simulation alongside CML. FortiGate live. policy, NAT, VPN. Juniper vMX and Arista vEOS planned for multi-vendor interop topologies.
Like CML but for Fortinet, Juniper, Arista.06. automation
IaC & scripting
Ansible + Jinja2
In progress. Migrating from shell scripts to idempotent playbooks: LXC bootstrap, nginx vhost templating via Jinja2, Netgate Unbound DNS merge, TLS cert distribution. Goal: one command to provision any service end-to-end.
Automates setup tasks so running them twice doesn't break anything.Cloudflare API + Python
Automation target in the Ansible toolkit. creates public DNS records for externally-facing services as part of the provisioning pipeline. Bash for glue scripting throughout.
Automatically creates the DNS entry when a new public service goes live.07. workstation
Software I use daily
VS Code
YAML, Python, Astro, Ansible playbooks, Sigma rules. Vim keybindings.
iTerm2 + Zsh + tmux
SSH into the cluster, git, and every CLI operation. tmux keeps sessions alive on remote nodes across disconnects.
Terminal. Stays connected to remote servers even when the laptop sleeps.Wireshark / tcpdump
tcpdump on the remote node to capture, Wireshark locally to analyze. First tool out when something is wrong on the wire.
Reads actual network packets. Closest thing to seeing what's really on the wire.Astro
This site. Static output, content collections, zero client-side JS framework. Deployed to Cloudflare Pages on every push to main.
Builds this website into static files and ships them to Cloudflare.