System hardening
Apply security updates
Track Ubuntu support, install security fixes promptly, plan reboots, and test application health after changes.
Known vulnerabilities become easier to exploit after public disclosure. Keep the operating system inside a supported update path.
An Ubuntu LTS release receives standard security fixes for five years. A server on an unsupported release gets nothing, no matter how carefully you run the commands below.
Review and apply pending fixes
Refresh package metadata, review pending updates, apply security fixes:
sudo apt update
apt list --upgradable
sudo apt upgrade
Then check whether a reboot is required:
cat /var/run/reboot-required
# *** System restart required ***
A kernel fix may install successfully but remain inactive until reboot. Record the running kernel and package version separately. That evidence prevents a successful package command from being mistaken for a completed fix when the vulnerable code remains loaded:
uname -r
# 6.8.0-45-generic <- still the old kernel until you reboot
Automate the security channel
Ubuntu ships unattended-upgrades to install security fixes on their own:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
Answering yes writes /etc/apt/apt.conf.d/20auto-upgrades, which turns on daily security updates. Automate updates only with monitoring and a recovery plan. Automatic updates shorten exposure, while staged updates make application regressions easier to catch.
My advice for a single-purpose VPS: enable unattended security updates for the OS, and move application dependencies through your normal deploy process where you can test them.
Snapshotting is useful, but it does not replace a tested application rollback and backup.
Check health after every update
An update that breaks the application is still an outage. After upgrading and rebooting, hit the health endpoint and watch the service logs before you walk away:
curl -s https://blog.flaviocopes.com/health
# ok
Record pending packages, installed versions, reboot state, and service checks before and after updating. Break one health check or use a disposable failed service, then prove monitoring detects the incomplete maintenance.
Lesson completed