Rebooting a production VPS for every kernel security update is not sustainable. Each reboot drops connections, interrupts services, and risks data inconsistency. Kpatch is an open-source tool that patches a running kernel in memory, applying security fixes without a restart. Here is how to set it up, verify it works, and automate it on your VPS.
What Kpatch Actually Does
Kpatch works at the function level. When a security vulnerability is patched upstream, the fix usually modifies one or two functions. Kpatch compiles a kernel module containing only the corrected versions of those functions. At load time, the kpatch core intercepts calls to the old functions using ftrace and redirects them to the new implementations. The kernel never stops running, and processes are unaware that the code underneath them changed.
This approach has limits. Patches that modify data structures, change function signatures, or touch initialization code cannot be applied live. Kpatch handles the most common case — a logic bug or buffer overflow fixed by swapping in a corrected function body — and that covers roughly 70% of kernel CVEs.
Checking Kernel Compatibility
First, confirm your kernel was built with live patching support. Most VPS images from Ubuntu 22.04, Debian 12, Rocky Linux 9, and Fedora 38 onward include it by default.
# Quick check on any system
grep CONFIG_LIVEPATCH /boot/config-$(uname -r)
# Expected output:
# CONFIG_LIVEPATCH=y
# If the config file is not in /boot, try /proc
grep CONFIG_LIVEPATCH /proc/config.gz 2>/dev/null || \
zcat /proc/config.gz 2>/dev/null | grep CONFIG_LIVEPATCH
If live patching is not enabled, you need a kernel upgrade and a single reboot to get there. This is a one-time cost.
Installing Kpatch on Ubuntu and Debian
sudo apt update
sudo apt install kpatch kpatch-build -y
# Verify the tools are installed
kpatch --version
# Check that the kpatch kernel module loaded
lsmod | grep kpatch
On RHEL-based systems, install from EPEL:
sudo dnf install epel-release -y
sudo dnf install kpatch kpatch-dnf -y
Applying a Live Patch
Distribution repositories ship pre-built kpatch modules alongside kernel security updates. When you install a kernel update, the package manager also places a live patch module in /usr/lib/kpatch/<kernel-version>/. Loading it is a single command:
# List available patches for your running kernel
ls /usr/lib/kpatch/$(uname -r)/*.ko 2>/dev/null
# Load a specific patch
sudo kpatch load /usr/lib/kpatch/$(uname -r)/CVE-2024-12345.ko
# Verify the patch is active
sudo kpatch list
# Output: Loaded patch modules:
# kpatch_CVE_2024_12345 [enabled]
Building a Custom Patch from Source
If your distribution does not ship a pre-built module for a specific CVE, you can build one yourself. This requires the kernel source or debug symbols for your exact kernel version.
# Install build dependencies
sudo apt install linux-headers-$(uname -r) build-essential elfutils libelf-dev -y
# Create a patch file from the CVE fix
# Example: simple fix for a kernel function
cat > /tmp/cve-fix.patch << 'EOF'
diff --git a/kernel/example.c b/kernel/example.c
--- a/kernel/example.c
+++ b/kernel/example.c
@@ -42,6 +42,8 @@
int vulnerable_function(void *data) {
+ if (!data)
+ return -EINVAL;
return do_work(data);
}
EOF
# Build the kpatch module
sudo kpatch-build -t vmlinux /tmp/cve-fix.patch \
--vmlinux /usr/lib/debug/boot/vmlinux-$(uname -r)
# The output is kpatch-cve-fix.ko in the current directory
sudo kpatch load ./kpatch-cve-fix.ko
Automating Patch Application with Systemd
The safest approach is to automatically apply any available live patches on boot and periodically check for new ones:
#!/bin/bash
# /usr/local/sbin/apply-kpatch.sh
# Load all available kpatch modules for the running kernel
PATCH_DIR="/usr/lib/kpatch/$(uname -r)"
if [ ! -d "$PATCH_DIR" ]; then
exit 0
fi
for patch in "$PATCH_DIR"/*.ko; do
[ -f "$patch" ] || continue
name=$(basename "$patch" .ko)
if ! kpatch list 2>/dev/null | grep -q "$name"; then
logger -t kpatch "Loading patch: $name"
kpatch load "$patch"
fi
done
# /etc/systemd/system/kpatch-apply.service
[Unit]
Description=Apply kernel live patches
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/apply-kpatch.sh
RemainAfterExit=no
# /etc/systemd/system/kpatch-apply.timer
[Unit]
Description=Daily kernel live patch check
[Timer]
OnCalendar=daily
OnBootSec=60
Persistent=true
[Install]
WantedBy=timers.target
sudo chmod +x /usr/local/sbin/apply-kpatch.sh
sudo systemctl daemon-reload
sudo systemctl enable --now kpatch-apply.timer
Troubleshooting Common Issues
- "kpatch: module not found" — The kpatch-dkms package may not have built the core module. Reinstall it:
sudo apt install --reinstall kpatch-dkms. - "kpatch: incompatible kernel version" — A patch module is tied to the exact kernel version it was compiled against. After a kernel upgrade, reboot to the new kernel before loading patches for it.
- VPS runs on a container/OpenVZ — Live patching requires a real kernel, not a containerized one. KVM-based VPS plans work fine. Check with
systemd-detect-virt— if it returnsopenvzorlxc, live patching is not available. - Memory overhead — Each loaded patch consumes 100–500 KB of kernel memory. On a VPS with 512 MB RAM, limit yourself to the most critical patches.
When Live Patching Is Not Enough
Kpatch is a tactical tool. It eliminates the downtime cost of the most common kernel CVEs, but it does not replace scheduled reboots. Major kernel version upgrades, patches that change data structures, and fixes to module initialization code still require a restart. Use live patching to buy time — apply security fixes immediately, then schedule a reboot during the next maintenance window. For more on choosing a VPS that gives you full kernel control, see our VPS hosting plans.

Leave a Reply
You must be logged in to post a comment.