Kali live images mount a tmpfs overlay by default. Changes do not survive reboot unless you create a persistence partition.
# Assuming Kali is on /dev/sdb1, create a third partition
fdisk /dev/sdb # create sdb3, type 83
mkfs.ext4 -L persistence /dev/sdb3
mkdir /mnt/persist
mount /dev/sdb3 /mnt/persist
echo "/ union" > /mnt/persist/persistence.conf
umount /mnt/persist
Boot with the persistence kernel parameter. Combine with persistence-encryption for LUKS-backed persistence:
cryptsetup --verbose --verify-passphrase luksFormat /dev/sdb3
cryptsetup luksOpen /dev/sdb3 kali-persistence
mkfs.ext4 -L persistence /dev/mapper/kali-persistence
mkdir /mnt/lukspers
mount /dev/mapper/kali-persistence /mnt/lukspers
echo "/ union" > /mnt/lukspers/persistence.conf
umount /mnt/lukspers
cryptsetup luksClose kali-persistence
Boot parameters: persistence persistence-encryption=luks.
persistence.conf with / union makes the entire root writable over the squashfs. Limit scope to /home union or /root union on shared images.
Kali uses tiered metapackages. Install only what you need to avoid bloat on resource-constrained hardware.
| Package | Contents | Approx. size |
|---|---|---|
| kali-linux-core | Base system, no tools | ~800 MB |
| kali-linux-headless | Core + non-GUI tools | ~1.9 GB |
| kali-linux-default | Headless + common GUI tools | ~3.5 GB |
| kali-linux-large | Default + extended tool set | ~9 GB |
| kali-linux-everything | All packaged tools | ~17 GB |
| kali-linux-nethunter | Mobile/NetHunter subset | ~1.1 GB |
Category metapackages (kali-tools-web kali-tools-wireless kali-tools-forensics) let you compose precisely:
apt install kali-linux-headless kali-tools-web kali-tools-wireless
List all metapackages and their dependencies:
apt-cache show kali-linux-everything | grep Depends
# or browse categories:
apt-cache search kali-tools-
Kali ships zsh as default with a minimal config. The recommended baseline:
# Install oh-my-zsh (unattended)
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
# Useful plugins — edit ~/.zshrc
plugins=(git z sudo zsh-autosuggestions zsh-syntax-highlighting)
# Install external plugins
git clone https://github.com/zsh-users/zsh-autosuggestions \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/themes/powerlevel10k
# In ~/.zshrc:
ZSH_THEME="powerlevel10k/powerlevel10k"
# Then configure interactively:
p10k configure
Recommended ~/.tmux.conf settings for offensive work:
set -g default-terminal "tmux-256color"
set -ag terminal-overrides ",xterm-256color:RGB"
set -g history-limit 50000
set -g mouse on
set -g base-index 1
setw -g pane-base-index 1
bind r source-file ~/.tmux.conf \; display "Reloaded"
# Vim-style pane navigation
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# ~/.zshrc or /etc/environment
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin:$HOME/.local/bin:/opt/tools/bin
export PYTHONDONTWRITEBYTECODE=1
export HISTFILESIZE=100000
export HISTSIZE=100000
export SAVEHIST=100000
Kali supports XFCE (default), GNOME, KDE, i3, Sway, and others. Switch with:
apt install kali-desktop-gnome # or kali-desktop-kde, kali-desktop-i3
update-alternatives --config x-session-manager
For a minimal tiling setup (Sway on Wayland):
apt install kali-desktop-sway sway swaylock swayidle waybar wofi
# Copy default config
mkdir -p ~/.config/sway
cp /etc/sway/config ~/.config/sway/config
Programmatic XFCE configuration via xfconf-query — useful for scripted setups:
# Disable compositing (reduces latency on VMs)
xfconf-query -c xfwm4 -p /general/use_compositing -s false
# Set panel to autohide
xfconf-query -c xfce4-panel -p /panels/panel-1/autohide-behavior -s 1
# Enable tap-to-click on touchpad
xfconf-query -c pointers -p /SynPS2_Synaptics_TouchPad/Properties/libinput_Tapping_Enabled -s 1
# Disable screen blanking
xfconf-query -c xfce4-power-manager -p /xfce4-power-manager/dpms-enabled -s false
# Xorg: add to ~/.Xresources
Xft.dpi: 192
# Wayland (Sway): ~/.config/sway/config
output eDP-1 scale 2
# GTK scaling
gsettings set org.gnome.desktop.interface scaling-factor 2
gsettings set org.gnome.desktop.interface text-scaling-factor 1.0
# Qt
export QT_SCALE_FACTOR=2
Kali ships kali-themes. To revert to the official dark palette:
apt install kali-themes kali-wallpapers-2024
# Apply via xfconf (XFCE)
xfconf-query -c xsettings -p /Net/ThemeName -s "Kali-Dark"
xfconf-query -c xsettings -p /Net/IconThemeName -s "Flat-Remix-Blue-Dark"
| Package | Use case |
|---|---|
| linux-image-amd64 | Standard 64-bit (default) |
| linux-image-rt-amd64 | Real-time kernel (RF timing, SDR) |
| linux-image-cloud-amd64 | Cloud/VM optimized (no firmware) |
| linux-image-arm64 | Native arm64 (RPi, Apple M-series Parallels) |
Kali includes patched drivers for monitor mode and packet injection. Confirm:
# Check driver and capabilities
iw phy phy0 info | grep -A10 "Supported interface modes"
# Load rtl8812au (e.g. Alfa AWUS036ACH)
apt install realtek-rtl88xxau-dkms
modprobe 88XXau
# Persist module options
echo "options 88XXau rtw_drv_log_level=0 rtw_power_mgnt=0" \
> /etc/modprobe.d/rtl88xxau.conf
# Blacklist conflicting in-kernel driver
echo "blacklist rtl8xxxu" >> /etc/modprobe.d/blacklist-rtl8xxxu.conf
update-initramfs -u
DKMS modules rebuild automatically on kernel upgrades. Check status:
dkms status
# Rebuild all for current kernel
dkms autoinstall
# /etc/sysctl.d/99-kali.conf
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv4.tcp_timestamps = 0 # reduce OS fingerprinting
kernel.randomize_va_space = 2
vm.swappiness = 10
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
sysctl --system
Kali uses live-build via a wrapper in kali-linux/build-scripts. This is the official, supported method for custom ISOs.
apt install git live-build cdebootstrap curl
git clone https://gitlab.com/kalilinux/build-scripts/live-build-config.git
cd live-build-config
| Path | Purpose |
|---|---|
| kali-config/variant-default/ | Default variant config |
| kali-config/common/hooks/live/ | Shell hooks run inside chroot |
| kali-config/common/includes.chroot/ | Files copied verbatim into chroot |
| kali-config/common/package-lists/ | .list.chroot files for apt |
# Add a package list
echo "gobuster\nferoxbuster\nnuclei" \
> kali-config/variant-default/package-lists/custom.list.chroot
# Inject a dotfile
mkdir -p kali-config/common/includes.chroot/root
cp ~/.zshrc kali-config/common/includes.chroot/root/.zshrc
# kali-config/common/hooks/live/0060-install-tools.hook.chroot
#!/bin/bash
set -e
pip3 install impacket --break-system-packages
go install github.com/ffuf/ffuf/v2@latest
# Build default amd64 ISO (requires root)
./build.sh --variant default --arch amd64
# With verbose output
./build.sh --variant default --arch amd64 2>&1 | tee build.log
Output lands in images/. Expect 30–90 min depending on mirror latency and package count.
qemu-user-static and a compatible binfmt.
Kali is not hardened by default; many services are disabled but not locked down. For deployments beyond a pentest laptop:
# /etc/ssh/sshd_config
PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes
X11Forwarding no
AllowTcpForwarding no
MaxAuthTries 3
LoginGraceTime 20
# /etc/nftables.conf — restrictive workstation baseline
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
tcp dport 22 ct state new accept
}
chain forward { type filter hook forward priority 0; policy drop; }
chain output { type filter hook output priority 0; policy accept; }
}
systemctl enable --now nftables
Kali ships AppArmor disabled. Enable it:
apt install apparmor apparmor-profiles apparmor-utils
# Add to GRUB_CMDLINE_LINUX in /etc/default/grub:
# apparmor=1 security=apparmor
update-grub
systemctl enable apparmor
apt install auditd audispd-plugins
systemctl enable --now auditd
# Basic ruleset
auditctl -w /etc/passwd -p wa -k identity
auditctl -w /etc/sudoers -p wa -k sudoers
auditctl -w /root -p rwa -k root-activity
# /etc/apt/sources.list
deb https://http.kali.org/kali kali-rolling main contrib non-free non-free-firmware
# Offline / airgap mirror (replace hostname)
deb http://mirror.internal/kali kali-rolling main contrib non-free non-free-firmware
Use http.kali.org for automatic GeoDNS resolution. For explicit regional mirrors:
# Check latency to candidate mirrors
curl -s https://http.kali.org/README | head -5
netselect-apt -n 5 -s kali
# /etc/apt/preferences.d/hold-metasploit
Package: metasploit-framework
Pin: version 6.3.*
Pin-Priority: 1001
# Build a local repo from downloaded debs
mkdir -p /srv/localrepo
cp *.deb /srv/localrepo/
cd /srv/localrepo && dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
# Add to sources.list
deb [trusted=yes] file:///srv/localrepo ./
apt install apt-cacher-ng
systemctl enable --now apt-cacher-ng
# On clients, /etc/apt/apt.conf.d/02proxy
Acquire::http::Proxy "http://<cacher-host>:3142";
apt update && apt full-upgrade on a fresh Kali install before any other customization. Rolling release deltas can be large and occasionally break partial upgrade states.