zypper and gpg

So I’ve set up my own repo for my own use and created a gpg key so I can sign the packages and the repomd.xml file. Because apparently it’s a good idea to do that. The idea, or so I thought, being that should someone somehow manage to get a package in to my repo it wouldn’t be signed with the key and so zypper wouldn’t install it when the machines that look at it run ‘zypper up -y’.

The trouble is, the other day I forget to sign a package after building a new version of it and zypper installed the new package without complaint. So now I’m thining, what’s the point of signing packages and the repomd.xml file if zypper will install packages that I forgot to sign anyway?

Can anyone who understands this stuff better than I do explain…I dunno, exactly what the point of gpg signing packages is I guess and whether it’s obviously apparent from what I’ve described that I’m doing something wrong.

Hi,

this isn’t too complicated. There are two levels of security first signing the package and second signing the repository contents file. First prevents someone from changing the package second prevents from changing the repository content.

OK, lets have a closer look at signing the package:
I assume that you already have a gpg key pair. Signing the package is easy, create a file called .rpmmacros in your home directory and specify the following items:


%_signature gpg
%_gpg_name <key name>

I guess the contents is self explaining. This allows you to specify a different key for signing your packages. After that you can sign the packages with:


rpm --addsign <package>

I guess you’ve got already this far :slight_smile: The package is now signed but when you run rpm -K there is shown that the public key is unknown and therefore the signature could not be checked. You have to import the public key into rpm:


rpm --import <public key>

Public keys behaves almost like packages you can list them with rpm rpm -qa gpg-pubkey* and get a more detailed overview with rpm -qi gpg-pubkey…

After that you may want to create a repository. Which is simple, copy your RPMs to a direcotry install createrepo package and run createrepo. To sign the package contents file go to repodata directory and run:


gpg -a -u <user key> --detach-sign repomd.xml

Now the contents is signed but the key maybe is unknown, e.g. if you didn’t imported the key as above. So it is recommended to export the public key to the file repodata/repomd.xml.key. And now comes the trick because suse is more comfortable you don’t have to import the public rpm signing key manually (I assume that package signing key and repo contents signing key are identical) yast/zypper will ask for importing them. Just one more sentence yast/zypper will complain if the signature is missing for the repomd file.

So why did I told you the first manual way? I just wanted to explain it in a more detailed way so that you can better understand what’s going on.

Last but not leas you also might want to have a look at Secure Installation Sources - openSUSE

Hope this helps

OK, that’s a good explanation, but it doesn’t answer the question of why zypper will install a package that isn’t signed without some sort of prompting to ask if it’s OK. Although…

I sign the packages and that makes sure no one tampers with them after they’ve been put in to the repo.

I sign the repomd.xml file and that means that if someone regenerates repomd.xml without signing it with the correct key then zypper complains and hence won’t install something from the repo ‘zypper up -y’.

If someone puts a new rpm in to the repo dir, then that doesn’t matter because it’s not going to be seen by zypper since there’s no information about it in the repomd.xml file. If they manage to regenerate repomd.xml as well then see previous paragraph.

So the fact that zypper will install a package even if I forgot to sign it doesn’t actually matter (assuming the package hasn’t been tampered with), because the package will only get installed if it’s mentioned in repomd.xml and if repomd.xml has been signed by the correct key.

Does that make sense?

Also, I don’t run createrepo against the live repo. I create the repo in another location then update the live location from that using rsync. So any changes that have been made just in the live location would be lost when I update the repo. So that’s another layer of security.

Part of me feels like just forgetting the whole signing thing as being more effort than it’s worth. The repository in question is invisible from the Internet and the server itself is locked down such that only trusted people can log in. But I guess you can’t have too many layers of security, I have it all up and running already anyway and I’m now thinking my one concern about the whole process is actually unfounded. So I might as well do it.

Hi,

I guess zypper installs the package because RPM doesn’t complain about missing keys or signs :stuck_out_tongue:

Anyway creating the repo local and signing the repomd.xml and then copy the contents to another location might be the preferred way because the private key never leaves you local host. Of course you then can use rsync for that task but you must have the whole repository contents locally available so that you can run createrepo :stuck_out_tongue:

Finally I think it is a good idea to sign packages and repositories especially on the internet. See it’s always a trust relationship between the packager and the user of the package which makes sure that this is really the package created from that specific packager and not created by someone else. That yast also allows to install unsigned packages is a bit unlucky but maybe this is a bug or should be fixed in the future.

Maybe you also want to have a look at Attacks on Package Managers for further reading.

Have a lot of fun

On Thu, 16 Jul 2009 19:56:01 GMT, Monex
<Monex@no-mx.forums.opensuse.org> wrote:

>
>Hi,
>
>this isn’t too complicated. There are two levels of security first
>signing the package and second signing the repository contents file.
>First prevents someone from changing the package second prevents from
>changing the repository content.
>
>OK, lets have a closer look at signing the package:
>I assume that you already have a gpg key pair. Signing the package is
>easy, create a file called .rpmmacros in your home directory and specify
>the following items:
>
>Code:
>--------------------
>
> %_signature gpg
> %_gpg_name <key name>
>
>--------------------
>
>I guess the contents is self explaining. This allows you to specify a
>different key for signing your packages. After that you can sign the
>packages with:
>
>Code:
>--------------------
>
> rpm --addsign <package>
>
>--------------------
>
>I guess you’ve got already this far :slight_smile: The package is now signed but
>when you run rpm -K <package name> there is shown that the public key is
>unknown and therefore the signature could not be checked. You have to
>import the public key into rpm:
>
>
>Code:
>--------------------
>
> rpm --import <public key>
>
>--------------------
>
>
>Public keys behaves almost like packages you can list them with rpm rpm
>-qa gpg-pubkey* and get a more detailed overview with rpm -qi
>gpg-pubkey…
>
>After that you may want to create a repository. Which is simple, copy
>your RPMs to a direcotry install createrepo package and run createrepo.
>To sign the package contents file go to repodata directory and run:
>
>Code:
>--------------------
>
> gpg -a -u <user key> --detach-sign repomd.xml
>
>--------------------
>
>Now the contents is signed but the key maybe is unknown, e.g. if you
>didn’t imported the key as above. So it is recommended to export the
>public key to the file repodata/repomd.xml.key. And now comes the trick
>because suse is more comfortable you don’t have to import the public rpm
>signing key manually (I assume that package signing key and repo
>contents signing key are identical) yast/zypper will ask for importing
>them. Just one more sentence yast/zypper will complain if the signature
>is missing for the repomd file.
>
>So why did I told you the first manual way? I just wanted to explain it
>in a more detailed way so that you can better understand what’s going
>on.
>
>Last but not leas you also might want to have a look at ‘Secure
>Installation Sources - openSUSE’
>(http://en.opensuse.org/Secure_Installation_Sources)
>
>Hope this helps

This is great help on how to do it, but scant help on why it is done.
Please discuss the why as well.