#!/usr/bin/env bash ################################################################ # This script automatically sets up unattended-upgrades # for Ubuntu/Debian-based systems, with a custom configuration # created by Privex. # # It also creates a cron to make sure it runs at least once per day. # # Usage: # # curl -fsSL https://cdn.privex.io/extras/setup-auto-updates.sh | bash # # # (C) 2021 Privex Inc. - https://www.privex.io/ # License: X11 / MIT ################################################################ : ${CONF_DIR="/etc/apt/apt.conf.d"} : ${CONF_FILE="50unattended-upgrades"} : ${CONF_PATH="${CONF_DIR}/${CONF_FILE}"} : ${CRON_PATH="/etc/cron.d/unattended-upgrades"} export PATH="${HOME}/.local/bin:/snap/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:${PATH}" export DEBIAN_FRONTEND=noninteractive hascmd() { [[ -f "/bin/$1" || -f "/usr/bin/$1" || -f "/usr/local/bin/$1" || -f "/sbin/$1" || -f "/usr/sbin/$1" || -f "/usr/local/sbin/$1" ]]; } xsudo() { if (( EUID == 0 )); then "$@" else if hascmd sudo; then sudo "$@" else >&2 echo -e "\n\n [!!!] ERROR: You're not root, and 'sudo' is not available. Cannot continue. Cannot run: $*" exit 9 fi fi } echo -e "\n\n >>> Updating apt repos ... \n" xsudo apt update -y echo -e "\n\n >>> Installing unattended-upgrades ...\n" xsudo apt install -y unattended-upgrades apt-listchanges echo "\n\n >>> Generating cron file at: $CRON_PATH \n" xsudo tee "$CRON_PATH" <<"EOF" ######################################################################################## # # Run unattended upgrades every day at 04:37 AM, and log it's output # into the file /var/log/unattended-upgrades.log # # This file was added by Privex's setup-auto-upgrades.sh file ( https://www.privex.io ) # https://cdn.privex.io/extras/setup-auto-upgrades.sh # ######################################################################################## SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command 37 4 * * * root unattended-upgrades -v &> /var/log/unattended-upgrades.log EOF xsudo chmod +x "$CRON_PATH" TMPD="$(mktemp -d)" BK_FILE="" if [[ -f "$CONF_PATH" ]]; then BK_FILE="${TMPD}/${CONF_FILE}" echo -e "\n\n >>> The unattended upgrades config file already exists at: $CONF_PATH" echo -e " >>> Backing up file '$CONF_PATH' to: $BK_FILE \n" xsudo mv -v "${CONF_FILE}" "$BK_FILE" fi echo -e "\n\n >>> Generating config at: $CONF_PATH \n" xsudo tee "$CONF_PATH" &> /dev/null <<"EOF" // Automatically upgrade packages from these (origin:archive) pairs // // Note that in Ubuntu security updates may pull in new dependencies // from non-security sources (e.g. chromium). By allowing the release // pocket these get automatically pulled in. Unattended-Upgrade::Allowed-Origins { "${distro_id}:${distro_codename}"; "${distro_id}:${distro_codename}-security"; "${distro_id}:${distro_codename}-updates"; "Privex:universal"; "TorProject:bionic"; "LP-PPA-i2p-maintainers-i2p:main"; // Extended Security Maintenance; doesn't necessarily exist for // every release and this system may not have it installed, but if // available, the policy for updates is such that unattended-upgrades // should also install from here by default. "${distro_id}ESMApps:${distro_codename}-apps-security"; "${distro_id}ESM:${distro_codename}-infra-security"; // "${distro_id}:${distro_codename}-updates"; // "${distro_id}:${distro_codename}-proposed"; // "${distro_id}:${distro_codename}-backports"; }; // List of packages to not update (regexp are supported) Unattended-Upgrade::Package-Blacklist { // Updating docker generally causes containers to be restarted, which could // corrupt them if shutdown incorrectly, so we blacklist docker packages // from auto-updates. "docker"; "docker-ce"; "docker-ce-cli"; "docker.io"; // "vim"; // "libc6"; // "libc6-dev"; // "libc6-i686"; }; // This option will controls whether the development release of Ubuntu will be // upgraded automatically. Unattended-Upgrade::DevRelease "false"; // This option allows you to control if on a unclean dpkg exit // unattended-upgrades will automatically run // dpkg --force-confold --configure -a // The default is true, to ensure updates keep getting installed Unattended-Upgrade::AutoFixInterruptedDpkg "true"; // Split the upgrade into the smallest possible chunks so that // they can be interrupted with SIGTERM. This makes the upgrade // a bit slower but it has the benefit that shutdown while a upgrade // is running is possible (with a small delay) //Unattended-Upgrade::MinimalSteps "false"; // Install all unattended-upgrades when the machine is shutting down // instead of doing it in the background while the machine is running // This will (obviously) make shutdown slower Unattended-Upgrade::InstallOnShutdown "false"; // Send email to this address for problems or packages upgrades // If empty or unset then no email is sent, make sure that you // have a working mail setup on your system. A package that provides // 'mailx' must be installed. E.g. "user@example.com" Unattended-Upgrade::Mail "company@privex.io"; // Set this value to "true" to get emails only on errors. Default // is to always send a mail if Unattended-Upgrade::Mail is set //Unattended-Upgrade::MailOnlyOnError "true"; // Remove unused automatically installed kernel-related packages // (kernel images, kernel headers and kernel version locked tools). Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; // Do automatic removal of new unused dependencies after the upgrade // (equivalent to apt-get autoremove) Unattended-Upgrade::Remove-Unused-Dependencies "true"; // Automatically reboot *WITHOUT CONFIRMATION* // if the file /var/run/reboot-required is found after the upgrade Unattended-Upgrade::Automatic-Reboot "false"; // If automatic reboot is enabled and needed, reboot at the specific // time instead of immediately // Default: "now" //Unattended-Upgrade::Automatic-Reboot-Time "02:00"; // Use apt bandwidth limit feature, this example limits the download // speed to 70kb/sec //Acquire::http::Dl-Limit "70"; // Enable logging to syslog. Default is False Unattended-Upgrade::SyslogEnable "true"; // Specify syslog facility. Default is daemon // Unattended-Upgrade::SyslogFacility "daemon"; // Download and install upgrades only on AC power // (i.e. skip or gracefully stop updates on battery) // Unattended-Upgrade::OnlyOnACPower "true"; // Download and install upgrades only on non-metered connection // (i.e. skip or gracefully stop updates on a metered connection) // Unattended-Upgrade::Skip-Updates-On-Metered-Connections "true"; EOF xsudo chmod +x "$CONF_PATH" echo -e "\n\n +++ FINISHED +++ \n" echo -e "\n\n +++ Testing unattended-upgrades with a verbose dry run, please check for any errors below. \n" xsudo unattended-upgrades -v --dry-run if [[ -n "$BK_FILE" ]]; then echo -e "\n\n [!!!] Please be aware - your original config for unattended-upgrades was backed up to $BK_FILE if you need to restore it.\n" fi