The Server That Nobody Is Allowed to Touch
You know the one. It’s running some critical service. It was set up by someone who left the company two years ago. The documentation consists of a sticky note that says “don’t restart it.” The uptime counter has crossed into four digits. There’s an informal office understanding that if this server goes down, you are personally responsible for whatever follows.
This is a real situation. And it happens because rebooting servers is genuinely risky — services need to restart, dependencies need to come back up in the right order, sometimes things don’t come back at all. So people avoid it. Which means kernel vulnerabilities go unpatched for months or years.
Kernel live patching is the technology that breaks this deadlock. Patch the running kernel without a reboot. Apply CVE fixes while your server keeps serving.
Why Kernel Updates Normally Require Reboots
The kernel isn’t an application you can restart independently. It’s the foundation everything else runs on. When you install a kernel update, you’re replacing that foundation — but you can’t swap out the foundation while the building is standing on it.
The traditional flow: install new kernel packages → schedule maintenance window → reboot → new kernel loads → everything hopefully comes back up. The reboot is unavoidable because the running kernel image is loaded into memory and in active use.
Live patching works around this by modifying the kernel in memory, redirecting function calls from vulnerable code to patched replacement functions, without ever touching the stored kernel image on disk or requiring a restart.
How Live Patching Actually Works
The mechanism is clever. When a live patch is applied:
- A new kernel module is loaded containing the patched version of vulnerable functions
- The live patching infrastructure (built into the kernel since 4.0) intercepts calls to the vulnerable function
- Using
ftrace(the kernel’s function tracer) and some clever trampolining, the old function is redirected to the new patched version - Callers continue to work — they just end up at the patched code instead
This is function-level surgery on a running kernel. It works well for security patches because CVEs typically involve fixing a specific function’s behavior — a bounds check, a null pointer dereference, a race condition. Patching that one function fixes the vulnerability.
What it can’t do: data structure changes, changes to how the kernel initializes, patches that require processes to restart to pick up new behavior. Not every CVE can be live-patched.
The Live Patching Ecosystem
Three main options depending on your distribution:
| Solution | Distribution | Cost | Notes |
|---|---|---|---|
| Canonical Livepatch | Ubuntu | Free (≤5 machines), paid | Integrated with Ubuntu Pro |
| kpatch | RHEL/CentOS/Fedora | Part of RHEL subscription | Red Hat’s implementation |
| kernel upstream livepatch | Any (manual) | Free | DIY, requires patch building |
| KernelCare | Any | Commercial | Third-party, broad distro support |
Setting Up Canonical Livepatch on Ubuntu
Ubuntu’s Livepatch is the friendliest option for getting started. You get free coverage for up to 5 machines — enough for a home lab or small deployment.
Step 1: Get a free Ubuntu Pro token
Go to ubuntu.com/pro and create a free personal account. You’ll get a token that covers up to 5 machines.
Step 2: Attach your machine to Ubuntu Pro
sudo apt install ubuntu-advantage-tools
sudo pro attach YOUR_TOKEN_HERE
Step 3: Enable Livepatch
sudo pro enable livepatch
That’s it. Livepatch is now active and will automatically apply kernel patches as they become available.
Check the current status:
sudo pro status
canonical-livepatch status
You’ll see output like:
kernel: 5.15.0-97-generic
fully-patched: true
version: "10.5.1"
patches:
- patched: true
name: lp-CVE-2024-1086
title: Kernel privilege escalation
Verify it’s actually working:
livepatch status --verbose
Look for fully-patched: true. If patches are pending, they typically apply within minutes.
Setting Up kpatch on RHEL/CentOS
kpatch is Red Hat’s implementation and ships as part of RHEL subscriptions. On RHEL 8/9 or compatible:
Install kpatch:
sudo dnf install kpatch kpatch-dnf
Enable automatic updates:
sudo systemctl enable --now kpatch
Apply available patches:
# List available patches
sudo kpatch list
# Install kpatch-patch packages (RHEL subscriptions required)
sudo dnf install "kpatch-patch-$(uname -r | sed 's/-/_/g')"
Check patch status:
sudo kpatch list
Output shows loaded patches and which CVEs they address.
For CentOS Stream or Rocky Linux, the ecosystem is less mature — you’re looking at third-party solutions like KernelCare or building patches yourself.
Building Your Own Patches with kpatch-build
If you’re adventurous (or running something that’s not RHEL/Ubuntu), you can build live patches yourself:
# Install kpatch-build
git clone https://github.com/dynup/kpatch
cd kpatch
make
sudo make install
# Build a patch (you need the source patch and kernel source)
kpatch-build -t vmlinux path/to/fix.patch
This generates a .ko module you can load:
sudo kpatch load kpatch-fix.ko
This is not recommended for production unless you really know what you’re doing. Building kernel patches requires the exact matching kernel source, build environment, and a good understanding of what the patch actually does.
What Can and Can’t Be Live-Patched
Understanding limitations prevents nasty surprises.
Good candidates for live patching:
- Function-level security fixes
- Bounds checking improvements
- Null pointer dereference fixes
- Race condition fixes in specific functions
- Most CVEs that don’t require structural changes
Cannot be live-patched:
- Changes to kernel data structures (struct layout changes)
- Changes to how the kernel boots or initializes
- Patches requiring filesystem remounting
- Some complex race conditions that require all callers to restart
- Patches to heavily inlined code paths
Canonical and Red Hat both maintain lists of which CVEs can and cannot be addressed via live patching. A given kernel release might have 20 security issues — live patching might cover 15 of them.
You Still Need to Reboot Eventually
Let’s be honest about what live patching is and isn’t.
Live patching is not “never reboot again.” It’s “defer reboots to a scheduled maintenance window instead of emergency patching.” This is a meaningful and valuable distinction, but it’s not magic.
Reasons you still need periodic reboots:
- Patches that can’t be live-patched
- Hardware firmware updates
- Kernel version upgrades (live patching covers a specific kernel version)
- Memory leaks in long-running kernels
- Accumulated state that needs clearing
The recommended pattern:
- Use live patching to maintain security coverage between maintenance windows
- Schedule regular (quarterly? monthly?) maintenance windows for full reboots
- Test your startup procedures so when you do reboot, you’re not surprised
- The 847-day uptime becomes a 90-day uptime, which is still impressive but survivable
Automating the Reboot You’ve Been Avoiding
For servers that genuinely can be rebooted (most of them, if you have proper startup automation):
# /etc/cron.d/kernel-reboot
# Reboot on the first Sunday of each month at 3am if a new kernel is installed
0 3 * * 0 root [ -f /var/run/reboot-required ] && /sbin/shutdown -r now
Or with systemd:
# /etc/systemd/system/scheduled-reboot.service
[Unit]
Description=Scheduled reboot if kernel update pending
ConditionPathExists=/var/run/reboot-required
[Service]
Type=oneshot
ExecStart=/sbin/shutdown -r +1 "Scheduled maintenance reboot"
# /etc/systemd/system/scheduled-reboot.timer
[Unit]
Description=Run scheduled reboot check weekly
[Timer]
OnCalendar=Sun *-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
Live patching handles the urgent CVEs. Scheduled reboots handle the accumulated technical debt. You sleep through the night instead of getting paged at 2am.
Monitoring Patch Status
Don’t set it and forget it. Monitor whether patches are actually applying:
# Quick check script
#!/bin/bash
STATUS=$(canonical-livepatch status 2>/dev/null | grep "fully-patched" | awk '{print $2}')
if [ "$STATUS" != "true" ]; then
echo "WARNING: System not fully patched"
canonical-livepatch status
exit 1
fi
echo "OK: Kernel fully live-patched"
Integrate this into your monitoring stack. A server where live patching silently stopped working is worse than a server where you know patching isn’t happening.
# Check patch application history
journalctl -u snapd --since "7 days ago" | grep -i livepatch
The Philosophical Win
Beyond the technical mechanics, live patching represents a shift in how you think about security updates. The traditional choice was: accept the risk of staying on a vulnerable kernel, or accept the risk of rebooting and possibly breaking things. Neither is a good answer.
With live patching, you can apply the security fix immediately while deferring the reboot to a time when you’re prepared for it — maintenance window scheduled, runbooks reviewed, team standing by. The server that never reboots becomes the server that reboots on schedule with proper ceremony instead of in a 3am panic.
That 847-day uptime server? It should probably just be rebooted at this point. But now you can patch it while you plan the reboot, instead of having to choose between vulnerability and chaos.