← Back to Blog

Building a Security Distribution

November 5, 2025 nullsecdistrodevlog

Behind the scenes of building NullSec Linux: package selection, hardening, and the live-build system. How do you create a security-focused distribution from scratch?

◉ Why Build a Distro?

There are already great security distros: Kali, ParrotOS, BlackArch. Why build another?

  1. Lateralus integration. We wanted the Lateralus SDK pre-installed with full security tooling bindings.
  2. Minimal bloat. Kali ships 600+ tools. Most pentests use maybe 30. NullSec ships lean.
  3. Different workflow. Pipeline-based security automation instead of manual tool juggling.
  4. Learning. Building a distro teaches you more about Linux than any course.

◉ Debian Live-Build

NullSec is built on Debian Bookworm using the live-build system. This gives us:

The build configuration lives in a Git repo:

nullsec-live/
├── auto/
│   ├── build        # Build script
│   ├── clean        # Clean script
│   └── config       # Configuration script
├── config/
│   ├── package-lists/
│   │   ├── base.list.chroot      # Base system packages
│   │   ├── security.list.chroot  # Security tools
│   │   └── lateralus.list.chroot # Lateralus SDK
│   ├── includes.chroot/          # Files to include
│   │   ├── etc/                  # System configs
│   │   └── usr/                  # Custom binaries
│   └── hooks/
│       └── live/                 # Build-time scripts
└── README.md

◉ Package Selection

The core philosophy: include what's actually used daily. Here's our package list rationale:

Recon Tools

# Network discovery
nmap
masscan
netdiscover

# DNS enumeration
dnsrecon
dnsenum
fierce

# Web enumeration
gobuster
nikto
whatweb

Exploitation

# Frameworks
metasploit-framework
exploitdb

# Web exploitation
sqlmap
burpsuite  # Community edition
zaproxy

# Password attacks
john
hashcat
hydra

Post-Exploitation

# Shells and listeners
nc
socat
rlwrap

# Privilege escalation
linpeas
linux-exploit-suggester

Lateralus SDK

# Custom packages (built from source)
lateralus          # Core compiler + runtime
lateralus-security # Security tool bindings
nullkia-de         # Custom desktop environment
marshall           # Network marshal tool

◉ Building Custom Packages

The Lateralus ecosystem doesn't exist in Debian repos, so we package it ourselves:

# Build script for lateralus package
#!/bin/bash
set -e

# Clone and build
git clone https://github.com/bad-antics/lateralus-lang.git
cd lateralus-lang
python -m build

# Create Debian package structure
mkdir -p pkg/DEBIAN pkg/usr/local/lib/python3.11/dist-packages
cp dist/*.whl pkg/usr/local/lib/python3.11/dist-packages/

# Control file
cat > pkg/DEBIAN/control << EOF
Package: lateralus
Version: 1.5.0
Architecture: amd64
Maintainer: NullSec Team
Description: Lateralus programming language
EOF

dpkg-deb --build pkg lateralus_1.5.0_amd64.deb

Custom packages go into a local APT repository served during build.

◉ System Hardening

Live security distros need to balance usability with security. Our hardening choices:

Enabled by Default

Available but Optional

# /etc/nullsec/hardening.conf
mac_randomize=true
hostname_randomize=true
dns_over_https=true
tor_mode=false
kernel_lockdown=false

◉ The Nullkia Desktop

NullSec ships with Nullkia, a custom desktop environment built on Qt:

Nullkia is intentionally lightweight (~200MB RAM idle) to leave resources for tool execution.

◉ Build Process

Building a NullSec ISO:

# Clone the configuration
git clone https://github.com/bad-antics/nullsec-live.git
cd nullsec-live

# Configure
lb config

# Build (takes 30-60 minutes)
sudo lb build

# Output
ls -lh live-image-amd64.hybrid.iso
# 4.2G  NullSec-v2.0-amd64.iso

The build is deterministic — same commit produces identical ISO.

◉ Testing Pipeline

Every ISO goes through automated testing before release:

fn test_iso(iso_path: str) {
    let tests = [
        ("boot", test_qemu_boot),
        ("network", test_network_tools),
        ("lateralus", test_lateralus_sdk),
        ("persistence", test_persistent_mode),
    ]

    tests
        |> map(fn((name, test_fn)) {
            println("Testing " + name + "...")
            let result = test_fn(iso_path)
            (name, result)
        })
        |> filter(fn((_, r)) { !r.passed })
        |> each(fn((name, _)) {
            panic("Test failed: " + name)
        })

    println("All tests passed!")
}

Tests run in QEMU with automated input via VNC scripting.

◉ Release Workflow

  1. Upstream Debian updates merged weekly
  2. Security tool updates merged as released
  3. CI rebuilds ISO on every merge to main
  4. Manual QA on physical hardware
  5. Signed release published to download server

◉ Lessons Learned

NullSec is available on the downloads page. Source code at GitHub.