security hardening

Kali Linux
Hardening

📅 2026-06-05 💻 kali-laptop ⚒ Lynis 3.1.6 👤 kmrlbhr 🔔 Kali Rolling
0
hardening index
0
Warnings
0
Suggestions
+29
Points gained
252
Tests passed
Baseline
59
+ tools
78
+ kernel
86
+ final
88
✓ Firewall active ✓ AppArmor enabled ✓ fail2ban running ✓ auditd enabled ✓ AIDE + SHA512 ✓ rkhunter baselined ✓ GRUB password set ✓ Kernel hardened ⚠ kernel.modules_disabled skipped
00

Timeline

59 / 100 — Baseline
Initial Lynis scan. 3 warnings, 43 suggestions. No firewall, no AppArmor, no fail2ban, missing malware scanner, 14 sysctl values wrong.
78 / 100 — Round 1
Installed ufw, fail2ban, auditd, rkhunter, libpam-pwquality, libpam-tmpdir, needrestart, apt-listbugs, apt-listchanges, debsums. Enabled all services. Applied sysctl kernel values.
86 / 100 — Round 2
Installed AIDE with SHA512, sysstat, acct, unattended-upgrades. Set auditd rules, fail2ban jail.local, login banners, password policy, hashing rounds, umask, /proc hidepid, session timeout.
88 / 100 — Final
Fixed AIDE database, restricted all compilers (cpp, as/assembler, mingw cross-compilers) to root only. Fixed system account home directory permissions. Set GRUB pbkdf2-sha512 password. 0 warnings, 0 suggestions.
01

Install security tools

⚠
SecLists is stored under /usr/share/seclists/ on this system, not /usr/share/wordlists/. rockyou.txt requires extraction: tar -xzf /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt.tar.gz
apt
Install all missing packages
required ▼

Install everything Lynis flagged as missing in one command. This covers firewall, intrusion detection, file integrity, PAM modules, audit tools, and package management utilities.

# Core security tools
apt install ufw fail2ban auditd rkhunter \
  libpam-pwquality libpam-tmpdir \
  needrestart apt-listbugs apt-listchanges \
  debsums apt-show-versions -y

# File integrity + accounting
apt install aide sysstat acct unattended-upgrades -y
02

Enable services

UFW
deny incoming / allow outgoing
AppArmor
MAC framework enabled
fail2ban
jail.local configured
auditd
comprehensive ruleset
svc
Enable and start all services
done ▼
# Firewall — deny all incoming by default
ufw default deny incoming
ufw default allow outgoing
ufw enable

# Security services
systemctl enable auditd   && systemctl start auditd
systemctl enable fail2ban  && systemctl start fail2ban
systemctl enable apparmor  && systemctl start apparmor
systemctl enable sysstat   && systemctl start sysstat
systemctl enable psacct    && systemctl start psacct

# Protect fail2ban config from upgrades
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
systemctl restart fail2ban
03

Kernel hardening (sysctl)

16 kernel parameters hardened covering memory protection, BPF JIT hardening, ptrace scope, network redirect blocking, and martian packet logging. Note: kernel.modules_disabled=1 intentionally skipped — breaks Kali drivers.

sys
Apply sysctl values
36/37 OK ▼
cat >> /etc/sysctl.conf << 'EOF'
# Kernel hardening
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
kernel.sysrq = 0
kernel.unprivileged_bpf_disabled = 1
kernel.yama.ptrace_scope = 1
dev.tty.ldisc_autoload = 0
fs.protected_fifos = 2

# Network hardening
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.core.bpf_jit_harden = 2
EOF

sysctl -p
⚠
sysctl values revert if VPN reconnects. Run sysctl -p again to re-apply.
04

Authentication hardening

pam
Password policy & aging
done ▼
# PAM password strength (12 char min, complexity required)
cat > /etc/security/pwquality.conf << 'EOF'
minlen = 12
dcredit = -1
ucredit = -1
ocredit = -1
lcredit = -1
maxrepeat = 3
EOF

# Password aging
sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS\t90/' /etc/login.defs
sed -i 's/^PASS_MIN_DAYS.*/PASS_MIN_DAYS\t1/'  /etc/login.defs
sed -i 's/^PASS_WARN_AGE.*/PASS_WARN_AGE\t7/'  /etc/login.defs

