Most hacked servers aren't broken into with clever zero-days. They're running software that was patched weeks ago. When PHP2Shell was disclosed, attacks started within days, and servers that installed security updates automatically were protected before most admins even read the news. Ubuntu can do this for you with a built-in tool called unattended-upgrades. Here's how to set it up properly, test it, and control reboots.

sudo.Step 1: Install and enable unattended-upgrades
It's preinstalled on most Ubuntu servers, but make sure:
sudo apt update
sudo apt install unattended-upgrades apt-listchanges
# turn it on (choose "Yes" in the dialog)
sudo dpkg-reconfigure -plow unattended-upgrades
This creates /etc/apt/apt.conf.d/20auto-upgrades. Check that it contains:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
The "1" means every day: refresh the package lists, then install updates.
Step 2: Choose what gets updated
The main settings live in /etc/apt/apt.conf.d/50unattended-upgrades. By default only the security pocket is enabled, which is the safest choice for production servers:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
// "${distro_id}:${distro_codename}-updates";
};
Include PHP from the ondrej/php PPA
Many servers get newer PHP versions from ppa:ondrej/php. Updates from PPAs are not installed automatically unless you add them. Add this line inside Allowed-Origins:
"LP-PPA-ondrej-php:${distro_codename}";
Not sure of the right name for a repository? Run apt-cache policy and look at the o= (origin) and a=/n= values for that repository.
Useful options
// remove old kernels and packages that are no longer needed
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
// email a report (needs a working mail setup, e.g. msmtp or postfix)
Unattended-Upgrade::Mail "you@example.com";
Unattended-Upgrade::MailReport "only-on-error";
// never auto-update these packages
Unattended-Upgrade::Package-Blacklist {
"mysql-server";
};
Step 3: Decide how reboots work
Kernel and core library updates only take effect after a reboot. You have three options:
| Option | Setting | Good for |
|---|---|---|
| Reboot automatically at a quiet time | Automatic-Reboot "true"; + Automatic-Reboot-Time "04:00"; | Single servers where a minute of downtime at night is fine |
| Reboot manually | leave Automatic-Reboot "false"; | Servers you check regularly |
| Livepatch (no reboot for kernel fixes) | sudo pro attach then sudo pro enable livepatch | Servers that must stay up. Ubuntu Pro is free for personal use on a few machines |
Check whether a server is waiting for a reboot:
[ -f /var/run/reboot-required ] && cat /var/run/reboot-required.pkgs || echo "No reboot needed"
Services like PHP-FPM, Nginx and MySQL are restarted automatically after library updates by needrestart, which is installed by default on recent Ubuntu releases.
Step 4: Test it with a dry run
Don't wait a day to find out if it works. Simulate a run and watch what it would install:
sudo unattended-upgrade --dry-run --debug

Look for the line listing Allowed origins and the packages it would upgrade. If you added the PHP PPA, PHP packages should appear when updates are available.
Step 5: Check that it's running
# when the automatic jobs run next
systemctl list-timers apt-daily.timer apt-daily-upgrade.timer
# what was installed and when
less /var/log/unattended-upgrades/unattended-upgrades.log
grep -h 'Packages that will be upgraded' /var/log/unattended-upgrades/unattended-upgrades.log | tail
By default the upgrade timer runs once a day around 06:00 with a random delay. To pick a time, override the timer:
sudo systemctl edit apt-daily-upgrade.timer
[Timer]
OnCalendar=
OnCalendar=*-*-* 03:30
RandomizedDelaySec=15m
What automatic updates don't cover
- Software you installed outside apt: Docker images, Composer and npm packages, WordPress and its plugins, and binaries you downloaded manually. Docker containers keep old PHP until you rebuild them.
- Major version upgrades: moving from PHP 8.1 to 8.3, or from Ubuntu 22.04 to 24.04, is always a manual decision.
- End-of-life releases: an Ubuntu version that's out of support gets no new security updates at all (unless covered by Ubuntu Pro). Check with
pro statusorlsb_release -a.
Summary
sudo apt install unattended-upgrades apt-listchanges
sudo dpkg-reconfigure -plow unattended-upgrades
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades # origins, reboot, email
sudo unattended-upgrade --dry-run --debug # test
Five minutes of setup means the next critical PHP, OpenSSL or kernel fix lands on your server within a day, without you having to remember. Questions about a specific setup? Ask in the comments.
Comments
Post a Comment