Building a Containerized Cybersecurity Lab from Scratch
Why build your own lab?
Cloud-based security labs are convenient, but they come with limitations — cost, latency, and lack of control over the network stack. Building your own gives you full visibility into every packet entering or leaving your test environment.
For my capstone project, I needed an environment where I could safely run offensive tools against vulnerable targets without touching production networks. The solution: Docker containers connected via custom Linux network namespaces.
Architecture
The lab consists of three network segments:
- Attacker subnet — Kali-based containers with pre-installed tools
- Target subnet — Intentionally vulnerable services (DVWA, Metasploitable)
- Monitoring subnet — IDS/IPS sensors watching traffic between segments
# docker-compose.yml (simplified)
services:
attacker:
build: ./attacker
networks:
- attack-net
target-web:
image: vulnerables/web-dvwa
networks:
- target-net
monitor:
build: ./monitor
networks:
- attack-net
- target-net
Each subnet is isolated using Docker's bridge networking. The monitor container sits on both networks, capturing traffic with tcpdump and feeding it into Suricata for real-time alerting.
Network isolation
The key challenge was ensuring complete isolation from the host network. I used iptables rules on the Docker host to prevent any container-to-internet traffic:
# Block all outbound traffic from lab containers
iptables -I DOCKER-USER -i br-lab -j DROP
iptables -I DOCKER-USER -i br-lab -o br-lab -j ACCEPT
This creates a closed loop — containers can talk to each other but never reach the outside world.
Your ad here — Interested in reaching security-minded developers? Get in touch
Results
The lab runs on a single VPS with 4GB RAM. I can spin up the entire environment in under 30 seconds with docker compose up. It's been invaluable for:
- Practicing OWASP Top 10 exploitation techniques
- Testing IDS rule sets before deploying to production
- Demonstrating security concepts to colleagues
What I'd do differently
If I were starting over, I'd use Podman instead of Docker for rootless container execution. I'd also add a VPN gateway container so team members could connect remotely to the lab for collaborative exercises.
The full source is available on my GitHub.