# SHA512 hashing rounds & umask
echo "SHA_CRYPT_MIN_ROUNDS 65536"  >> /etc/login.defs
echo "SHA_CRYPT_MAX_ROUNDS 655360" >> /etc/login.defs
echo "UMASK           027"         >> /etc/login.defs
echo "umask 027" >> /etc/bash.bashrc
echo "umask 027" >> /etc/profile

# Session timeout (15 min)
echo "TMOUT=900"        >> /etc/profile
echo "readonly TMOUT"  >> /etc/profile
echo "export TMOUT"    >> /etc/profile

# Apply expiry to accounts
chage --maxdays 90 --mindays 1 --warndays 7 root
chage --maxdays 90 --mindays 1 --warndays 7 kmrlbhr
05

Auditd rules

aud
Comprehensive audit ruleset
done ▼

Audit rules covering identity changes, privilege escalation, SSH config, network config, cron jobs, and kernel module loading.

cat > /etc/audit/rules.d/hardening.rules << 'EOF'
-D
-b 8192
-f 1

# Identity changes
-w /etc/passwd  -p wa -k identity
-w /etc/shadow  -p wa -k identity
-w /etc/group   -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers    -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers

# Privilege escalation
-w /var/log/auth.log -p wa -k auth
-w /bin/su           -p x  -k priv_esc
-w /usr/bin/sudo     -p x  -k priv_esc

# SSH & network
-w /etc/ssh/sshd_config -p wa -k ssh
-w /etc/hosts           -p wa -k network
-w /etc/network/        -p wa -k network

# Cron
-w /etc/crontab  -p wa -k cron
-w /etc/cron.d/  -p wa -k cron

# Kernel modules
-w /sbin/insmod  -p x -k modules
-w /sbin/rmmod   -p x -k modules
-w /sbin/modprobe -p x -k modules
EOF

augenrules --load
systemctl restart auditd
06

File integrity monitoring

aid
AIDE — SHA512 baseline
done ▼

Initialize AIDE with explicit SHA512 checksums. The database build takes 2–13 minutes depending on filesystem size.

# Override default checksum to SHA512 explicitly
sed -i 's/^Checksums = H/Checksums = sha512/' /etc/aide/aide.conf
grep "^Checksums" /etc/aide/aide.conf  # verify

# Build database (~2-13 min)
aide -c /etc/aide/aide.conf --init
cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db

# Verify database exists
ls -lh /var/lib/aide/aide.db
rkh
rkhunter — rootkit baseline
done ▼
# Update definitions (may fail offline — ok)
rkhunter --update

# Build file properties baseline
rkhunter --propupd
07

Filesystem hardening

fs
Permissions, /proc, cron dirs
done ▼
# Home directory permissions
chmod 750 /home /home/kmrlbhr
chmod 700 /root

# System account home dirs (found by checking getent passwd)
chmod 750 /usr/sbin /usr/games /var/cache/man
chmod 750 /var/mail /var/backups /run/sshd
chmod 750 /var/lib/misc /var/lib/colord
chmod 750 /var/lib/saned /var/lib/postgresql
chmod 750 /var/lib/openvpn/chroot

# Cron directory permissions
chmod 700 /etc/cron.d /etc/cron.daily /etc/cron.hourly
chmod 700 /etc/cron.weekly /etc/cron.monthly
chmod 600 /etc/crontab
chmod 750 /etc/sudoers.d
chmod 600 /etc/ssh/sshd_config

# Hide /proc from other users
echo "proc /proc proc defaults,hidepid=2 0 0" >> /etc/fstab
mount -o remount,hidepid=2 /proc

# debsums weekly cron job
sed -i 's/^CRON_CHECK=.*/CRON_CHECK=weekly/' /etc/default/debsums
08

Network & device hardening

mod
Disable unused protocols & devices
done ▼
cat >> /etc/modprobe.d/hardening.conf << 'EOF'
# Unused network protocols
install dccp /bin/false
install sctp /bin/false
install rds  /bin/false
install tipc /bin/false

# Storage devices
install usb-storage   /bin/false
install firewire-ohci /bin/false
EOF
dns
Hardened DNS + immutable resolv.conf
done ▼
# Remove immutable flag if set
chattr -i /etc/resolv.conf

cat > /etc/resolv.conf << 'EOF'
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 1.1.1.1
EOF

# Lock from being overwritten by NetworkManager/DHCP
chattr +i /etc/resolv.conf
09

Boot security

