os:debian:unattendedupgrades
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| os:debian:unattendedupgrades [2025/10/03 14:23] – warnaud | os:debian:unattendedupgrades [2026/06/07 11:13] (current) – [7. Minimal checklist] warnaud | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Auto updates ====== | ====== Auto updates ====== | ||
| Here's how to setup your debian to update automatically | Here's how to setup your debian to update automatically | ||
| + | |||
| + | This page describes how to set up automatic security updates with '' | ||
| + | |||
| + | ===== 1. Install unattended-upgrades and msmtp ===== | ||
| + | |||
| + | <code bash> | ||
| + | apt update | ||
| + | apt install -y unattended-upgrades msmtp msmtp-mta mailutils | ||
| + | dpkg-reconfigure -plow unattended-upgrades | ||
| + | </ | ||
| + | |||
| + | Notes: [freundschafter](https:// | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | Check that '' | ||
| + | |||
| + | <code bash> | ||
| + | readlink -f / | ||
| + | # should be / | ||
| + | </ | ||
| + | |||
| + | ===== 2. Configure msmtp ===== | ||
| + | |||
| + | Create ''/ | ||
| + | |||
| + | <code bash> | ||
| + | cat >/ | ||
| + | # Global msmtp config | ||
| + | |||
| + | defaults | ||
| + | auth on | ||
| + | tls on | ||
| + | tls_trust_file / | ||
| + | logfile | ||
| + | |||
| + | account | ||
| + | host | ||
| + | port 587 | ||
| + | from | ||
| + | user | ||
| + | password | ||
| + | EOF | ||
| + | |||
| + | chmod 600 / | ||
| + | touch / | ||
| + | chmod 640 / | ||
| + | </ | ||
| + | |||
| + | Adjust: '' | ||
| + | |||
| + | For providers using SMTPS (465/SSL) instead of STARTTLS on 587, change: | ||
| + | |||
| + | * '' | ||
| + | * keep '' | ||
| + | * add '' | ||
| + | |||
| + | ==== Optional: aliases for local users ==== | ||
| + | |||
| + | Create ''/ | ||
| + | |||
| + | <code bash> | ||
| + | cat >/ | ||
| + | root: user@yourdomain.tld | ||
| + | default: user@yourdomain.tld | ||
| + | EOF | ||
| + | |||
| + | chmod 600 / | ||
| + | </ | ||
| + | |||
| + | Add the aliases line inside ''/ | ||
| + | |||
| + | < | ||
| + | aliases / | ||
| + | </ | ||
| + | |||
| + | ==== (optional) Make the mail(1) command use msmtp ==== | ||
| + | |||
| + | Create ''/ | ||
| + | |||
| + | <code bash> | ||
| + | cat >/ | ||
| + | set sendmail="/ | ||
| + | set from=unattended@fortier.it | ||
| + | EOF | ||
| + | </ | ||
| + | |||
| + | ===== 3. Test msmtp and CLI mail ===== | ||
| + | |||
| + | ==== Direct msmtp test ==== | ||
| + | |||
| + | <code bash> | ||
| + | echo "Hello from $(hostname)" | ||
| + | </ | ||
| + | |||
| + | If there is a problem, inspect: | ||
| + | |||
| + | <code bash> | ||
| + | tail -n 50 / | ||
| + | </ | ||
| + | |||
| + | for SMTP / TLS / auth errors. [manpages.debian](https:// | ||
| + | |||
| + | ==== Test via mail(1) (what unattended-upgrades uses) ==== | ||
| + | |||
| + | <code bash> | ||
| + | echo "Test via mail from $(hostname)" | ||
| + | </ | ||
| + | |||
| + | If this arrives, the system-wide mail path is working. | ||
| + | |||
| + | ===== 4. Configure unattended-upgrades mail and origins ===== | ||
| + | |||
| + | Edit ''/ | ||
| + | |||
| + | < | ||
| + | Unattended-Upgrade:: | ||
| + | Unattended-Upgrade:: | ||
| + | </ | ||
| + | |||
| + | Typical '' | ||
| + | |||
| + | < | ||
| + | Unattended-Upgrade:: | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | }; | ||
| + | </ | ||
| + | |||
| + | ===== 5. Enable and check apt systemd timers ===== | ||
| + | |||
| + | Enable the standard apt timers: [exampleconfig](https:// | ||
| + | |||
| + | <code bash> | ||
| + | systemctl enable --now apt-daily.timer apt-daily-upgrade.timer | ||
| + | </ | ||
| + | |||
| + | List timers: | ||
| + | |||
| + | <code bash> | ||
| + | systemctl list-timers ' | ||
| + | </ | ||
| + | |||
| + | You should see: | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | with '' | ||
| + | |||
| + | ===== 6. Live tests for unattended-upgrades ===== | ||
| + | |||
| + | ==== A. Manual debug run (immediate mail) ==== | ||
| + | |||
| + | <code bash> | ||
| + | unattended-upgrades --dry-run --debug | ||
| + | </ | ||
| + | |||
| + | At the end you should see lines similar to: [prezu](https:// | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | A notification email should arrive even if there are: | ||
| + | |||
| + | * '' | ||
| + | |||
| + | ==== B. Simulate a real timer run ==== | ||
| + | |||
| + | Trigger the same service that the timer calls: | ||
| + | |||
| + | <code bash> | ||
| + | systemctl start apt-daily-upgrade.service | ||
| + | journalctl -u apt-daily-upgrade.service -n 50 | ||
| + | </ | ||
| + | |||
| + | Then check the unattended-upgrades log: | ||
| + | |||
| + | <code bash> | ||
| + | tail -n 50 / | ||
| + | </ | ||
| + | |||
| + | You should see either: | ||
| + | |||
| + | * '' | ||
| + | * or | ||
| + | * '' | ||
| + | |||
| + | In both cases a mail report should have been sent. [std](https:// | ||
| + | |||
| + | If something fails: | ||
| + | |||
| + | * Mail errors: | ||
| + | <code bash> | ||
| + | tail -n 50 / | ||
| + | </ | ||
| + | * Apt / unattended-upgrades errors: | ||
| + | <code bash> | ||
| + | journalctl -u apt-daily-upgrade.service -n 50 | ||
| + | </ | ||
| + | |||
| + | ===== 7. Minimal checklist ===== | ||
| + | |||
| + | - Install: | ||
| + | - '' | ||
| + | - Configure ''/ | ||
| + | - '' | ||
| + | - '' | ||
| + | - Set in ''/ | ||
| + | - '' | ||
| + | - '' | ||
| + | - Enable timers: | ||
| + | - '' | ||
| + | - Test unattended-upgrades: | ||
| + | - '' | ||
| + | - '' | ||
| + | |||
| + | | ||
| + | |||
| + | |||
| + | ===== 8. auto-reboot ===== | ||
| + | In this example, timer for upgrade is at 2:00 AM then reboot if needed is at 4:00AM | ||
| + | <code bash> | ||
| + | sudo apt install update-notifier-common -y | ||
| + | sudo vim / | ||
| + | add: | ||
| + | <code perl> | ||
| + | Unattended-Upgrade:: | ||
| + | Unattended-Upgrade:: | ||
| + | # to avoid reboot while people logged in: | ||
| + | # | ||
| + | |||
| + | <code bash> | ||
| + | sudo systemctl enable --now unattended-upgrades</ | ||
| + | Set time for upgrades ( before?): | ||
| + | <code bash> | ||
| + | sudo systemctl edit apt-daily-upgrade.timer</ | ||
| + | <code perl> | ||
| + | ### Editing / | ||
| + | ### Anything between here and the comment below will become the contents of the drop-in file | ||
| + | |||
| + | [Timer] | ||
| + | OnCalendar= | ||
| + | OnCalendar=*-*-* 02:00:00 | ||
| + | RandomizedDelaySec=0 | ||
| + | Persistent=true | ||
| + | </ | ||
| + | Relaunch/ | ||
| + | <code bash> sudo systemctl restart apt-daily-upgrade.timer | ||
| + | sudo systemctl status apt-daily-upgrade.timer</ | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ====== :!: OLD :!: Below ====== | ||
| ====== Install ====== | ====== Install ====== | ||
| Line 54: | Line 316: | ||
| Test: | Test: | ||
| <code bash> | <code bash> | ||
| + | ====== Reboot automatic when needed ====== | ||
| + | <code bash>vi / | ||
| + | <code perl> | ||
| + | APT:: | ||
| + | APT:: | ||
| + | </ | ||
| + | Daily check packages & upgrade | ||
| + | <code bash>vi / | ||
| + | <code perl> | ||
| + | ... | ||
| + | Unattended-Upgrade:: | ||
| + | Unattended-Upgrade:: | ||
| + | ... | ||
| + | </ | ||
| + | <code bash> | ||
| + | |||
| ====== Mail via msmtp ====== | ====== Mail via msmtp ====== | ||
| <code bash> apt install msmtp msmtp-mta mailutils | <code bash> apt install msmtp msmtp-mta mailutils | ||
| Line 87: | Line 365: | ||
| " | " | ||
| </ | </ | ||
| + | |||
| + | ====== Ubuntu ====== | ||
| + | A bug prevent SIGTERM to be sent properly to containers: https:// | ||
| + | Let's make a service for that: | ||
| + | <code bash> vi / | ||
| + | <code perl> | ||
| + | Description=Gracefully stop Docker containers before system shutdown or reboot | ||
| + | DefaultDependencies=no | ||
| + | Before=shutdown.target reboot.target halt.target | ||
| + | Requires=docker.service | ||
| + | After=network.target docker.service | ||
| + | |||
| + | [Service] | ||
| + | Type=oneshot | ||
| + | ExecStart=/ | ||
| + | ExecStop=/ | ||
| + | RemainAfterExit=yes | ||
| + | TimeoutStopSec=300 | ||
| + | |||
| + | [Install] | ||
| + | WantedBy=halt.target reboot.target shutdown.target | ||
| + | </ | ||
| + | <code bash> | ||
| + | systemctl enable docker-graceful-stop.service</ | ||
| + | |||
| + | As always it's not that simple... | ||
| + | ====== apt-daily-upgrade.timer ====== | ||
| + | <code bash> | ||
| + | <code bash> | ||
| + | <code perl> | ||
| + | [Timer] | ||
| + | OnCalendar= | ||
| + | OnCalendar=*-*-* 02:15 | ||
| + | RandomizedDelaySec=0 | ||
| + | Persistent=true | ||
| + | </ | ||
| + | <code bash> | ||
| + | systemctl restart apt-daily-upgrade.timer | ||
| + | systemctl list-timers apt-daily-upgrade.timer</ | ||
| + | ====== apt-daily.timer ====== | ||
| + | Of course... if you haven' | ||
| + | <code bash> | ||
| + | <code perl> | ||
| + | [Timer] | ||
| + | OnCalendar= | ||
| + | OnCalendar=*-*-* 01:45 | ||
| + | RandomizedDelaySec=0 | ||
| + | Persistent=true | ||
| + | </ | ||
| + | <code bash> | ||
| + | systemctl restart apt-daily.timer | ||
| + | systemctl list-timers apt-daily.timer | ||
| + | </ | ||
| + | |||
| + | |||
| ====== Reference ====== | ====== Reference ====== | ||
| * https:// | * https:// | ||
os/debian/unattendedupgrades.1759494187.txt.gz · Last modified: by warnaud
