latest commit

This commit is contained in:
2026-01-30 09:35:27 +01:00
commit 552f8c566d
4 changed files with 517 additions and 0 deletions

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Allan Christensen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

233
README.md Normal file
View File

@@ -0,0 +1,233 @@
# Unattended Upgrades Policy for Ubuntu 24.04 Server
![Ubuntu](https://img.shields.io/badge/Ubuntu-24.04-orange)
[![Feature](https://img.shields.io/badge/feature-controlled_updates-0078D7)](#)
![License](https://img.shields.io/badge/License-MIT-green)
Install unattended upgrades on Ubuntu 24.04 server — with **explicit OPS control**.
> **Production notice**
> This script configures automatic updates and optional automatic reboots.
> Read and understand the policy modes before applying it on production systems.
---
## Why this installer exists
Ubuntu already ships with unattended upgrades — but the defaults are a bear trap.
This installer exists to give **OPS full control** over:
- what gets updated
- when updates run
- whether systems reboot automatically
- how users are impacted
No hidden timers.
No silent defaults.
No surprises.
---
## What this installer does
✔ Installs required packages (`unattended-upgrades`, `update-notifier-common`)
✔ Disables Ubuntus automatic APT timers
✔ Enforces **one explicit update policy (mode 14)**
✔ Configures unattended-upgrades accordingly
✔ Creates a controlled cron job
✔ Backs up original configuration files **once**, in-place
✔ Can be safely re-run to switch policies
✔ Does **NOT** enable automatic package removal (`apt autoremove`)
---
## What this installer does NOT do
It wont stop you from running the script without reading the documentation like theres no tomorrow.
Skip the README, and whatever happens next is your headache, not a bug report.
---
## Supported systems
- Ubuntu **24.04 Server**
- Designed for **servers**, not desktops
- Not intended for containers or Docker images
---
## Before you run the script
Update package metadata **manually**:
```
apt update
```
This is intentionally not done by the script.
---
## Installation
Clone the repository:
```
git clone https://git.x-files.dk/server/auto-update-ubuntu.git
```
Change into the directory:
```
cd auto-update-ubuntu
```
---
## Usage
The script is **non-interactive** and **argument-driven**.
You must select **exactly one mode**:
```
sudo ./auto-update-ubuntu <mode>
```
Example:
```
sudo ./auto-update-ubuntu 1
```
### Available modes
**Mode 1**
- Security **and** software updates
- Automatic reboot
- Reboot happens even if users are logged in
**Mode 2**
- Security **and** software updates
- No automatic reboot
- Users are notified on next login if a reboot is required
**Mode 3**
- Security updates only
- Automatic reboot
- Reboot happens even if users are logged in
**Mode 4**
- Security updates only
- No automatic reboot
- Users are notified on next login if a reboot is required
Running the script again with a different mode will **overwrite the previous policy**.
---
## Cron schedule
Updates are executed via cron:
- **Every Friday at 03:00**
- Command executed:
```
apt update && unattended-upgrade -v
```
The cron file is managed at:
```
/etc/cron.d/updatesystem
```
Re-running the script will always reassert this schedule.
---
## Backups and rollback
### Full rollback (restore Ubuntu defaults)
This rollback **fully returns the system to Ubuntus default unattended-upgrades behavior**.
It restores the original configuration files, removes the OPS-controlled cron job, and hands scheduling control back to Ubuntus built-in APT timers.
Partial rollback is **not recommended**.
---
### 1. Restore original configuration files
```
sudo cp /etc/apt/apt.conf.d/20auto-upgrades.orig /etc/apt/apt.conf.d/20auto-upgrades
sudo cp /etc/apt/apt.conf.d/50unattended-upgrades.orig /etc/apt/apt.conf.d/50unattended-upgrades
```
Restart unattended-upgrades:
```
sudo systemctl restart unattended-upgrades.service
```
---
### 2. Re-enable Ubuntus default APT timers (important)
This script disables and masks Ubuntus automatic APT timers to ensure OPS-controlled scheduling.
To restore Ubuntu defaults:
```
sudo systemctl unmask apt-daily.service apt-daily-upgrade.service
sudo systemctl enable --now apt-daily.timer apt-daily-upgrade.timer
```
---
### 3. Remove the OPS-controlled cron job
```
sudo rm -f /etc/cron.d/updatesystem
sudo systemctl restart cron.service
```
---
### Important note about collisions
Do **not** run Ubuntus APT timers **and** this cron job at the same time.
Doing so may result in:
- concurrent APT locks
- unpredictable update timing
- reboots outside approved maintenance windows
Choose **one scheduling mechanism only**.
---
## Operational notes
- The script is silent on success
- Invalid or missing arguments cause a hard failure
- No defaults are assumed
- All configuration is **authoritative**, not incremental
This is a **policy tool**, not a wizard.
---
### More Information
More guides and documentation can be found on [wiki.x-files.dk](https://wiki.x-files.dk)
---
### License
Licensed under the MIT License.
Licensed under the [MIT License](./LICENSE).
---

259
auto-upgrade-new Executable file
View File

@@ -0,0 +1,259 @@
#!/usr/bin/env bash
# Author : Allan Christensen
# First Created : 23-06-2022 (DD-MM-YYYY)
# Description : OPS-controlled unattended-upgrades policy configuration for Ubuntu 24.04
# License : MIT License
#
# Are we root
#
if [[ $(id -u) -ne 0 ]]; then
echo ""
echo "Must be root or use sudo"
echo ""
exit 1
fi
#
# Variables
#
mode="${1:-}"
config1="/etc/apt/apt.conf.d/20auto-upgrades"
config1alt="/usr/share/unattended-upgrades/20auto-upgrades"
config2="/etc/apt/apt.conf.d/50unattended-upgrades"
config2alt="/usr/share/unattended-upgrades/50unattended-upgrades"
cronfile="/etc/cron.d/updatesystem"
#
# Functions
#
die () {
echo "Error: $*" >&2
exit 1
}
usage () {
cat <<EOF
Usage: $0 <mode>
Please select ONE of the following modes:
1 Security + software updates
Automatic reboot immediately after upgrades complete
2 Security + software updates
No automatic reboot
Users will be notified on next login if a reboot is required
3 Security updates only
Automatic reboot immediately after upgrades complete
4 Security updates only
No automatic reboot
Users will be notified on next login if a reboot is required
EOF
exit 1
}
chkcfg () {
if [[ ! -f "$1" ]]; then
[[ -f "$2" ]] || die "Missing source config: $2"
cp -Rp "$2" "$1" || die "Failed to copy $2 to $1"
fi
}
mkorig () {
if [[ ! -f "${1}.orig" ]]; then
cp -Rp "$1" "${1}.orig" || die "Failed to create backup: ${1}.orig"
fi
}
#
# Disable Ubuntu automatic timers (OPS owns scheduling)
#
disable_apt_timers () {
systemctl disable --now apt-daily.timer apt-daily-upgrade.timer >/dev/null 2>&1 || true
systemctl mask apt-daily.service apt-daily-upgrade.service >/dev/null 2>&1 || true
}
#
# Ensure periodic jobs are disabled (cron owns execution)
#
set_20auto () {
sed -i 's|^\s*APT::Periodic::Update-Package-Lists.*|APT::Periodic::Update-Package-Lists "0";|' "$config1"
sed -i 's|^\s*APT::Periodic::Unattended-Upgrade.*|APT::Periodic::Unattended-Upgrade "0";|' "$config1"
}
#
# Allowed origins explicit, Bash-native
#
set_allowed_origins () {
local allow_updates="$1"
#
# Always enable security updates
#
sed -i \
'/^\s*\/\/\s*"\${distro_id}:\${distro_codename}-security"/ s|^\s*//\s*||' \
"$config2"
#
# Enable or disable non-security updates
#
if [[ "$allow_updates" == "true" ]]; then
sed -i \
'/^\s*\/\/\s*"\${distro_id}:\${distro_codename}-updates"/ s|^\s*//\s*||' \
"$config2"
else
sed -i \
'/^\s*"\${distro_id}:\${distro_codename}-updates"/ s|^|// |' \
"$config2"
fi
}
#
# Reboot policy immediate reboot after upgrades
#
set_reboot_policy () {
local reboot="$1"
local reboot_with_users="$2"
#
# Automatic-Reboot (exact key only)
#
sed -i \
'/^\s*\/\/\s*Unattended-Upgrade::Automatic-Reboot\s/ s|^\s*//\s*||' \
"$config2"
sed -i \
's|^\s*Unattended-Upgrade::Automatic-Reboot\s*".*";|Unattended-Upgrade::Automatic-Reboot "'"$reboot"'";|' \
"$config2"
#
# Automatic-Reboot-WithUsers (exact key only)
#
sed -i \
'/^\s*\/\/\s*Unattended-Upgrade::Automatic-Reboot-WithUsers\s/ s|^\s*//\s*||' \
"$config2"
sed -i \
's|^\s*Unattended-Upgrade::Automatic-Reboot-WithUsers\s*".*";|Unattended-Upgrade::Automatic-Reboot-WithUsers "'"$reboot_with_users"'";|' \
"$config2"
#
# Ensure reboot-time stays commented (cron defines timing)
#
sed -i \
'/^\s*Unattended-Upgrade::Automatic-Reboot-Time/ s|^|// |' \
"$config2"
}
#
# Cron authoritative schedule
#
write_cron () {
cat > "$cronfile" <<EOF
#
# Managed by: auto-update-ubuntu
# Purpose : OPS-controlled unattended upgrades
# Schedule : Every Friday at 03:00
#
0 3 * * 5 root /usr/bin/apt update && /usr/bin/unattended-upgrade -v >/dev/null 2>&1
EOF
chmod 644 "$cronfile" || die "Failed chmod on $cronfile"
chown root:root "$cronfile" || die "Failed chown on $cronfile"
}
restart_services () {
systemctl restart unattended-upgrades.service >/dev/null 2>&1 || die "Failed to restart unattended-upgrades"
systemctl restart cron.service >/dev/null 2>&1 || die "Failed to restart cron"
}
#
# Validate mode
#
case "$mode" in
1|2|3|4) ;;
*) usage ;;
esac
#
# Informational output (configuration-time only)
#
echo "Applying unattended-upgrades policy:"
echo ""
case "$mode" in
1)
echo " Mode: 1"
echo " Updates: Security + software updates"
echo " Reboot: Immediate reboot after upgrades complete"
;;
2)
echo " Mode: 2"
echo " Updates: Security + software updates"
echo " Reboot: Disabled"
echo " User notification: On next login if a reboot is required"
;;
3)
echo " Mode: 3"
echo " Updates: Security updates only"
echo " Reboot: Immediate reboot after upgrades complete"
;;
4)
echo " Mode: 4"
echo " Updates: Security updates only"
echo " Reboot: Disabled"
echo " User notification: On next login if a reboot is required"
;;
esac
echo ""
#
# Packages (no implicit apt update)
#
apt-get -y -qq install unattended-upgrades update-notifier-common >/dev/null \
|| die "Package install failed"
#
# Ensure configs exist
#
chkcfg "$config1" "$config1alt"
chkcfg "$config2" "$config2alt"
#
# Backup originals (once)
#
mkorig "$config1"
mkorig "$config2"
#
# OPS-owned execution model
#
set_20auto
disable_apt_timers
#
# Apply policy
#
case "$mode" in
1|2) set_allowed_origins "true" ;;
3|4) set_allowed_origins "false" ;;
esac
case "$mode" in
1|3) set_reboot_policy "true" "true" ;;
2|4) set_reboot_policy "false" "false" ;;
esac
#
# Cron + services
#
write_cron
restart_services
exit 0

4
last-tested Normal file
View File

@@ -0,0 +1,4 @@
------------------------------------
Last tested: 28-01-2026 (DD-MM-YYYY)
Environment: Ubuntu Server 24.04 LTS
------------------------------------