Ubuntu 22.04 and apt-key deprecation
by Ty Myrddin
Published on May 12, 2022
After upgrading to Ubuntu 22.04 from 20.04 several repositories are disabled, and deprecation warnings on its signing keys are given.
The apt-key deprecation message reads, "Warning: apt-key is deprecated. Manage
keyring files in trusted.gpg.d instead (see apt-key(8))
", and "Key is stored in legacy trusted.gpg
keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details.
"
Long story short, installing a key in the global keyring the way we used to mean that any packages
signed by that key are trusted. The new [signed-by]
option limits the damage when a repository's
keys are compromised; the key cannot be used to forge packages unrelated to the repository itself and limits
the damage done.
New repositories need to be signed in a different way, and existing keys need to be exported to
/usr/share/keyrings
and the associated source.list
files adapted to reflect that
change.
Below is a summarized version of applying the excellent instructions given by Debian and apt-key Is Deprecated. How To Add OpenPGP Repository Signing Keys Without It On Debian, Ubuntu, Linux Mint, Pop!_OS, Etc. for our setup in Ubuntu 22.04.
Note that curl
can be used instead of wget
, and that key extensions can also be
.pgp
, .asc
, .key
, .whatever
, as long as it is a key in a
format apt
supports. If a key is not ascii-armored, gpg
will exit successfully
without changing anything. If apt chokes on the resulting key, it is likely because the key is in another
format like the newer binary "keybox database" format, which apt does not support.
Adding keys the new way
Checking whether a key is armored:
$ wget https://example.com/key/repo-key.gpg
$ file repo-key.gpg
If the answer is repo-key.gpg: PGP public key block Public-Key (old)
, then it is an armored key,
but there is no harm in piping through --dearmor
by default.
Armored keys:
$ wget -O- <https://example.com/key/repo-key.gpg> | gpg --dearmor | sudo tee /usr/share/keyrings/<myrepository>-archive-keyring.gpg
Non-armored keys:
$ wget -O- <https://example.com/key/repo-key.gpg> | sudo tee /usr/share/keyrings/<myrepository-archive-keyring.gpg>
Getting keys from a keyserver:
$ sudo gpg --no-default-keyring --keyring /usr/share/keyrings/<myrepository>-archive-keyring.gpg --keyserver <hkp://keyserver.ubuntu.com:80> --recv-keys <fingerprint>
All keys will be stored in the /usr/share/keyrings/
folder to be used in adding the repository
with the signed-by
option in a sources.list
file.
The sources.list files
Each of the sources.list
files in /etc/apt/sources.list.d/
is to contain a
[signed-by]
reference to its own key:
deb [arch=amd64 signed-by=/usr/share/keyrings/<myrepository>-archive-keyring.gpg] https://repository.example.com/debian/ stable main
Example
An example of adding the repository for helm
, signing with its armored key, the old way:
$ curl https://baltocdn.com/helm/signing.asc | sudo apt-key add -
$ echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
And the new way:
$ wget -O- https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm-archive-keyring.gpg
[sudo] password for [user]:
$ echo "deb [signed-by=/usr/share/keyrings/helm-archive-keyring.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm.list
Exporting existing signatures
In order to be able to keep using the existing list of signatures and enable the disabled repositories again, it
is necessary to export the individual keys to individual signature files. The below method also works for
re-enabling repositories that use install scripts and do not have their signing keys listed on their sites,
like for nordvpn
and slack
.
Moving keys from /etc/apt/trusted.gpg.d
First move all existing keyring files in /etc/apt/trusted.gpg.d/
to the (newly created)
/usr/local/share/keyrings/
directory as-is.
/etc/apt/trusted.gpg.d$ sudo mv repo-key.gpg /usr/share/keyrings/
Then, using an editor of choice, update all the corresponding .list
files in
/etc/apt/sources.list.d
to have the [signed-by]
field referencing its own key
(as described above), and remove the hash that disabled the repository.
Exporting keys from /etc/apt/trusted.gpg
List all remaining keys:
$ apt-key list
Remove all expired keys to shrink the list:
$ sudo apt-key del [last 8 digits]
Export a useful key:
$ apt-key export [last 8 digits]|sudo gpg --dearmor -o /usr/share/keyrings/<myrepository>-archive-keyring.gpg
Example exporting slack
signing key in /etc/apt/trusted.gpg
pub rsa4096 2014-01-13 [SCEA] [expired: 2019-01-12]
418A 7F2F B0E1 E6E7 EABF 6FE8 C2E7 3424 D590 97AB
uid [ expired] packagecloud ops (production key) <ops@packagecloud.io>
pub rsa4096 2016-02-18 [SCEA]
DB08 5A08 CA13 B8AC B917 E0F6 D938 EC0D 0386 51BD
uid [ unknown] https://packagecloud.io/slacktechnologies/slack (https://packagecloud.io/docs#gpg_signing)
sub rsa4096 2016-02-18 [SEA]
Remove the expired key:
$ sudo apt-key del D59097AB
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
OK
Export the useful key:
$ apt-key export 038651BD|sudo gpg --dearmor -o /usr/share/keyrings/slack-archive-keyring.gpg
Change the slack.list
file in /etc/apt/sources.list.d
:
deb [arch=amd64 signed-by=/usr/share/keyrings/slack-archive-keyring.gpg] https://packagecloud.io/slacktechnologies/slack/debian/ jessie main
Now remove the just exported key from /etc/apt/trusted.gpg
:
$ sudo apt-key del 038651BD
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
OK
And such for each key in the key list for trusted.gpg
(not trusted.gpg.d
).
Test with sudo apt update
all is well.
WHERE'S MY COW?! Wyrd Sisters