Skip to content

Instantly share code, notes, and snippets.

Last active March 23, 2023 00:39
What would you like to do?
debian testing with automatic security updates from unstable
APT::Default-Release "testing";
APT::Update::Pre-Invoke { "/usr/sbin/debsecan-apt-priority"; };


WARNING: these commands can be very disruptive. review each of the files in this gist and on the filesystem which they will replace before executing the commands below.

when you run apt update, this script will be executed automatically. for each vulnerable package in testing which has been fixed in unstable, it will create a priority 990 pin for the unstable package.



It is a good idea to install security updates from unstable since they take extra time to reach testing and the security team only releases updates to unstable. If you have unstable in your apt sources but pinned lower than testing, you can automatically add temporary pinning for packages with security issues fixed in unstable using the output of debsecan.


these scripts assume that you are running debian testing and have enabled the unstable repositories but pinned at a lower priority by default.

this can usually be achieved by running the command below. USE WITH CAUTION and check that the output of apt update && apt full-upgrade --autoremove --purge looks reasonable before proceeding.

curl | sh

apt update && apt full-upgrade --autoremove --purge


the command below will change your sources.list to debian testing, enable the unstable repositories pinned at a lower priority and configure debsecan to run with each apt update.

execute the following commands as root to install/enable:

curl | sh

apt update && apt full-upgrade --autoremove --purge

you can view the list of packages which will be installed from unstable in /var/lib/debsecan/apt_preferences

special cases

i recommend always running chromium and firefox from unstable.

this can be achieved with the following command:

curl -o /etc/apt/preferences.d/unstable-packages

apt update && apt install -y chromium firefox


note: uninstalling will not downgrade packages to their testing versions. you will need to do this yourself or wait for the packages to catch up on their own (which should typically happen within a few weeks).

curl | sh
set -ex
curl -o /etc/apt/apt.conf.d/00default-release
curl -o /etc/apt/preferences.d/default-priority
curl -o /etc/apt/sources.list
# this program will add APT pinning for packages that are fixed in
# unstable and not testing
# see
set -e
echo "running debsecan check for issues fixed in unstable..." >&2
rm -f /var/lib/debsecan/apt_preferences.disabled
cat > /var/lib/debsecan/apt_preferences.disabled <<EOF
# pin packages with security issues fixed in unstable
# generated automatically on $(date) by $0
for pkg in $(debsecan --suite=sid --only-fixed | cut -d\ -f2 | sort -u) ; do
case "$pkg" in
echo "adding pin to suite $suite for package $pkg" >&2
cat <<EOF >> /var/lib/debsecan/apt_preferences.disabled
Package: $pkg
Pin: release a=$suite
Pin-Priority: 990
chmod 644 /var/lib/debsecan/apt_preferences.disabled
mv --force /var/lib/debsecan/apt_preferences.disabled /var/lib/debsecan/apt_preferences
Package: *
Pin: release a=unstable
Pin-Priority: 50
set -ex
rm -f /etc/apt/preferences.d/unstable-security-packages
rm -f /etc/apt/apt.conf.d/99debsecan
apt update
set -ex
apt install -y debsecan
curl -o /usr/sbin/debsecan-apt-priority
curl -o /etc/apt/apt.conf.d/99debsecan
chmod 755 /usr/sbin/debsecan-apt-priority
ln -sf /var/lib/debsecan/apt_preferences /etc/apt/preferences.d/unstable-security-packages
deb testing main non-free contrib
deb-src testing main non-free contrib
deb testing-security main contrib non-free
deb-src testing-security main contrib non-free
deb unstable main non-free contrib
deb-src unstable main non-free contrib
Package: chromium chromium-sandbox chromium-common
Pin: release a=unstable
Pin-Priority: 990
Package: firefox libnss3 libnss3:i386 libnss3-dev
Pin: release a=unstable
Pin-Priority: 990
Copy link

@martin-braun -- this is needed because there is still a delay (sometimes as long as weeks) between fixes entering testing-security from the unstable repo.

Copy link

@khimaros Thanks for the quick reply, I already removed my comment, because I realized this by myself. However one more thing:

This looks wrong to me, shouldn't the first EOF stay behind like at ?

In any case, I will try this on a clean Debian in combination with additional Sparky repositories, will see how it goes. Thanks for your work.

Copy link

@martin-braun -- either syntax works. actually, i should mention that this file actually came from another repository which was originally started collaboratively on this bug:

Copy link

@khimaros Great, thanks a lot! :) I'm using your solution and I hope it will work out in the long run. Thanks sharing!

Copy link

jmzumg commented May 17, 2022


Thank you for the instructions and scripts here. There were extremely enlightening.

However I believe there is one small error in the instructions in

I believe the following line:

ln -sf /var/lib/debsecan/apt_priorities /etc/apt/preferences.d/unstable-security-packages

should actually read:

ln -sf /var/lib/debsecan/apt_preferences /etc/apt/preferences.d/unstable-security-packages

Otherwise the symbolic link points to a non-existent file. apt outputs the following error:

N: Ignoring `unstable-security-packages` in directory '/etc/apt/preferences.d/ as it is not a regular file

and the packages pinned by debsecan do not get upgraded.

I have tested using ln -sf /var/lib/debsecan/apt_preferences /etc/apt/preferences.d/unstable-security-packages instead and everything seems to work.

Thanks again for the instructions :)

Copy link

khimaros commented Jun 7, 2022

@jmzumg thank you, updated!

Copy link

I think that for bookworm+ that you need to add non-free-firmware to the sources.list file.

Thanks for maintaining this!

Copy link

crpb commented Dec 16, 2022

A suggestion
I would change the content of /etc/apt/apt/conf.d./99debscan to

APT::Update::Post-Invoke { "/usr/sbin/debsecan-apt-priority"; };

just to make sure we have the latest Info before doing any pinning'.

I ran into the issue that it did pin some package which wasn't available anymore because the system wasn't running for a few days and so a second apt-get update was needed to "fix" that 🙈

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment