signing your local debian repository

(project incomplete at this time. I can’t see straight)

Usually when I configure a local PXE install of an apt-mirror i use ‘d-i debian-installer/allow_unauthenticated string true’ so I can add my own packages to a mirror. I think in the future setting up two separate mirrors on different virtual hosts is the solution, because I always leave myself with a messy series of symlinks between the web tree and the apt-mirror tree and my own repositories. Only Adam has ever had to look at my mess, so I’ve survived without too much mockery.

On the most recent adventure I tried hacking the Release file. However recently I’ve had some consultant provided scripts that aren’t fond of the “allow unauthenticated packages?” prompts. This could be worked around with some flags (like –force-yes) but I like to try to clean things up when confronted with them, at least a little bit. There is the preseed option “#d-i apt-setup/local0/key string http://local.server/key” but that just applies to the apt-setup package that configures etc/apt/sources.list on /target. All of the installation comes off of “d-i mirror/*” and I don’t see such an option for passing a key. I assume they’re afraid of a MitM attack, as it looks like this is part of of a debian-archive-keyring package that gets pushed into the initrd when it’s made.

If you’re not familiar with udebs, they’re worth taking a look at. udebs are small debs used in the installer. Both are ar archives that contain three files. You can extract them without using any dpkg utils with ‘ar p data.tar.gz some.udeb | tar xvz’. More info is in an earlier research project with debs here.

I happen to know that some udebs are unpacked when the initrd is made and others are downloaded by the installer and then installed. Looking in the current initrd for etch i386 I found ‘archive.gpg’ in usr/share/keyrings. This is a little interesting as it looks like the latest udeb installs ‘debian-archive-keyring.gpg’ and symlinks it to ‘archive.gpg’ in the postinst (debian script, found in control.tar.gz in the ar (udeb)). There’s no such file, so I guess this particular udeb wasn’t used to create this initrd. That’s fine though, I figured it out.

You’ll need a gpg key:

gpg --gen-key
cd [wherever your Release file is]
gpg -b Release
mv Release.sig Release.gpg

By the way! There’s lots of information on the internet about mounting initrd’s using cramfs. That’s old, and it’s frustrating when I forget that. debian and ubuntu initrd images aren’t cramfs filesystems anymore, use:

mkdir initrd ; cd initrd ; gzip -cd ../initrd.gz | cpio -idmv

‘gzip -cd’ does decompress to stdout, and ‘cpio -idmv’ does “copyin” from the cpio archive, making directories, preserving timestamps and being verbose, respectively.

create a new signature file:

cd usr/share/keyrings
gpg --import < archive.gpg
gpg --export > archive.gpg

In the root of your decompressed initrd cpio tree:

find . | cpio -ovH newc | gzip -9c > ../initrd.new.gz

The -9 on gzip is super-duper compression and you’ll get a kernel panic if you try to boot off an initrd image made without ‘-H newc’.

Putting this in your netboot gets you as far as the stage where debian-installer creates the new initrd for the new box, where it fails because you’re now chrooted into /target but apt-setup hasn’t appeared to have run yet so your key listed in “d-i mirror” hasn’t been installed yet (verify with ‘chroot /target’ then ‘apt-key list’ in the shell of your installer when it fails). We could rebuild the debian-archive-keyring udeb with our key added to the keyring, but then we have to regenerate package files an release files to create all the right md5sums.

Apt-setup runs after base-installer in debian-installer, see here. It looks like base-installer runs debootstrap and passes arguments:

int
main(int argc, char *argv[])
{
char **args;
int i;

di_system_init("run-debootstrap");
debconf = debconfclient_new();
args = (char **)malloc(sizeof(char *) * (argc + 1));
args[0] = "/usr/sbin/debootstrap";
for (i = 1; i < argc; i++)
args[i] = argv[i];
args[argc] = NULL;
return exec_debootstrap(args);
}

And debootstrap has a —-keyring option. I can’t see a way to configure this though. There’s a postinst file that has this hardcoded into a variable, I think this is where the option should be. For now I’m re-enabling allow_unauthenticated, as at the very least apt-setup should install my key, and thus allow the packages I want to install to be “authenticated” after in the reboot.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.