Using 3rd party Debian repository keys with apt
mikas blog » Blog Archive

				(Blogging this, since this is a recurring anti-pattern I noticed at several customers and often comes up during deployments of 3rd party repositories.)
Update on 2021-02-19: clarified, that Signed-By requires apt >= 1.1, thanks Vincent Bernat
Many upstream projects provide Debian repository instructions like this:
curl -fsSL https://example.com/stable/debian.gpg | sudo apt-key add -

Do not follow this, for different reasons, including:

You do not see what you get before adding the GPG key to your global apt trust store
You can’t easily script this via your preferred configuration management (the apt-key manpage clearly discourages programmatic usage)
The signing key is considered valid for all your enabled Debian repositories (instead of only a specific one)
You need GnuPG (either gnupg2 or gnupg1) on your system for usage with apt-key

There’s a much better approach to this: download the GPG key, make sure it’s in the appropriate format, then use it via `deb [signed-by=/usr/share/keyrings/�]` in your apt’s sources list configuration. Note and FTR: the Signed-By feature is available starting with apt 1.1 (so apt in Debian jessie/8 and older does not support it).
TL;DR:

Install GPG keys in ascii-armored / old public key block format as /usr/share/keyrings/example.asc and use `deb [signed-by=/usr/share/keyrings/example.asc] https://example.com/�` in apt’s sources.list configuration
Install GPG keys in binary OpenPGP format as /usr/share/keyrings/example.gpg and use `deb [signed-by=/usr/share/keyrings/example.gpg] https://example.com/…` in apt’s sources.list configuration

As an example, let’s demonstrate this with the Tailscale Debian repository for buster.
Downloading the GPG file will give you an ascii-armored GPG file:
% curl -fsSL -o buster.gpg https://pkgs.tailscale.com/stable/debian/buster.gpg
% gpg --keyid-format long buster.gpg 
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
pub   rsa4096/458CA832957F5868 2020-02-25 [SC]
      2596A99EAAB33821893C0A79458CA832957F5868
uid                           Tailscale Inc. (Package repository signing key) <info@tailscale.com>
sub   rsa4096/B1547A3DDAAF03C6 2020-02-25 [E]
% file buster.gpg
buster.gpg: PGP public key block Public-Key (old)

If you have apt version >= 1.4 available (Debian >=stretch/9 and Ubuntu >=bionic/18.04), you can use this file directly as follows:
% sudo mv buster.gpg /usr/share/keyrings/tailscale.asc
% cat /etc/apt/sources.list.d/tailscale.list
deb [signed-by=/usr/share/keyrings/tailscale.asc] https://pkgs.tailscale.com/stable/debian buster main
% sudo apt update
[...]

And you’re done!
Iff your apt version really is older than 1.4, you need to convert the ascii-armored GPG file into a GPG key public ring file (AKA binary OpenPGP format), either by just dearmor-ing it (if you don’t care about checking ID + fingerprint):
% gpg --dearmor < buster.gpg > tailscale.gpg

… or if you prefer to go via GPG, you can also use a temporary GPG home directory (if you don’t care about going through your personal GPG setup):
% mkdir --mode=700 /tmp/gpg-tmpdir
% gpg --homedir /tmp/gpg-tmpdir --import ./buster.gpg
gpg: keybox '/tmp/gpg-tmpdir/pubring.kbx' created
gpg: /tmp/gpg-tmpdir/trustdb.gpg: trustdb created
gpg: key 458CA832957F5868: public key "Tailscale Inc. (Package repository signing key) <info@tailscale.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1
% gpg --homedir /tmp/gpg-tmpdir --output tailscale.gpg  --export-options=export-minimal --export 0x458CA832957F5868
% rm -rf /tmp/gpg-tmpdir

The resulting GPG key public ring file should look like that:
% file tailscale.gpg 
tailscale.gpg: PGP/GPG key public ring (v4) created Tue Feb 25 04:51:20 2020 RSA (Encrypt or Sign) 4096 bits MPI=0xc00399b10bc12858...
% gpg tailscale.gpg 
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
pub   rsa4096/458CA832957F5868 2020-02-25 [SC]
      2596A99EAAB33821893C0A79458CA832957F5868
uid                           Tailscale Inc. (Package repository signing key) <info@tailscale.com>
sub   rsa4096/B1547A3DDAAF03C6 2020-02-25 [E]

Then you can use this GPG file on your system as follows:
% sudo mv tailscale.gpg /usr/share/keyrings/tailscale.gpg
% cat /etc/apt/sources.list.d/tailscale.list
deb [signed-by=/usr/share/keyrings/tailscale.gpg] https://pkgs.tailscale.com/stable/debian buster main
% sudo apt update
[...]

Such a setup ensures:

You can verify the GPG key file (ID + fingerprint)
You can easily ship files via /usr/share/keyrings/ and refer to it in your deployment scripts, configuration management,� (and can also easily update or get rid of them again!)
The GPG key is valid only for the repositories with the corresponding `[signed-by=/usr/share/keyrings/�]` entry
You don’t need to install GnuPG (neither gnupg2 nor gnupg1) on the system which is using the 3rd party Debian repository

Thanks: Guillem Jover for reviewing an early draft of this blog article.
	
					
				
					
						This entry was posted
						 
                        by mika on Tuesday, February 16th, 2021 at 11:19						and is filed under Computer, Debian, English, Open Source.
						You can follow any responses to this entry through the RSS 2.0 feed. 
						
													Both comments and pings are currently closed.			
						
												
					
				
	
			