apt-key is deprecated, now what?

It’s only a few weeks since I upgraded one of my systems from Debian 10 to Debian 11. In fact, I use to apply a “Debian distribution quarantine”: when a new major version of the distribution is out, I usually wait until a “.1” or “.2” minor version before installing it, as I don’t have enough time to debug problems that may have escaped Debian’s QA process at the very first release.

One of the first things that catch one’s attention when I ran the apt-key command in Debian 11 (e.g. a simple apt-key list) was a warning:

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

“Deprecated” usually means that a certain functionality will be eventually removed from the system. In this case, Ubuntu users will be hit already in 2022 with the release of 22.10 in October as the command will be available last in the next LTS (22.04) to be released in April. Debian users will have more time, as the command won’t available in the next major release of Debian (supposedly Debian 12, that may be a couple of years away). This is written in clear letters in the man page:

apt-key(8) will last be available in Debian 11 and Ubuntu 22.04.

So, what are you supposed to do now in order to manage the keys of third party APT repositories?

What the official documentation says

Debian’s documentation is a bit misleading in this regard. In fact in the man page itself you will see a suggestion to deploy keys directly in /etc/apt/trusted.gpg.d/:

           Note: Instead of using this command a keyring should be
           placed directly in the /etc/apt/trusted.gpg.d/ directory
           with a descriptive name and either "gpg" or "asc" as file
           extension.

Towards the end of the man page you also read that trusted.gpg and trusted.gpg.d are the only places where keys are to be stored:

FILES
       /etc/apt/trusted.gpg
           Keyring of local trusted keys, new keys will be added here.
           Configuration Item: Dir::Etc::Trusted.

       /etc/apt/trusted.gpg.d/
           File fragments for the trusted keys, additional keyrings
           can be stored here (by other packages or the
           administrator). Configuration Item Dir::Etc::TrustedParts.

The file extension “.asc” suggests that ASCII-armored, non-binary keyrings can be used, and they actually can, but according to the Debian Wiki, things look a bit different. The document is a bit hard to read in that it tries to address both repository owners and consumers at the same time, so let me try to summarise that for you:

  • the use of ASCII-armored files is discouraged;
  • key files go in /usr/share/keyrings and not in /etc/apt/trusted.gpg.d/;
  • the signed-by clause must be used in the APT source files to map each repository to its key.

So, what should you do?

The easy and insecure way

Instead of using apt-key add, you download the key directly in /etc/apt/trusted.gpg.d/, with ownership root:root, permissions 644 and extension .gpg if the file is binary, or .asc if the key is ASCII-armored.

In the example below, we download two keys from two repositories, one in ASCII format and one binary, and we deploy them in trusted.gpg.d.

# run your shell as root
sudo -s

cd /etc/apt/trusted.gpg.d

# ASCII key, download in a file with extension .asc
wget -O foo-archive-keyring.asc https://foo.example.com/repo/foo-repo-key.gpg

# Binary key, 
wget -O bar-archive-keyring.gpg https://bar.example.com/repo/bar-repo-key.gpg

# Set ownerships and permissions
chown root:root foo-archive-keyring.asc bar-archive-keyring.gpg
chmod 644 foo-archive-keyring.asc bar-archive-keyring.gpg

After this, you can create a source file as usual and run apt update to both update the package cache and make apt aware of new keys.

Just a tad safer

Similar to the one above, but:

  • you only download via secure protocols (e.g. HTTPS) and check the site’s SSL/TLS certificate to be extra sure that the repository is actually owned by the legitimate organisation;
  • you convert ASCII-armored keys to the binary format before you deploy them to trusted.gpg.d.

In the example below, we download an ASCII key and we convert it to binary format before we deploy it to trusted.gpg.d.

# ASCII key, download in a file with extension .asc
wget -O foo-archive-keyring.asc https://foo.example.com/repo/foo-repo-key.gpg

# Convert it to binary format and deploy it in trusted.gpg.d
sudo gpg --dearmor --output /etc/apt/trusted.gpg.d/foo-archive-keyring.gpg foo-archive-keyring.asc

# Set ownerships and permissions as above
sudo chown root:root /etc/apt/trusted.gpg.d/foo-archive-keyring.gpg
sudo chmod 644 /etc/apt/trusted.gpg.d/foo-archive-keyring.gpg

After this, you can create a source file as usual and run apt update to both update the package cache and make apt aware of new keys.

  • You only download via secure protocols (e.g. HTTPS) and check the site’s SSL/TLS certificate to be extra sure that the repository is actually owned by the legitimate organisation;
  • you convert the ASCII-armored keys to the binary format;
  • you deploy keys in /usr/share/keyrings;
  • you use the signed-by option in source files.

In the example below we add a new repository to the system in the recommended way:

# ASCII key, download in a file with extension .asc
wget -O foo-archive-keyring.asc https://foo.example.com/repo/foo-repo-key.gpg

# Convert it to binary format and deploy it in /usr/share/keyrings
sudo gpg --dearmor --output /usr/share/keyrings/foo-archive-keyring.gpg foo-archive-keyring.asc

# Set ownerships and permissions as above
sudo chown root:root /usr/share/keyrings/foo-archive-keyring.gpg
sudo chmod 644 /usr/share/keyrings/foo-archive-keyring.gpg

Now you can add the source in the usual way, except that you need to also specify a signed-by clause: whereas you would have added a source with a line like this:

deb https://foo.example.com/repo/ stable main

you would now use:

deb [signed-by=/usr/share/keyrings/foo-archive-keyring.gpg] https://foo.example.com/repo/ stable main

And wherever you already had other clauses already, e.g.:

deb [arch=amd64] https://foo.example.com/repo/ stable main

you’ll add the signed-by clause separating it from the others with a space, e.g.:

deb [arch=amd64 signed-by=/usr/share/keyrings/foo-archive-keyring.gpg] https://foo.example.com/repo/ stable main

Dearmoring keys in scripts

When running gpg --dearmor in scripts keep two things in mind:

  • you must add the --batch option and the --no-tty option for good measure
  • gpg will refuse to overwrite an existing file, so move an existing key out of the way if you are going to update it.

More info

One could observe that even the safer of the options illustrated above doesn’t add much to security: that is the topic for the second article of this series: apt-key is deprecated, part 2.

The Linux Uprising web site also has a very nice article on the subject, with many examples. It also covers key removal.

You may want to read the page “Instructions to connect to a third-party repository” in the Debian Wiki. As said above, it has all the information you need to know about the subject, although it may be a bit confusing for an end user in that it addresses both repository owners and consumers.

2 thoughts on “apt-key is deprecated, now what?

  1. Pingback: apt-key is deprecated, part 2 | A sysadmin's logbook

  2. Thank-you. The sloppiness in this is a nightmare when one is a noob and trying to learn how things work. I have a ‘new’ system that was already hacked (password changes when you first go online, reboot and password is back to normal, never seen elsewhere ever even with same OS version and methods).

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.