Ubuntu: apt-key is deprecated

Gilles Legoux
13 min readJul 29, 2023

TL;DR apt-key is deprecated from Ubuntu 22.04 LTS (Jammy Jellyfish) for security flaws: don’t use it anymore whatever your Linux environment. Instead of using it, consider the command gpg now. Then move your public keys relative to your APT package manager to a new location with the binary format OpenPGP, and specify the option Signed-By (signed-by) for all your used package repositories.

Let’s follow this plan together to properly use your secure package management and see if you are not infected by these security flaws:

  • 🔒Understand the security flaws
  • 💡 Explore its workstation environment for apt and apt-key
  • 🔨 Use directly the gpg command to manage your new keys
  • ➡️ Migrate your current trusted public security keys to the correct format and location
  • ✅ Check the migration and stop the useapt-key, /etc/apt/trusted.gpg, /etc/apt/trusted.gpg.d/
  • ❔Questions
  • 🚀 Go further

🔒 Understand the security flaws

apt-key is a sub-command of apt to secure the management packages with asymmetric security keys. As you know, package management is a sensible area for security; it is an access door for an attacker to install malicious packages. That’s why when a package is installed, cryptography is used to validate that the installed package is really the one wishes (see Debian Wiki: SecureApt).

Security risks in package management

Here are the milestones of the lifecycle of a package until be installed:

  1. The package is produced on a build machine;
  2. The package is signed on the build machine with a private key;
  3. The signed package is uploaded to a repository (download mirror);
  4. The client system downloads the package (with its package dependencies before if needed) thanks to the metadata and the usage of its package manager from an authorized repository (or from cache);
  5. The signature of the package is verified (with its package dependencies before if needed) with the associated public key;
  6. If the signature is valid, the package is installed.

The developers of Debian and Ubuntu realized that the apt-key command has had flaws for a long time (see Security tracker: package apt and particularly CVE-2011–3374). While apt-key was not guaranteed to work people continue to use it, that’s why now this command line has been marked as deprecated (see Fully deprecate apt-key, schedule removal for Q2/2022 (ee284d59) · Commits · APT Developers / apt · GitLab) and will be deleted. Support for the function ends with Debian 11 (Bullseye) and Ubuntu 22.04 (Jammy Jellyfish).

The problem is to move all tech ecosystems because numerous documentations or blog posts are not up-to-date on this aspect, even the tech giant like Google: Linux Software Repositories where the usage of apt-key is still referenced in July 2023.

The home page of the Google Linux Software Repositories is not up-to-date with the usage of apt-key

Let’s understand an attack scenario among several ones possible. Even if by default, APT checks the validity of the signature of each package to install, and if it is invalid, a warning message is printed and the package is not installed. It is not sufficient because APT needs also to know which trusted public GPG key belongs to which package repository.

Effectively, APT can be configured to have several package repositories through the sources.list files (which is very often the case, see Debian Wiki: SourceList and Debian Wiki: Third Party). APT has a system of priority and inclusive list to choose which package repository is considered to install such or such packages (the same package can appear in different package repositories).

multi-authorized package repositories

With the usage of apt-key, the installed and trusted GPG public keys of each package repository are installed by default in the common file /etc/apt/trusted.gpg or in the common folder /etc/apt/trusted.gpg.d/. But if an entry of asources.list file (configuring a repository) does not have the option Signed-By (signed-by), then all public keys will be checked from the common file /etc/apt/trusted.gpg or in the common folder /etc/apt/trusted.gpg.d/ without making the difference if the signature is from the related package repository or other ones authorized.

Among your third-party repositories authorized, a malicious attacker could actually provide its own “version” of a package: google-chrome-stable signed by any GPG public keys that we have authorized. It should have access to a private key of one of the repositories authorized without having stolen it: it could be simply a package uploader of this repository. This security flaw has the highest severity level: Remote Code Execution (RCE) vulnerabilities allow an attacker to execute arbitrary code on a remote device.

Security vulnerabilities

Even if, this scenario can be complicated to set up for the malicious attacker (if you have only famous and globally trusted third repositories), it could do a lot of other things if it could do it. Beware that adding and using third-party repositories always poses a security and stability risk! You need to pay attention to which third-party repositories are authorized with which public keys.

