Moving from single-line source files to deb822 source files
Tags: debian, apt, deb822, aptkey
Published: 2024-02-28 20:15:18

A while back, I ran into an issue where `apt-key` (or `apt`) issued a deprecation warning similar to this:

> W: http://example.com/suite/component/InRelease: Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details.

After reading the deprecation documentation on its man page, I did the quick fix. I moved the keys to `/etc/apt/trusted.gpg.d`. I glanced over the reference to the deb822-style sources.list. Then, later on, I was building an Ansible docker image, and it didn't have a `sources.list` file. Instead, it had a `/etc/apt/sources.list.d/Debian.sources` file containing an odd way of defining sources—the deb822 style.

---

While working on an Ansible role for provisioning my desktop (and creating a similar environment on a couple of VMs), I decided to look closely at the deb822-style.

Deb822 allows a couple of things that the single-line sources.list-style doesn't allow. One definition supports multiple suits, components, types, and options. Single-line sources support multiple components and options, but multiple suits and types aren't supported. An example, your usual suspect for a `sources.list` on stable looks something like this:

```
deb https://deb.debian.org/debian/ stable main contrib non-free non-free-firmware
deb https://deb.debian.org/debian/ stable-updates main contrib non-free non-free-firmware
```

With a deb822 style sources file you can combine the two:

```
Types: deb
URIs: http://deb.debian.org/debian
Suites: stable stable-updates
Components: main contrib non-free non-free-firmware
```

This is pretty cool, add stable-backports, and you have backports enabled, and in case you want source packages, add deb-src:

```
Types: deb deb-src
URIs: http://deb.debian.org/debian
Suites: stable stable-updates stable-backports
Components: main contrib non-free non-free-firmware
```

Now back to `apt-key`. `apt-key` deprecates the signing keys stored in the trusted keyring (`/etc/apt/trusted.gpg`). You can put the file in `/etc/apt/trusted.gpg.d/` as a `.gpg` (binary) or `.asc` (armored). The problem apt is trying to solve or wants you to do is to define at each repository which key was used to sign it with. You should configure this by adding a `Signed-By` in your `sources.list`, eg:

```
deb [Signed-By=/path/to/key] https://deb.debian.org/debian/ stable main contrib non-free non-free-firmware
```

The equivalent of deb822 is this (but with added benefit of once configuring it for deb, deb-src packages for stable, stable-updates and stable-backports):

```
Types: deb deb-src
URIs: http://deb.debian.org/debian
Suites: stable stable-updates stable-backports
Components: main contrib non-free non-free-firmware
Signed-By: /path/to/key
```

You don't even need to store the key in `/etc/apt/trusted.gpg.d`, you can put it everywhere on the system as long as you refer to the correct path. But there is more; the cool and nifty feature of why I chose to use deb822 with my Ansible role is that you can also add the key in the file itself. This means you don't need to deploy it anywhere. You have one file that contains all the relevant data:

```
Types: deb deb-src
URIs: http://deb.debian.org/debian
Suites: stable stable-updates stable-backports
Components: main contrib non-free non-free-firmware
Signed-By: 
 -----BEGIN PGP PUBLIC KEY BLOCK-----
 .
 mQINBGPL0F0BEAC8s6aFGXEkW0xvN5FSZKaM+rp9FX4EhWNfkKi7PaHEpZcjzC6J
 gIwSwJP7o9L/LLtLYr68Df9sv+AktdzhY50T4zBQouEl6ps/ZaaiVoTsH8wLOp7g
 /qDFJ8kH7quUU9Qh6AmirwmEddKmEZTrabg4OjeU/eJEEBJW8/NDc18lrqKC7S62
 [snipped]
 =QzR4
 -----END PGP PUBLIC KEY BLOCK-----
```

Now, we only need to deploy the correct source file, and we are done.

To get the ASCII armored keys you'll need to import the keys into your gpg and then export them:

```
gpg --import /path/to/file
gpg --export --armor <keyid> # I piped them to my deb-822 sources
```

When using deb822-style source files you need to be aware of a couple of things:
1. deb822 files end with `.sources` as opposed to `.list`
1. There is no `/etc/apt/sources.sources`
1. The space on the 2nd line of the key block needs to be a `.`
1. You need to put a space before every line of the key in the `.sources` file
1. Not all applications support the deb822 style files

And for the last point I look at Google Chrome as provided by Google. They install their browser with a cronjob that creates a single line sources-file if it cannot find one. If you add Google's repo with a `.sources` file you will get duplicate repository definitions and warnings/errors. To fix these errors, you need to do two things:

1. Remove the offending `/etc/apt/sources.list.d/google-chrome.list` file
1. Use `dpkg-divert` to divert the cronjob: `sudo dpkg-divert --divert /etc/cron.daily/google-chrome --rename /etc/cron.daily/google-chrome.disabled`.

It would be nice of Google to change their scripts to check also for `.sources` files or switch to deb822-style files altogether.

If you want to know more, head over to the man page: [`man 5 sources.list`](https://manpages.debian.org/bookworm/apt/sources.list.5.en.html).


---

Please note that while I use Debain repo's in the examples, adding the armored keys for Debian repo's might be a bit much. Debian ships its keys in the package `debian-archive-keyring`. Since you probably have this package installed, you can refer to them via `Signed-By: /path/to/key`.