Hello,

I first came across this problem on a computer I maintain for an elderly
relative who uses it only occasionally, typically two or three times a
week for about an hour each time. As that includes online banking, the
system was configured to use the "unattended-upgrades" package to keep up
with security updates.

After the upgrade from Debian 10 to Debian 11 (switch from anacron to
systemd as the entity triggering automatic upgrades), I noticed that
while unattended-upgrades was still being executed, it didn't find any
packages to upgrade any more although such packages had been released.
At the time I fixed that by brute force with a daily anacron job for
"apt-get update".

Recently I observed similar behaviour on my own PC (three days without
installing security updates although such packages existed already for
at least two days). I therefore looked closer into this behaviour and
traced it to the problem described in this report, i.e., the
"RandomizedDelaySec=12h" line in the default configuration for
apt-daily.timer (which is part of the "apt" package and not of the
"systemd" package as implied by the current assignation of this report).
In the scenario as described above (typical run time 1 hour), this leads
to the system having only a chance of 1/12 (8 %) per boot session to
update its package lists, irrespective of how often it boots. (Note that
in contrast apt-daily-upgrade.timer is configured with
"RandomizedDelaySec=60m".)

Systems running continuously should obviously have no problems with the
default configuration, while for the use case above I would consider
this behaviour totally unacceptable for security reasons. In my opinion
the "apt" package should either provide a default configuration which
achieves the (presently misleading) "daily" claim implied by the name of
the units or at least prominently document the limitations of the
configuration so users will know when they have to take action.

For those who prefer to do the latter by restoring the old behaviour I
append a shell script I'm presently using with anacron. Because
apt-compat refuses to act if systemd is running at all, irrespective of
the status of the apt timers, we can't use it unmodified in its present
form; I suggest that it should be changed to behave similar to my
script which would make the latter obsolete. The initial comments in the
script describe how it is intended to be used.

Regards,
Martin Lottermoser
-- 
Martin Lottermoser             martin.lottermo...@htp-tel.de
Greifswaldstrasse 28
38124 Braunschweig             http://home.htp-tel.de/lottermose2
Germany                        Telephone: +49 531 6802747
#!/bin/sh
#******************************************************************************
# File:     @(#)$OrigId: apt-daily,v 1.3 2023-08-18 08:24:09+02 martin Exp $
# Contents: anacron script replacing the apt-daily*.timer configurations
# Author:   Martin Lottermoser, Braunschweig, Germany;
#           martin.lottermo...@t-online.de
#
#******************************************************************************
#
#       Copyright (C) Martin Lottermoser, 2023
#       SPDX-License-Identifier: GPL-2.0
#
#******************************************************************************
#
# The switch from anacron to systemd as the triggering entity for unattended
# upgrades in Debian 11 (2021) led to unexpectedly changed behaviour. While the
# old solution basically ensured that a system running at least 30 minutes
# after a day's first boot would then have all the security updates issued up
# to a day ago, the default configuration for the new timer unit
# "apt-daily.timer" works as implied by its "daily" name part only for systems
# with a continuous runtime of at least 12 hours. Shorter-running systems have
# lesser chances of discovering security updates at all; a system running only
# for 1 hour per boot session, for example, has only a chance of 1/12 (8 %) per
# session, irrespective of how often it is booted.
#
# The timer configuration file which is the cause of this behaviour is part of
# the "apt" package but its maintainers have shifted the blame to "systemd" and
# have so far done nothing to fix this problem (first reported in October 2021;
# see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=997943).
#
# Users therefore have to correct this security-threatening behaviour
# themselves. One possibility is to reconfigure the timers, another is to
# revert to an anacron-based solution. The present file is intended for the
# second choice: just install the file in /etc/cron.daily and disable the apt
# timers with:
#
#   systemctl disable apt-daily.timer apt-daily-upgrade.timer
#
# It's also possible to disable only one of the timers in which case this
# script will take over only the job of that timer.
#
#******************************************************************************

name=`basename "$0"`

#******************************************************************************

if [ $# -ne 0 ]; then
  printf 'ERROR[%s]: No arguments permitted.\n' "$name" >&2
  exit 1
fi

# No action at all if there is no script to execute
script=/usr/lib/apt/apt.systemd.daily
test -f "$script" -a -x "$script" || exit 0

# No action if systemd isn't running; apt-compat will take over in that case.
test -d /run/systemd/system || exit 0
# Construct arguments for the script, depending on which timer is inactive
args=''
systemctl --quiet is-active apt-daily.timer || args="$args update"
systemctl --quiet is-active apt-daily-upgrade.timer || args="$args install"
test '' != "$args" || exit 0    # Both timers active; nothing to do.
test ' update install' != "$args" || args=''  # Neither active; full programme.

# Delay the execution randomly based on the same configuration variable and
# default value (30 min) as apt-compat
RandomSleep=1800
eval $(apt-config shell RandomSleep APT::Periodic::RandomSleep)
if [ 0 != "$RandomSleep" ]; then
  # Randomize, assuming a POSIX-conforming awk implementation
  to_sleep=$(awk 'BEGIN { srand(); print int(rand() * '"$RandomSleep"'); }' \
    /dev/null)
  # If this fails, $to_sleep should be empty and sleep below will immediately
  # return. Anacron will mail any error messages to root.

  # Sleep
  sleep $to_sleep

  # While we were sleeping the situation might have changed, hence:
  test -f "$script" -a -x "$script" || exit 0
fi

# Execute
exec "$script" $args

printf 'ERROR[%s]: exec failed.\n' "$name" >&2
exit 1

Attachment: signature.asc
Description: PGP signature

Reply via email to