######################################################
Debian Apt Pinning: Restricting Packages By Repository
######################################################
.. note::
This document is quite old and much of the pinning world has changed
since I had need to write it. I believe that this kind of work is
still necessary to achieve safe mix-and-match of repositories, but
I will not be surprised if this documentation no longer achieves it
intended effects.
Introduction
############
`Debian `_ uses `Apt
`_ as a high-level wrapper around
its package manager tool, `dpkg `_,
which does all the low-level work of maintaining files and such.
Apt supports multiple repositories: https://wiki.debian.org/SourcesList .
Internally, apt understands that each repository came from somewhere (the
``origin``, not to be confused with the ``Origin`` metadata tag) and has
several metadata labels. These are enumerated in the `apt_preferences man
page `_, but briefly, any
and all ``Origin``, ``Archive``, ``Suite``, ``Codename``, ``Version``
(release version, they mean), ``Component``, and ``Label`` metadata comes
from the ``InRelease`` file of the repository.
If you have, for example, in your ``/etc/apt/sources.list`` or in a
file in ``/etc/apt/sources.list.d`` the line ::
deb http://archive.zfsonlinux.org/debian jessie main
Then after an ``apt-get update`` you will have the file
``/var/lib/apt/lists/archive.zfsonlinux.org_debian_dists_jessie_InRelease``
which will begin something like::
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Origin: archive.zfsonlinux.org
Label: ZoL
Codename: jessie
Date: Thu, 28 May 2015 14:41:09 UTC
Architectures: amd64
Components: main
Among other things, this file is used as a kind of Merkel tree root: it
contains strong hashes of all the subordinate metadata files, which in turn
contain strong hashes of the packages themselves. This allows apt to
validate a download without much overhead, since it had to fetch the index
and metadata anyway.
The ``apt-cache policy`` tool is very handy to see how Apt thinks of its
repositories.
Metadata Is Not Trustworthy
###########################
There is no reason to believe that the self-declared ``Origin:`` or
``Label:`` tags will be unique among repositories, which frustrates pinning.
There is no way for a system administrator to bind an Origin or Label to a
particular key (see `the apt-key manpage
`_ for more about what *can* be
done with a system's Apt root of trust.)
Restricting Non-Debian Repos
############################
If we wish to restrict the set of packages that a given repository can
install on our system, then, we're in some amount of trouble: we can trust
the repository maintainer to provide stable and consistent ``Origin`` or
``Label`` metadata (and, to be fair, most of them do) or we could be more
forceful and match on the ``origin`` URL itself for all our decisions.
We may wish to do this if we, for example, prefer the Debian version of a
package that is also provided in a repository along with packages that we do
want to install.
Towards the end of not relying on anyone to manage metadata correctly,
here's my ``/etc/apt/preferences.d/pin.pref`` file, with some commentary
between each section. This file is read in a first-match way, first without
globs, then with. Thus, we start with a list of packages that we *do* want
from non-Debian repositories::
Package: grub-common grub-pc grub-pc-bin grub2-common
Pin: origin archive.zfsonlinux.org
Pin-Priority: 510
Package: libnvpair1 libuutil1 libzfs-dev libzfs2 libzpool2
Pin: origin archive.zfsonlinux.org
Pin-Priority: 510
Package: debian-zfs spl spl-dkms zfs-dkms zfs-initramfs zfsonlinux zfsutils
Pin: origin archive.zfsonlinux.org
Pin-Priority: 510
Package: syncthing
Pin: origin apt.syncthing.net
Pin-Priority: 510
.. note::
There's no particular reason, other than presentation, that there are
three stanzas with the same ``origin`` here.
Now we use globs to *disable* all non-Debian origins. This must be kept up
to date as new repositories are added. ::
Package: *
Pin: origin archive.zfsonlinux.org
Pin-Priority: -1
Package: *
Pin: origin apt.syncthing.net
Pin-Priority: -1
Now, having eliminated those, we can give rules for the parts
of Debian that we *do* want. Note that these do *not* match on the
``origin``, which is why it is important that all non-Debian ``origin``
values have been eliminated already::
Package: *
Pin: release a=stable, o=Debian
Pin-Priority: 900
Package: *
Pin: release a=unstable, o=Debian
Pin-Priority: 800
Last, disable everything else from Debian::
Package: *
Pin: origin ftp.us.debian.org
Pin-Priority: -1