Kali Linux Customization

01 Persistence & overlays

Kali live images mount a tmpfs overlay by default. Changes do not survive reboot unless you create a persistence partition.

Creating a persistence partition (USB)

# 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.

Warning persistence.conf with / union makes the entire root writable over the squashfs. Limit scope to /home union or /root union on shared images.

02 Metapackages

Kali uses tiered metapackages. Install only what you need to avoid bloat on resource-constrained hardware.

PackageContentsApprox. size
kali-linux-coreBase system, no tools~800 MB
kali-linux-headlessCore + non-GUI tools~1.9 GB
kali-linux-defaultHeadless + common GUI tools~3.5 GB
kali-linux-largeDefault + extended tool set~9 GB
kali-linux-everythingAll packaged tools~17 GB
kali-linux-nethunterMobile/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-

03 Terminal environment

Shell: zsh + oh-my-zsh

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

Prompt: Powerlevel10k

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

tmux

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

Environment variables for tooling

# ~/.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

04 Desktop environment

Switching DEs

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

XFCE tweaks

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

HiDPI

# 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

Themes

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"

05 Kernel & modules

Kali kernel variants

PackageUse case
linux-image-amd64Standard 64-bit (default)
linux-image-rt-amd64Real-time kernel (RF timing, SDR)
linux-image-cloud-amd64Cloud/VM optimized (no firmware)
linux-image-arm64Native arm64 (RPi, Apple M-series Parallels)

Module management for wireless

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

DKMS modules rebuild automatically on kernel upgrades. Check status:

dkms status
# Rebuild all for current kernel
dkms autoinstall

sysctl tuning

# /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

06 Live-build ISO customization

Kali uses live-build via a wrapper in kali-linux/build-scripts. This is the official, supported method for custom ISOs.

Setup

apt install git live-build cdebootstrap curl
git clone https://gitlab.com/kalilinux/build-scripts/live-build-config.git
cd live-build-config

Configuration paths

PathPurpose
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

Adding packages and files

# 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

Chroot hooks

# 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

# 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.

Note Nested builds inside a Kali VM work but require the chroot to match the host arch. Cross-arch builds need qemu-user-static and a compatible binfmt.

07 Hardening

Kali is not hardened by default; many services are disabled but not locked down. For deployments beyond a pentest laptop:

SSH

# /etc/ssh/sshd_config
PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes
X11Forwarding no
AllowTcpForwarding no
MaxAuthTries 3
LoginGraceTime 20

Firewall (nftables)

# /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

AppArmor

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

Auditd

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

08 APT & mirrors

Sources

# /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

Regional mirrors

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

Pinning

# /etc/apt/preferences.d/hold-metasploit
Package: metasploit-framework
Pin: version 6.3.*
Pin-Priority: 1001

Offline / custom repository

# 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-cacher-ng (team use)

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";
Note Always run 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.