If you run a server—VPS, dedicated box, or even a shared hosting control panel—you'll eventually hear about CVE vulnerabilities. Maybe a client forwarded a scanner report. Maybe your monitoring tool flagged outdated packages. Either way, the term sounds urgent, and it is.
A CVE is a publicly disclosed security flaw with a unique identifier. Attackers study these flaws the moment they're published, so patching them quickly is the difference between a secure server and a compromised one. This guide walks you through the entire process from zero, defining every term and showing you exactly what to run.
What is a CVE vulnerability
CVE stands for Common Vulnerabilities and Exposures. It's a standardized naming system maintained by the MITRE Corporation. When a researcher or vendor discovers a security flaw in software, they request a CVE identifier—a number like CVE-2024-1234. That ID lets everyone worldwide refer to the same bug without confusion.
Each CVE entry includes a description of the flaw, which software versions are affected, and a severity score (usually CVSS, ranging from 0 to 10). A score above 7 is considered high; above 9 is critical. Critical vulnerabilities often allow remote code execution, meaning an attacker can run arbitrary commands on your server without logging in.
In support tickets I handled, the most common shock was realizing how fast exploits appear. A CVE published on Monday can have working exploit code circulating by Wednesday. Automated scanners sweep the internet for vulnerable systems within hours. That's why patching speed matters more than perfection.
Why infrastructure patching is different from desktop updates
On your laptop, you click "update" and reboot whenever convenient. Servers require more care. Here's why:
- Uptime commitments: rebooting a production web server means downtime for every site it hosts.
- Dependency chains: updating one library can break an application that depends on a specific version.
- Configuration drift: manual tweaks to config files can be overwritten by package updates, breaking services.
- Kernel updates: these always require a reboot, and if something goes wrong, remote access might be lost.
The trade-off is always risk versus availability. A critical remote exploit in OpenSSH demands immediate action even if it means a maintenance window. A low-severity bug in a package you don't use can wait for scheduled maintenance.
Step 1: Identify which CVEs affect your system
Before you patch anything, figure out what's vulnerable. Most Linux distributions ship with tools that compare installed packages against known CVE databases.
On Debian and Ubuntu, use apt with the ubuntu-security or debian-security repositories already configured:
sudo apt update
sudo apt upgrade --dry-run | grep -i security
The --dry-run flag shows what would be updated without actually doing it. Look for lines mentioning "security" in the changelog.
On Red Hat, CentOS, AlmaLinux, and Rocky Linux, use yum or dnf:
sudo yum updateinfo list security
This outputs every available security update with its associated CVE ID and severity. You can filter further:
sudo yum updateinfo list security --sec-severity=Critical
For a more detailed report, install yum-plugin-security if it's not already present, then run:
sudo yum updateinfo info CVE-2024-1234
Replace that example CVE with the one you're researching. The output shows which packages are affected and what the update fixes.
Vulnerability scanners
If you want a broader view across multiple servers or need to audit software installed outside package managers (like compiled binaries or Docker containers), consider a scanner. Tools like Lynis, OpenSCAP, or commercial options like Qualys and Tenable perform deep inspections and generate reports with CVE IDs, CVSS scores, and remediation steps.
I prefer package-manager queries for day-to-day work because they're fast and authoritative. Scanners are better for compliance audits or when you inherit an unknown system.
Step 2: Prioritize which vulnerabilities to patch first
You'll rarely have the luxury of patching everything at once. Prioritize by:
- Severity score: CVSS 9+ (critical) first, then high (7-8.9), then medium.
- Exposure: Is the vulnerable service listening on a public IP? SSH, web servers, and mail servers are prime targets. A vulnerability in a library used only by an internal script is lower priority.
- Exploit availability: Check whether proof-of-concept exploit code is public. Sites like Exploit-DB or GitHub often host working exploits days after disclosure.
- Vendor guidance: Read the CVE details and the vendor's security advisory. Sometimes a CVE is severe in theory but requires local access or rare configuration, making it less urgent in practice.
A concrete example: if your server runs Apache with a public-facing website and a critical CVE in Apache allows remote code execution, patch it today. If the same server has a medium-severity flaw in a library used by a cron job that runs once a week and isn't network-accessible, schedule it for your next maintenance window.
Step 3: Back up critical data and configurations
Patching can go wrong. A bad update might break your web server config, fail to start a database, or—worst case—render the system unbootable. Always have a recovery path.
Before applying updates:
- Snapshot the VM if you're on a cloud provider or hypervisor that supports it. This gives you a one-click rollback.
- Back up configuration files for services you're updating. For example:
sudo cp -a /etc/apache2 /root/apache2.backup.$(date +%F)
sudo cp -a /etc/nginx /root/nginx.backup.$(date +%F)
sudo cp -a /etc/my.cnf /root/my.cnf.backup.$(date +%F)
- Dump databases if the update affects database software:
mysqldump --all-databases > /root/all-databases.$(date +%F).sql
- Document your kernel version before updating:
uname -r > /root/kernel.before
In dozens of updates I've overseen, snapshots saved hours of panic maybe three times. The rest of the time they sat unused. But those three times justified every snapshot ever taken.
Step 4: Test the update in a staging environment
If you have a staging server—a clone of production used for testing—apply the patch there first. Boot it, run your application's test suite or smoke tests, check logs for errors, and confirm everything behaves normally.
Many small hosting setups skip staging because of cost. That's a trade-off you make consciously. If you do skip it, at least read the package changelog to understand what's changing:
sudo apt-get changelog apache2
or on Red Hat-based systems:
sudo yum changelog httpd
Look for lines mentioning "breaking change," "backward incompatible," or "configuration syntax." Those signal you'll need to adjust config files.
Step 5: Apply the security patch
Once you're confident (or as confident as you'll get), apply the update.
On Debian/Ubuntu
Update the package list, then install security updates:
sudo apt update
sudo apt upgrade
If you want to update only packages with security fixes and nothing else, you can parse the changelogs manually or use unattended-upgrades configured to apply security updates only. For a one-time manual run:
sudo unattended-upgrade -d
The -d flag enables debug output so you see what's happening.
On Red Hat/CentOS/AlmaLinux/Rocky
Install only security updates:
sudo yum update --security
Or update a specific package:
sudo yum update httpd
If a kernel update is included, you'll see a new kernel package installed. The running kernel won't change until you reboot.
Restart affected services
Updating a package doesn't restart the running process. Your old vulnerable Apache binary is still in memory until you restart it:
sudo systemctl restart apache2
or
sudo systemctl restart httpd
For other services:
sudo systemctl restart nginx
sudo systemctl restart mysql
sudo systemctl restart php-fpm
Check that the service came back up:
sudo systemctl status apache2
If it failed, the output will tell you why. Check the full logs:
sudo journalctl -u apache2 -n 50
Most failures are config syntax errors introduced by manual edits that conflict with new defaults. Fix the config and restart again.
Step 6: Reboot if the kernel was updated
Kernel vulnerabilities often affect low-level networking, memory management, or privilege escalation—things you can't patch without rebooting. After updating the kernel package, schedule a reboot during a maintenance window.
Before rebooting, double-check that your boot configuration is intact:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
(On Debian/Ubuntu, the command is sudo update-grub.)
Then reboot:
sudo reboot
After the server comes back up, verify the new kernel loaded:
uname -r
Compare it to the version you documented earlier. If the old kernel is still running, the bootloader might not have picked up the new one—check your GRUB config and reboot again.
Step 7: Verify the patch was applied
Confirm that the vulnerable package version is gone and the patched version is active.
On Debian/Ubuntu:
apt policy <package-name>
On Red Hat/CentOS:
yum info <package-name>
Cross-reference the installed version with the CVE advisory to confirm it includes the fix. For example, if CVE-2024-1234 says "fixed in version 2.4.50" and you're running 2.4.51, you're good.
Re-run your vulnerability scanner or package audit to confirm the CVE no longer appears:
sudo yum updateinfo list security
If the CVE is still listed, either the update didn't install correctly or the scanner's database hasn't refreshed. Wait a few hours and check again, or update the scanner's CVE database manually if the tool supports it.
What if a patch isn't available yet
Sometimes a CVE is disclosed before vendors release a patched package—a "zero-day" if it's being actively exploited. Your options:
- Mitigate at the perimeter: block access to the vulnerable service using a firewall rule or disable the service entirely if it's not critical.
- Apply a workaround: the CVE advisory or vendor bulletin might suggest a config change that reduces risk. For example, disabling a specific Apache module.
- Monitor closely: watch logs for signs of exploitation attempts (unusual requests, failed logins from unexpected IPs, new user accounts).
- Consider a backport patch: some distributions ship unofficial patches faster than upstream. Check your distro's security mailing list.
I've seen clients panic over CVEs in services they'd forgotten were even installed. The fastest mitigation is often sudo systemctl stop unwanted-service && sudo systemctl disable unwanted-service.
Automating security updates
Manual patching doesn't scale beyond a handful of servers. Both Debian and Red Hat families offer unattended update tools.
On Debian/Ubuntu, unattended-upgrades can apply security patches automatically:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
Edit /etc/apt/apt.conf.d/50unattended-upgrades to control which repositories are used (usually you want only security repos enabled) and whether automatic reboots are allowed.
On Red Hat/CentOS, yum-cron or dnf-automatic does the same:
sudo yum install yum-cron
sudo systemctl enable yum-cron
sudo systemctl start yum-cron
Edit /etc/yum/yum-cron.conf to set apply_updates = yes and configure email notifications.
Automation is a trade-off. You gain speed and consistency but lose control over timing. For production servers with strict uptime SLAs, I prefer automatic download with manual application—let the system fetch patches overnight, then apply them during a planned window.
How often should you patch
Critical vulnerabilities demand same-day or next-day patching. High-severity issues should be addressed within a week. Medium and low can wait for your regular maintenance cycle—weekly or monthly depending on your risk tolerance.
Set up a recurring task to check for updates:
0 2 * * * /usr/bin/apt update && /usr/bin/apt list --upgradable | mail -s "Available updates" [email protected]
That cron job runs daily at 2 AM and emails you a list of available updates. Adjust the command for your distro's package manager.
What to do right now
Run your package manager's security update check today. Pick the highest-severity CVE, read the advisory, take a snapshot, and patch it. Then set a calendar reminder to repeat the process weekly. The rhythm becomes routine fast, and each patched CVE is one less door left open.
You'll never patch everything instantly—that's not the goal. The goal is a system where you know what's vulnerable, you have a process to fix it, and you can prove to yourself (or an auditor) that critical flaws get closed before attackers find them. That's how you keep infrastructure secure without burning out.
