Install in three commands
Every repo follows the same shape: clone, optionallydry-run to preview the symlink plan, thenbootstrap. Core is vendored, so a clone is self-contained — no submodule flags. Pick your platform below.
Not ready to install?Launch the Kali environment in your browser (opens in a new tab) — a Codespace boots straight into the offensive shell, nothing to clone.
macOS
Apple Silicon or Intel. Homebrew does the heavy lifting; Core is vendored, so a clone is ready to go.
Clone the repo
The Core layer is already vendored under core/ — no submodule flags.
$ git clone https://github.com/dotgibson/dotfiles-MacBook ~/dotfiles-MacBook $ cd ~/dotfiles-MacBookPreview the plan (optional)
A dry run prints every symlink it would create and changes nothing.
$ ./bootstrap.sh --links-only --dry-runProvision + wire
Homebrew, brew bundle, then symlinks. Idempotent — re-run any time.
$ ./bootstrap.sh $ exec zshOptional system prefs
Apply the opt-in macOS defaults (may require a logout).
$ ./bootstrap.sh --macos-defaults
Windows
PowerShell 7 + Developer Mode (or run elevated) so symlinks work. The host layer only — WSL distros configure themselves.
One-line bootstrap
Clones the repo and runs the installer. Needs git and pwsh 7+.
PS> irm https://raw.githubusercontent.com/dotgibson/dotfiles-Windows/main/bootstrap.ps1 | iexOr install manually
Clone, then run the installer. -DryRun previews everything; -SkipPackages only re-wires links.
PS> git clone https://github.com/dotgibson/dotfiles-Windows.git PS> cd dotfiles-Windows PS> .\install.ps1Finish up
Open a new PowerShell window, set git identity, and apply mirrored WSL networking.
# set name/email in ~/.gitconfig.local, then: PS> wsl --shutdown
Offense (role layer)
The offensive role layer, stacked on an OS-native layer rather than replacing one. Kali is the box it is built for, and dotfiles-Debian provisions that — so this is two repos, in order. It installs nothing by default. Engagement data never lives in the repo.
Install the OS-native layer first
dotfiles-Debian covers Ubuntu, Debian and Kali. Skip this step only if you already run one of the fleet’s OS layers.
$ git clone https://github.com/dotgibson/dotfiles-Debian ~/dotfiles-Debian $ ~/dotfiles-Debian/bootstrap.shClone the role layer
$ git clone https://github.com/dotgibson/dotfiles-Offense ~/dotfiles-Offense $ cd ~/dotfiles-OffenseWire it, and see what you have
The default run creates the symlinks and reports which offensive tools are on $PATH, installed but unreachable, or missing. It installs nothing.
$ ./bootstrap.sh $ exec zshInstall the tool stack (opt-in)
On Kali this is apt from install/offensive-packages.txt. On any other Debian-family box it is a smaller portable subset via pipx and go — the rest of that list is Kali-packaged.
$ ./bootstrap.sh --installApply WSL networking
Running Kali under WSL2? It is NAT’d — a listener isn’t reachable from your LAN until you enable mirrored networking on the Windows side. The example file ships in dotfiles-Debian.
# drop wsl/windows.wslconfig.example at %UserProfile%\.wslconfig, then from Windows: $ wsl.exe --shutdown
Defense (role layer)
The defensive role layer — detection engineering and investigation, stacked on an OS-native layer rather than replacing one. Genuinely distro-agnostic: the heavy stack is containers, so you do not need Security Onion or any dedicated blue-team distro. It installs nothing. Case data never lives in the repo.
Install the OS-native layer first
Any of the fleet’s OS layers works — this repo owns no package manager, clipboard or paths. Skip this step if you already run one.
$ git clone https://github.com/dotgibson/dotfiles-Fedora ~/dotfiles-Fedora $ ~/dotfiles-Fedora/bootstrap.shClone the role layer
$ git clone https://github.com/dotgibson/dotfiles-Defense ~/dotfiles-Defense $ cd ~/dotfiles-DefenseWire it, and see what you have
The default run creates the symlinks, adds the defense stage to the loader, and probes for the forensics tools and Docker. It installs nothing. Use --dry-run first if you want the plan without the changes.
$ ./bootstrap.sh $ exec zshBring up the detection lab (opt-in)
The blue stack runs in containers from docker/detection-lab.compose.yml — siemup starts it detached, siemdown tears it down. Both need Docker; they are HAVE_*-guarded, so they simply say so when it is missing.
$ siemup # ... and when you are done: $ siemdownOpen a case
mkcase scaffolds an investigation under ~/cases — outside the repo by design, exactly as dotfiles-Offense keeps engagements in ~/engagements. Version-controlled detection content (Sigma, Sysmon, Zeek/Suricata, SIEM) lives under detections/.
$ mkcase suspicious-powershell
Linux distros
Fedora is the template; Arch, Debian/Ubuntu/Kali, openSUSE, Alpine, and Gentoo are stamped from it — same structure every time, only the package manager and a few distro quirks change. Pick the repo for your distro; the flow below is identical across all of them. Debian/Ubuntu is the one with a twist: it targets a frozen LTS, so it installs more from pinned upstream assets than the rest.
Clone your distro’s repo
Swap Fedora for Arch, Debian, openSUSE, Alpine, or Gentoo. Core is already vendored under core/, so the clone is self-contained.
$ git clone https://github.com/dotgibson/dotfiles-Fedora ~/dotfiles-Fedora $ cd ~/dotfiles-FedoraPreview the plan (optional)
A dry run prints every planned action and changes nothing — every distro repo supports it, and on every one provisioning is skipped rather than faked, while the host probe still runs. Adding --links-only narrows the preview to the symlinks, leaving out both the package manager and the probe.
$ ./bootstrap.sh --links-only --dry-runProvision + wire
Installs the distro package layer, then symlinks. Idempotent — re-run any time. exec zsh to land in the new shell.
$ ./bootstrap.sh $ exec zshPer-distro flags
Fedora / openSUSE: --no-flatpak skips Flatpak. Gentoo: --no-sync skips the slow emerge --sync on re-runs. Arch: a manual/minimal box needs the stage-0 prep in SETUP.md first (git, sudo, a UTF-8 locale). Alpine: run as root or with doas; enable the community repo. Debian/Ubuntu: the same repo also covers Kali rolling — --no-upgrade keeps apt-get update but skips full-upgrade, --no-unattended leaves automatic security updates off, and --force-os is needed on other derivatives like Mint or Pop!_OS.
NixOS
The one declarative host. nix owns the package set, PATH and the login-shell declaration (nix/nixos.nix + nix/home.nix); bootstrap.sh installs nothing, never escalates, and only wires the links. So the order inverts: nix first, bootstrap last.
Clone the repo
Clone before anything else — the next step imports a module from this checkout. Core is already vendored under core/.
$ git clone https://github.com/dotgibson/dotfiles-NixOS ~/dotfiles-NixOSRebuild the system
Import ~/dotfiles-NixOS/nix/nixos.nix from your configuration.nix, and set users.users.<you>.shell = pkgs.zsh there — the bootstrap never runs chsh. On channels, add nixos-25.05 and home-manager release-25.05 first (nix/README.md); flake users import the same modules and skip that.
$ sudo nixos-rebuild switchApply the home profile
The package set, PATH and tpm come from nix/home.nix. It deliberately declares no home.file or programs.zsh — the bootstrap owns those links, and two owners deadlock activation.
$ home-manager switchOnly now, the links
Wires Core + the NixOS layer. --dry-run previews; --links-only also skips the report-only host probe.
$ cd ~/dotfiles-NixOS $ ./bootstrap.sh $ exec zsh