To prevent this kind of vulnerability:

  1. Choose with attention your third-party repository;
  2. Configure the priority between the package repositories;
  3. Reduce the packages can be installed from a package repository with an inclusive list;
  4. Manage correctly the matching between a package repository and its related public key(s) serving to validate the signature of packages to install.

The first point can only be guaranteed by your vigilance (by default only trusted repositories are pre-authorized), you can also accept only your own private repository(-ies) and a list of possible packages to install. The next two points should be acceptable with the default configuration except if you are paranoid or you want to have a higher level of security policy. The last point requires us to stop to use apt-key, /etc/apt/trusted.gpg, /etc/apt/trusted.gpg.d/ and to use systematically correctly the option Signed-By (signed-by) by installing authorized public keys carefully.

💡Explore its workstation environment for apt and apt-key

Let’s discover it concretely to see if your environment is infected by this security flaw.

Suppose that I installed the GPG public keys of Google for Linux mentioned previously with apt-key add.

I am going to explore my workstation environment. The first thing to do is to check the versioning of my environment.

Ubuntu is based on the Debian GNU/Linux distribution and uses the same package management system (see Ubuntu Wiki: Development/Merging) with the same security layer (see Debian Wiki: SecureApt): apt and dpkg by default (other tools exist; see here).

I display the content of the files /etc/os-release and /etc/debian_version to see the version of Ubuntu and Debian used by your workstation environment. I use Ubuntu 22.04 (Jammy Jellyfish) based on Debian 12 (bookworm/sid) on an architecture AMD64 given by dpkg --print-architecture.

Ubuntu is based on the Debian GNU/Linux

The version of my APT installed is:

$ apt --version 
apt 2.4.9 (amd64)

Read the man page (see also Ubuntu Manpage: apt-key — Deprecated APT key management utility):

$ man apt-key

ℹ️ “apt-key will last be available in Debian 11 and Ubuntu 22.04.” And all commands are deprecated except apt-key del mostly deprecated for the migration to delete the keys

So now, I can check the source package: Ubuntu apt package: 2.4.9 , and the changelog Change log: apt package. If you inspect the source code, cmdline/apt-key.in: 2.4.9 is well the version of apt-key that I use locally (see cat "$(which apt-key)"). It is a simple shell script wrapper above the command line gpg (see The GNU Privacy Guard).

You can see a warning message when you execute apt update because the public key is badly installed to update Google Chrome:

$ sudo apt update
Hit:1 https://dl.google.com/linux/chrome/deb stable InRelease
Hit:2 http://archive.ubuntu.com/ubuntu jammy InRelease
Hit:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
Hit:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease
Hit:5 http://security.ubuntu.com/ubuntu jammy-security InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.
W: http://dl.google.com/linux/chrome/deb/dists/stable/InRelease: Key is
stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg),
see the DEPRECATION section in apt-key(8) for details.

ℹ️ Note that all the package repositories are not with HTTPS, but sometimes with HTTP only. It’s still safe. In fact, there is a small benefit to use HTTPS here, because the package signatures guarantee already that the package is authentic, see more details at How to use https with apt-get?. Not all package repositories expose the packages in HTTPS (even famous ones), but more and more do it, if you have the choice prefer using HTTPS, it costs nothing (except if you have specific performance challenges).

When I watch my public keys, I have:

$ apt-key list
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
/etc/apt/trusted.gpg
--------------------
pub dsa1024 2007-03-08 [SC]
4CCA 1EAF 950C EE4A B839 76DC A040 830F 7FAC 5991
uid [ unknown] Google, Inc. Linux Package Signing Key <linux-packages-keymaster@google.com>
sub elg2048 2007-03-08 [E]

pub rsa4096 2016-04-12 [SC]
EB4C 1BFD 4F04 2F6D DDCC EC91 7721 F63B D38B 4796
uid [ unknown] Google Inc. (Linux Packages Signing Authority) <linux-packages-keymaster@google.com>
sub rsa4096 2021-10-26 [S] [expires: 2024-10-25]
sub rsa4096 2023-02-15 [S] [expires: 2026-02-14]

The GPG public keys seem correct and valid with the right ids (compare it with the ids exposed on the web page provided by Google, see the screenshot above in the introduction) but I have another warning message for the usage of apt-key. My workstation is potentially infected by the security vulnerability mentioned.

