How to properly add 3rd party package repositories to Debian distros
-
How to add 3rd party repositories
There is some confusion how to add 3rd party repositories to Debian based distros. In part because best practice has changed a few times and also because there are lots of incorrect info floating around everywhere and it is copy & pasted over and over.
How does repositories work
A debian package repository is nothing more than straight files on a webserver, layed out in a particular way. To make sure the packages we are downloading and installing haven't been tampered with, debian package system (
apt
) uses SHA256 file hashes. To make sure the file hashes haven't been tampered with, debian uses cryptographically signed files, aka gpg keys or openpgp keys.Debian and Ubuntu already comes pre-installed with their own gpg keys but we need to add 3rd party repositories manually or in some case through pre-built packages.
Finding the gpg key
There is no standard location where to find the gpg key needed but usually the file is on the repository website and it's exact URL in the installation instructions.
Let's use postgreSQL as an example.
Looking at their outdated documentation we will find the repositories public key at https://www.postgresql.org/media/keys/ACCC4CF8.asc
Binary and ascii armored gpg keys
Keys can be in binary format or ascii encoded (aka ascii armored). Debian package system can handle both but the files need to have the proper file extension.
- binary files should be
*.gpg
- ascii armored should be
*.asc
Most package repositories use ascii armored key files but it can have any name regardless. Common examples are:
- *.gpg
- * .asc
- * .key
- *.gpg.key
How to determine what type of key file
If we open the key file we can immediately verify what type of key it is because ascii armored keys start with
-----BEGIN PGP PUBLIC KEY BLOCK-----
To show the start of the file straight from the shell run:
curl -sL https://www.postgresql.org/media/keys/ACCC4CF8.asc | head -1
Where to add the key file
To add this key to your system it should be placed in
/etc/apt/keyrings/
and nowhere else. For more info runman sources.list
on a current debian distro.Older distros doesn't have that directory but you can just create it it as root with
mkdir /etc/apt/keyrings
. It should get the right permissions but it's 0755.So to get the key from PostgreSQL using
curl
and put it in the right place do this as root:curl -sL https://www.postgresql.org/media/keys/ACCC4CF8.asc > /etc/apt/keyrings/postgresql.asc
Add repository info
Now we need to add the repository URL and tell the package system which key to use.
3rd party URL should be added in the
/etc/apt/sources.list.d
directory by creating one config file for every repository with the name*.list
What distro / code name are we running?
Often we need to know what specific distro and version/code name we are using because package repositories can often handles many different ones.
Debian 12 for example is code name bookworm. If you want to script this you can use
$(lsb_release -cs)
to get the code name (needs to have packagelsb-release
installed).Note:
If you find a reference tostable
in the package repository documentation, it's probably wrong. Stable is used to refer to the current stable debian distro, but that changes every two years as soon as a new version becomes stable. And that breaks your repository information. Best practice is to use the code name and not stable.Content of the config files for apt
The config file we are creating for postgreSQL should have the following basic info:
deb http://apt.postgresql.org/pub/repos/apt bookworm-pgdg main
But we also need to add the information about what key to use:
deb [signed-by=/etc/apt/keyrings/postgresql.asc] http://apt.postgresql.org/pub/repos/apt bookworm-pgdg main
To create the config file as root do:
echo "deb [signed-by=/etc/apt/keyrings/postgresql.asc] http://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" > /etc/apt/sources.list.d/postgresql.list
Run
man sources.list
for more info on what options are avalable in the apt config files.Checking that the repository is up
Run
apt update
and the new repository should appear.So you see
The following signatures couldn't be verified because the public key is not available
?
Then something is wrong with your key file or it's location.If everything looks good your system is ready to install packages from the new repository with
apt install
Check repositories and priority
Run
apt policy
if you want to check what repositories your system have.
This also show the priorities of the different repositories and tellsapt
what to do when the same package is available in different repositories. Runman apt_preferences
for more info on that.Misc tools
- To list what packages you have installed on your system run
dpkg -l
- To check what version a package is and what repository will be used to install it, run
apt info <packagename>
- for exampleapt info postgresql
Uninstall repository
To uninstall a 3rd party repository we just need to:
- remove the config file from /etc/apt/sources.list.d
- remove the key file from /etc/apt/keyrings
And then run
apt update
to refresh the package list.In our example:
rm /etc/apt/sources.list.d/postgresql.list rm /etc/apt/keyrings/postgresql.asc apt update
Things to look out for
- don't use
apt-key
, it has been deprecated - don't put keys anywhere but
/etc/apt/keyrings
, it's outdated - no need to convert key types with
gpg
- if you see gpg used you know it's outdated - don't run unvetted install scripts as root to install 3rd party packages, it's unsafe. Looks like this:
curl unknownscript.sh | bash -
- verify that you actually need the 3rd party repository with your current version - in many cases you don't
- check that you have the packages needed. Debian minimal install doesn't have
curl
installed by default for example - you need either
curl
orwget
to download files - when you see both used in a script you know it's a mishmash of multiple sources
- binary files should be
-
Alternative to manually install 3rd party repositories
There is an alternative to manually manage repositories and keys and that is to use
extrepo
extrepo
is a curated list of 3rd party repositories and keys and it's a debian package.
It's only been around a couple of years so I don't know how widely used it is yet.Installation
To install it run
apt install extrepo
Add repository
To add postgreSQL repository for example:
extrepo enable postgresql
Disable repository
To disable a repository, for example:
extrepo disable postgresql
Where do files go?
extrepo
puts apt config files in/etc/apt/sources.list.d
as you would manually but manages keys in it's own directory/var/lib/extrepo/keys
Repositories available
Currently these repositories are in there:
- anydesk
- apertium-nightly
- apertium-release
- bareos
- belgium_eid_continuous
- brave_beta
- brave_nightly
- brave_release
- caddyserver
- consol
- debian_official
- dns-oarc
- docker-ce
- edge
- elbe
- eturnal
- eyrie
- fai
- feistermops
- gitlab_ce
- gitlab_ee
- gitlab_runner
- google_chrome
- google_cloud
- grafana
- grafana_beta
- grafana_enterprise
- grafana_enterprise_beta
- haproxy-2.8
- i2pd
- janitor
- jellyfin
- jenkins
- jitsi-stable
- kea
- keybase
- kicksecure
- kicksecure_developers
- kicksecure_proposed
- kicksecure_testers
- lihas
- liquorix
- matrix
- mobian
- msteams
- neurodebian_software
- newrelic
- nginx
- node_12.x
- node_14.x
- node_16.x
- node_18.x
- notesalexp
- ooni
- openmodelica-contrib-nightly
- openmodelica-contrib-release
- openmodelica-contrib-stable
- openmodelica-nightly
- openmodelica-release
- openmodelica-stable
- openstack_antelope
- openstack_zed
- openvpn
- opera_stable
- opsi
- passbolt
- postgresql
- prosody
- proxmox-ceph-quincy
- proxmox-pve
- proxmox-pve8
- r-project
- raspberrypi
- raspbian-addons
- realsense
- rspamd
- signal
- skype
- slack
- speedtest-cli
- spotify
- steam
- surface-linux
- sury
- syncevolution
- syncthing
- teamviewer_default
- teamviewer_preview
- torproject
- trinity
- vector
- vscode
- vscodium
- weechat
- whonix
- whonix_developers
- whonix_proposed
- whonix_testers
- winehq
- wire-desktop
- wire-internal-desktop
- wtf
- wtf-lts
- x2go
- x2go-extras
- x2go-lts
- x2go-nightly
- xpra
- xpra-beta
- yarnpkg
- zammad
- zulu-openjdk