✓
Using --unrestricted flag so normal booting still works without entering the GRUB password. Only editing boot entries requires authentication.
grb
GRUB pbkdf2-sha512 password
done ▼
# Step 1: Generate hash (interactive)
grub-mkpasswd-pbkdf2
# Copy the full hash that starts with grub.pbkdf2.sha512...

# Step 2: Add to GRUB
cat >> /etc/grub.d/40_custom << 'EOF'
set superusers="root"
password_pbkdf2 root <PASTE_YOUR_HASH_HERE>
EOF

# Step 3: Allow normal boot without password
sed -i 's/^CLASS=.*/CLASS="--class gnu-linux --class gnu --class os --unrestricted"/' \
  /etc/grub.d/10_linux

# Step 4: Apply
update-grub
ban
Login banners
done ▼
cat > /etc/issue << 'EOF'
WARNING: Unauthorized access to this system is prohibited.
All activity is monitored and logged. Disconnect immediately.
EOF

cp /etc/issue /etc/issue.net
10

Compiler hardening

Lynis checks as, cc, gcc, and clang — following symlinks to real binaries. The GNU assembler (as) was the final culprit along with mingw cross-compilers.

gcc
Restrict all compilers to root only
done ▼
# Restrict cpp (follows symlink chain to real binary)
chmod o-rx /usr/bin/cpp
chmod o-rx /usr/bin/cpp-15
chmod o-rx /usr/bin/x86_64-linux-gnu-cpp-15

# Restrict as/assembler (Lynis treats as compiler)
chmod o-rx /usr/bin/as
chmod o-rx /usr/bin/x86_64-linux-gnu-as

# Restrict mingw cross-compilers
find /usr/bin -name "*mingw*cpp*" \
              -o -name "*mingw*gcc*" | \
  xargs chmod o-rx 2>/dev/null

find /etc/alternatives -name "*mingw*cpp*" \
                        -o -name "*mingw*gcc*" | \
  xargs chmod o-rx 2>/dev/null

# Verify — should show r-x--- (750) for all
ls -la /usr/bin/as /usr/bin/cpp /usr/bin/x86_64-linux-gnu-as
✓
Root can still compile normally. This only restricts non-root users from running compilers — safe for a pentest machine where you operate as root.
11

Intentionally skipped

⚠
88/100 is the maximum achievable score on a functional Kali pentest laptop without a full reinstall. The remaining 12 points require changes that would break the system or require repartitioning.
  • ✗
    kernel.modules_disabled=1 KRNL-6000
    Setting to 1 after boot prevents loading any kernel modules. Breaks network adapters, USB devices, Kali drivers, and most offensive tools. Incompatible with pentesting.
  • ✗
    Separate /home partition FILE-6310
    Requires full disk repartitioning and OS reinstall. Not feasible on a working machine mid-engagement.
  • ✗
    Separate /var partition FILE-6310
    Same — requires reinstall. /var contains logs, databases, and package cache; moving it live risks corruption.
  • —
    External log host LOGG-2154
    No remote syslog server available. Would require infrastructure setup outside scope of this engagement.
  • —
    Automation tooling TOOL-5002
    Chef/Puppet/Ansible not relevant for a standalone pentest laptop.
12

Full checklist

Security services

  • +UFW firewall (deny in / allow out)
  • +fail2ban + jail.local
  • +AppArmor MAC framework
  • +auditd + comprehensive rules
  • +rkhunter (baseline created)
  • +AIDE + SHA512 database
  • +sysstat + process accounting
  • +unattended-upgrades

Kernel & network

  • +kernel.dmesg_restrict=1
  • +kernel.kptr_restrict=2
  • +kernel.sysrq=0
  • +kernel.yama.ptrace_scope=1
  • +net BPF JIT harden=2
  • +IP redirects blocked
  • +Martian logging enabled
  • +Reverse path filtering=1

Authentication

  • +PAM pwquality (minlen=12)
  • +libpam-tmpdir enabled
  • +Password aging (90/1/7)
  • +SHA512 hashing rounds 65536
  • +Umask 027
  • +Session timeout 900s
  • +Account expiry set
  • +sudoers.d permissions

System & boot

  • +GRUB pbkdf2-sha512 password
  • +Login banners set
  • +USB storage disabled
  • +FireWire disabled
  • +dccp/sctp/rds/tipc blocked
  • +/proc hidepid=2
  • +Compilers root-only
  • +Home dir perms fixed
kmrlbhr  •  2026-06-05  •  Lynis 3.1.6  •  88/100  •  0 warnings  •  0 suggestions