Hardening Ubuntu 24.04 in 2026: the controls that actually matter
I've been running and re-running Ubuntu hardening playbooks since 18.04. Most of what's published online is still a copy of a copy of a 16.04 CIS checklist, with password minlen 14 and a dozen sysctl knobs.
I've been running and re-running Ubuntu hardening playbooks since 18.04. Most of what's published online is still a copy of a copy of a 16.04 CIS checklist, with password minlen 14 and a dozen sysctl knobs that haven't moved the needle since systemd-resolved became the default.
This is the short version of the 24.04 playbook I actually use on production. The full version with the Ansible roles, Lynis baseline, and benchmark numbers is on my site (linked at the bottom).
1. Stop trusting unattended-upgrades exit codes
On 24.04, needrestart 3.6 plus phased updates will silently leave kernel meta-packages in a kept back state. The unit reports success. Your boxes drift.
Minimal fix in /etc/apt/apt.conf.d/50unattended-upgrades:
Then add an assertion you can actually fail CI on:
#!/usr/bin/env bash
set -euo pipefail
running=$(uname -r)
latest=$(apt-cache policy linux-image-generic | awk '/Candidate:/ {print $2}')
if ! dpkg -l "linux-image-${running}" >/dev/null 2>&1; then
echo "Running kernel ${running} no longer installed — reboot pending"; exit 1
fi
echo "OK: kernel ${running}, candidate ${latest}"
2. AppArmor: enforce, don't complain
24.04 ships several profiles in complain mode out of the box. aa-status will happily report them as loaded. Anything in complain is documentation, not enforcement.
Watch out for snap refreshes resetting profiles. I run an apparmor_parser -r sweep nightly via systemd timer.
3. nftables that don't fight Docker
Docker 25 on 24.04 uses iptables-nft by default, so you can finally have one ruleset. The trick is putting your filter rules in a separate table so Docker's chains don't get flushed when you reload.
Leave Docker's nat and filter tables alone. nft list ruleset after docker compose up should still show both your inet filter and Docker's ip filter DOCKER-USER.
4. auditd rules that won't drown you
The CIS auditd ruleset generates roughly 8x more events than you need on a busy host. I strip it down to four categories: identity, time, privileged commands, and module loading.
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k identity
-w /etc/sudoers.d/ -p wa -k identity
-a always,exit -F arch=b64 -S init_module -S finit_module -S delete_module -k modules
-a always,exit -F arch=b64 -S settimeofday -S clock_settime -k time
Measured event volume on a typical app host: ~120 events/hour vs ~1,400 with the stock CIS ruleset.
5. Kernel lockdown is the cheap win
echo 'GRUB_CMDLINE_LINUX="lockdown=integrity"' | sudo tee /etc/default/grub.d/99-lockdown.cfg
sudo update-grub
This blocks unsigned module loading and kexec without breaking your average userland. If you're on ZFS or running out-of-tree drivers, test in staging first — it will refuse to load them unless they're signed against the platform keyring.
What I left out
pam_pwquality complexity knobs (use a password manager, move on)
Disabling IPv6 (just configure it)
tcp_wrappers (gone in 24.04, finally)
Full version
The full playbook with the Ansible roles, the Lynis baseline diff (94 -> 78 hardening index on a default install), and the actual benchmark output from oscap is on linuxsecureops.com:
If you've found something the CIS benchmark gets wrong on 24.04 specifically, I'd genuinely like to hear it — the playbook is versioned in git and I update it when the noble-updates pocket changes behaviour.
How Linux kernel live patching works in 2026 with kpatch, Ubuntu Livepatch, and TuxCare KernelCare. Install commands, comparison table, and audit tips for zero-downtime CVE fixes.
Wolfi vs Distroless vs Alpine base images for 2026 Linux workloads, with CVE benchmarks, apko and cosign pipeline snippets, and real migration examples for Node.js and Python services.
Deploy Keylime continuous remote attestation on Linux with TPM 2.0: registrar, verifier, Rust agent, IMA runtime policies, and revocation webhooks in 2026.