🔨 Use directly the gpg command to manage your new keys

Before fixing this security vulnerability, you need to learn the tool to use after apt-key: the equivalent command is gpg.

Use gpg directly instead of apt-key

Explore gpg command with gpg --help and man gpg.

Equivalent command with gpg

️ I use here the format one-line-style but it is also recommended to use the format deb822 style see man sources.list and Debian Wiki: SourceList.

ℹ️ The keys are public keys. They can have permission 644 with the owner root and group root, here it is for all system users.

️Instead of using a file path to a public key in the option Signed-By (signed-by) you can also use the content of the public key directly with the textual format PGP ASCII-Armor (see Debian Wiki: Setup With Repository) if the format deb822 style is used in the “source.list” file.

⚠️ A file with the old textual format PGP ASCII-Armor or the binary format OpenPGP can contain several public keys, and each public key can contain several subkeys. Regroup correctly your keys to dedicated files when required (i.e provided from different package repositories to avoid a side effect that is the main root cause of the mentionned vulnerability).

⚠️Check well that this public key is owned by the associated repository (certified by a CA or exposed on the official page of the repository).

➡️ Migrate your current trusted public security keys to the correct format and location

Now, we are going to fix this security vulnerability.

Move all your GPG public keys from the file /etc/apt/trusted.gpg and the folder /etc/apt/trusted.gpg.d/ to /etc/apt/keyrings/ with the correct format.

ℹ️ Some packages prefer using /etc/apt/keyrings/ than /usr/share/keyrings/ see Ubuntu Manpage : sources.list and What is the right place to put keyrings?

“The recommended locations for keyrings are /usr/share/keyrings for keyrings managed by packages, and /etc/apt/keyrings for keyrings managed by the system operator. If no keyring files are specified the default is the trusted.gpg keyring and all keyrings in the trusted.gpg.d/ directory (see apt-key fingerprint).”

In addition in the Ubuntu Manpage: apt-key in the section DEPRECATION:

“Recommended: Instead of placing keys into the /etc/apt/trusted.gpg.d directory, you can place them anywhere on your filesystem by using the Signed-By option in your sources.list and pointing to the filename of the key. See sources.list(5) for details. Since APT 2.4, /etc/apt/keyrings is provided as the recommended location for keys not managed by packages. When using a deb822-style sources.list, and with apt version >= 2.4, the Signed-By option can also be used to include the full ASCII armored keyring directly in the sources.list without an additional file.”

I use /etc/apt/keyrings/ here but you can use the folder that you want.

Start by migrating the keys of /etc/apt/trusted.gpg, like in my case.

I identify the keys to migrate with:

$ apt-key list
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
/etc/apt/trusted.gpg
--------------------
pub dsa1024 2007-03-08 [SC]
4CCA 1EAF 950C EE4A B839 76DC A040 830F 7FAC 5991
uid [ unknown] Google, Inc. Linux Package Signing Key <linux-packages-keymaster@google.com>
sub elg2048 2007-03-08 [E]

pub rsa4096 2016-04-12 [SC]
EB4C 1BFD 4F04 2F6D DDCC EC91 7721 F63B D38B 4796
uid [ unknown] Google Inc. (Linux Packages Signing Authority) <linux-packages-keymaster@google.com>
sub rsa4096 2021-10-26 [S] [expires: 2024-10-25]
sub rsa4096 2023-02-15 [S] [expires: 2026-02-14]

These 2 keys can be migrated into the same file:

sudo mkdir -p /etc/apt/trusted.gpg.d && \
sudo apt-key export -o /etc/apt/trusted.gpg.d/google.asc \
D38B4796 7FAC5991

ℹ️ The migration be in one command with sudo apt-key export D38B4796 7FAC5991 | sudo gpg --dearmour -o /etc/apt/keyrings/google.gpg but I prefer doing in 2 steps here. Also the key 7FAC5991 is obsolete and could be deleted.

ℹ️ The short key identifiers D38B4796 and 7FAC5991 are got from the final 8 characters of the hexadecimal (last 32 bits) of the fingerprint.

Now explore the format of the created file:

$ file /etc/apt/trusted.gpg.d/google.asc
/etc/apt/trusted.gpg.d/google.asc: PGP public
key block Public-Key (old)

The format is the old textual format PGP ASCII-Armor, we need to export it in a binary format OpenPGP supported by gpg and move it to the right folder:

