Kpatch Live Kernel Patching on a VPS: Limits, Verification, and Automation

A kernel security update normally means a reboot, and a reboot on a VPS means dropped connections, restarted services, and a window where nothing is serving traffic. Live patching removes that trade-off for the subset of CVEs that can be fixed by replacing a function body in memory. This article covers what Kpatch can and cannot patch, how to verify a live patch actually took effect, and how to automate the workflow so security updates land without a maintenance window. The same reasoning applies to fleet-wide security work such as SSH key rotation across a VPS fleet — the value is in the routine, not the one-off.

How Live Patching Works Under the Hood

Kpatch operates at function granularity. When a CVE is fixed upstream, the change usually touches one or two functions. Kpatch compiles a kernel module containing only the corrected versions, then uses ftrace to intercept calls to the original functions and redirect them to the new implementations. The kernel never stops; running processes never notice that the code beneath them changed.

This is powerful but bounded. Patches that modify data structures, change function signatures, or touch initialization code cannot be applied live. In practice, function-body fixes cover roughly 70% of kernel CVEs — a large majority, but not all. You still eventually need a real reboot for the remainder, so live patching is a delay mechanism, not an alternative to rebooting forever.

Confirming Your Kernel Supports It

Before installing anything, check whether the running kernel was built with live patching support and whether the required tracepoints are compiled in:

uname -r
grep CONFIG_LIVEPATCH /boot/config-$(uname -r)
mount | grep tracefs
ls /sys/kernel/livepatch 2>/dev/null

CONFIG_LIVEPATCH=y is required. A missing /sys/kernel/livepatch directory usually means the module is not loaded yet rather than unsupported — load it and re-check.

Installing Kpatch on Ubuntu and RHEL-family Hosts

On RHEL, Rocky, and AlmaLinux the tooling ships in the base repositories and integrates with the package manager:

sudo dnf install kpatch kpatch-dnf -y
sudo kpatch list

On Ubuntu and Debian the ecosystem differs — Canonical publishes livepatch through the ubuntu-advantage (formerly canonical-livepatch) service rather than as freely distributed kpatch modules. The command surface is the same idea:

sudo snap install canonical-livepatch
sudo canonical-livepatch enable <token>
sudo canonical-livepatch status --verbose

Do not assume kpatch is available for every kernel release on a given distribution. Live patches are built against specific kernel versions; if your VPS provider pins a custom kernel, patches may lag or be unavailable. Check before committing to the workflow.

Verifying a Patch Actually Applied

Installing the module and having it actually patch the running kernel are two different things. The authoritative check reads the livepatch sysfs state, where each patch reports enabled or transition:

sudo kpatch list
cat /sys/kernel/livepatch/*/enabled
dmesg | grep -i kpatch

enabled = 1 means the patch is active for new calls. A value stuck at 0 with a transition message means the kernel is waiting for in-flight executions of the old function to drain before switching — this is normal and usually clears within seconds.

Automating the Workflow

The point of live patching is to make kernel security updates routine. Wire it into the update path so patches apply on a schedule without interaction. For RHEL-family hosts:

sudo systemctl enable --now kpatch.service
dnf install kpatch-dnf
kpatch-dnf enable

kpatch-dnf enable hooks the patch modules into normal package upgrades, so a dnf update applies live patches as they ship. For periodic unattended updates, a systemd timer or cron job running dnf -y update on a maintenance schedule completes the loop. This is the same class of automation as unattended-upgrades failure modes on Debian/Ubuntu, where deferred reboots silently accumulate — the failure mode to watch for here is live patches that stack up while the underlying reboot debt grows.

The Reboot Debt Problem

Live patching can lull you into never rebooting. That is a trap. Patches that cannot be applied live still accumulate, and a kernel that has run for 300 days with dozens of un-appliable patches pending is fragile. Track reboot debt explicitly:

cat /var/run/reboot-required 2>/dev/null
sudo kpatch list | grep -c '\[enabled\]'
uname -r && rpm -q kernel | tail -1

When the installed kernel package version exceeds the running uname -r, a reboot is pending. Schedule it deliberately during a low-traffic window instead of discovering it mid-incident.

Rollback When a Patch Misbehaves

Live patches occasionally cause regressions — a rare race, a wrong fix, an interaction with another module. Because the patch is a loadable module, you can disable it without rebooting, which is the whole point:

echo 0 | sudo tee /sys/kernel/livepatch/<patch>/enabled
sudo kpatch unload <patch>

Writing 0 to the enabled file starts a reverse transition: new calls go to the original function while in-flight ones drain, then the patch unloads cleanly. This is dramatically faster and less disruptive than rebooting into the previous kernel, but it also means a broken live patch can be backed out in seconds — a safety net you do not get with a conventional kernel upgrade.

Monitoring Live Patch State Over Time

Live patches are invisible in normal monitoring until something depends on them. Add a lightweight check to your existing exporter or a cron probe so you catch a patch that failed to apply or silently unloaded:

#!/bin/sh
# /usr/local/bin/kpatch-check.sh — alert if any patch is not enabled for <patch> in $(ls /sys/kernel/livepatch); do
  [ "$(cat /sys/kernel/livepatch/$patch/enabled)" = "1" ] || echo "$patch not enabled"
done

Feed that script’s output into your alerting; a patch reporting transition indefinitely, or disappearing from sysfs after a kernel upgrade, is exactly the silent failure that leaves a host believing it is patched when it is not.

When Live Patching Is the Wrong Choice

Live patching is not universal. On kernels the vendor does not build patches for, on hosts where the affected subsystem is a data-structure change, or on machines that can tolerate a two-second reboot anyway, the effort may exceed the benefit. A stateless worker behind a load balancer that drains and restarts cleanly in seconds — the pattern covered in zero-downtime service reloads with connection draining — gains little from live patching, because it already has no meaningful downtime. Reserve the mechanism for stateful, single-instance, or high-availability-sensitive hosts where a reboot genuinely costs money.

The Takeaway

Live patching is a legitimate, well-documented mechanism for applying about 70% of kernel security fixes without downtime — provided you verify patches actually reach enabled state, check whether your specific kernel build is even supported, and treat reboots as deferred rather than eliminated. Automate the patch path, monitor reboot debt, and schedule the inevitable real reboots on your terms. Used that way, Kpatch meaningfully shortens a VPS’s exposure to known kernel CVEs.

Leave a Reply