sudo mkdir -p /etc/apt/keyrings/ \
&& cat /etc/apt/trusted.gpg.d/google.asc \
| sudo gpg --dearmour -o /etc/apt/keyrings/google-chrome.gpg

Now the format is correct:

$ file /etc/apt/keyrings/google.gpg
/etc/apt/keyrings/google.gpg: OpenPGP Public Key Version 4,
Created Thu Mar 8 20:17:10 2007, DSA (1024 bits); User ID; Signature;
OpenPGP Certificate

You can remove the public keys with:

sudo apt-key del D38B4796 7FAC5991

ℹ️ If it fails because the format is incorrect remove the related file /etc/apt/trusted.gpgand/or in the folder /etc/apt/trusted.gpg.d/, it will be removed all keys inside the deleted file.

After updating the source list of apt for the package in the file /etc/apt/sources.list or in a file in the folder /etc/apt/sources.list.d/ to have:

deb [arch=amd64 signed-by=/etc/apt/keyrings/google.gpg] https://dl.google.com/linux/chrome/deb/ stable main

ℹ️ Adapt with your architecture dpkg --print-architecture here it is for me AMD64.

Then, you can migrate all the other potential keys that you have (not only for Linux Google packages) from the file /etc/apt/trusted.gpg and the folder /etc/apt/trusted.gpg.d/too. Once done, you can remove the file /etc/apt/trusted.gpg and the folder /etc/apt/trusted.gpg.d/.

✅ Check the migration and stop the use apt-key, /etc/apt/trusted.gpg and /etc/apt/trusted.gpg.d/

Check that all is correct:

$ sudo apt update
Hit:1 https://dl.google.com/linux/chrome/deb stable InRelease
Hit:2 http://archive.ubuntu.com/ubuntu jammy InRelease
Hit:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
Hit:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease
Hit:5 http://security.ubuntu.com/ubuntu jammy-security InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.

It should log no warning message.

$ apt-key list
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d
instead (see apt-key(8)).

It should show no key.

Finally, you can stop to use the command line apt-key, the file /etc/apt/trusted.gpg and the folder /etc/apt/trusted.gpg.d/.

❔Questions

What are the differences between apt, apt-cache, and apt-get?

apt and apt-get , apt-cache are command line tools. You can use them to manage software packages like applications and libraries on any Linux distribution based on Debian for workstations and server/container/VM instances. Briefly, apt for Advanced Package Tool (APT) is more recent, user-friendly, and should replace progressively apt-get andapt-cache : see Difference between apt, apt-get and apt-cache?.

What are the differences between GPG, Open PGP, and PGP?

GPG (GNU Privacy Guard): A popular open-source solution based on an implementation that follows the Open PGP standard and provides an interface for users to easily encrypt/sign/hash their files, see https://gnupg.org/.

OpenPGP (Open Pretty Good Privacy): The IETF-approved standard that describes any encryption technology that uses processes interoperable with PGP. See openpgp.org.

PGP (Pretty Good Privacy): A proprietary historical encryption solution owned by Symantec and now Broadcom. See here.

🚀 Go further

Play with apt by creating a docker container:

$ docker create -it --name ubuntu-22.04 ubuntu:jammy
$ docker start ubuntu-22.04
$ docker exec -it ubuntu-22.04 /bin/bash
container (root)$ unminimize
container (root)$ apt update && apt install curl wget gnupg file sudo vim man-db
  • Understand deeply how APT works by reading the doc and the source code and experimenting with the command apt(activate the debug mode sudo apt -oDebug::pkgAcquire::Worker=1 update).
  • Try to mimic an attack scenario on apt.
  • Change the policy of validation by playing with the parameters allow-insecure=yes or trusted=yes and signed-by for example (and all other ones).
  • Explore the subkeys, read Debian Wiki: Subkeys
  • Try to produce the HTTPS validation error with apt and to force a certificate or not check it:
Certificate verification failed: The certificate is NOT trusted. The certificate issuer is unknown.  Could not handshake: Error in the certificate verification. [IP: XX.XXX.XX.XX 443]

--

--

Gilles Legoux

💻 Senior Software Engineer on Data and Applied Machine Learning. Here are posts about all these aspects of engineering. More details: https://glegoux.com