Friday, January 4, 2013

Creating a private signed repository with Ubuntu

To have a streamlined deployment and management strategy via Puppet it is necessary to be able to create signed Debian Packages and have a private signed repository that can contain such packages, this makes the Puppet manifest simpler and the updates will be done in a controlled manner.


Webserver configuration

Installing the webserver
apt-get install apache
<Directory /var/www/repos/ >
        Options Indexes FollowSymLinks Multiviews
        Order allow,deny
        Allow from all
</Directory>
<Directory "/var/www/repos/apt/*/db/">
        Order allow,deny
        Deny from all
</Directory>
<Directory "/var/www/repos/apt/*/conf/">
        Order allow,deny
        Deny from all
</Directory>
<Directory "/var/www/repos/apt/*/incoming/">
        Order allow,deny
        Deny from all
<?/Directory>

RNG Tools


The rngd daemon acts as a bridge between a Hardware TRNG (true random number generator) such as the ones in some Intel/AMD/VIA chipsets, and the kernel's PRNG (pseudo-random number generator). Virtual Machines are generally really bad at generating enough entropy that the gpg key generation need. RNG Tools aids that process.< /br>

NOTE: This step is optional but highly recommended if you are using a virtual machine

apt-get install rng-tools
vi /etc/default/rng-tools
Edit and Add the following

HRNGDEVICE=/dev/urandom

Finally start the service
/etc/init.d/rng-tools start

GPG key file generation


Next we will generate a GPG key to sign our repository and all of our packages with.
root@agent1:/home/alex# gpg --gen-key
gpg (GnuPG) 1.4.11; Copyright (C) 2010 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 
Key does not expire at all
Is this correct? (y/N) y
You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) "
Real name: DevOps stuff
Email address: dev@gmx.de
Comment: DevOps stuff
You selected this USER-ID:
    "devops (DevOps stuff) "
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.
gpg: gpg-agent is not available in this session
passphrase not correctly repeated; try again.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
...+++++
+++++
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
.................+++++
.......+++++
gpg: key F15542E1 marked as ultimately trusted
public and secret key created and signed.
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   2048R/F15542E1 2012-11-30
      Key fingerprint = FF1E A313 F3DA 256B A40E  FB3E 0749 613D F155 42E1
uid                  devops (DevOps stuff) 
sub   2048R/024EC2A2 2012-11-30

Create public GPG key

Now the key is already created and in the keychain. You may list it with

root@agent1:/home/alex# gpg --list-keys
/root/.gnupg/pubring.gpg
------------------------
pub   2048R/F15542E1 2012-11-30
uid                  devops (DevOps stuff) 
sub   2048R/024EC2A2 2012-11-30

Create the gpg key file that will be shared publicly via the webserver.
root@agent1:/home/alex# gpg --armor --output secure.gpg.key --export 024EC2A2
please note 024EC2A2 comes from the gpg --list-keys above!

Configure the Repository

Create the directory structure
mkdir -p /var/www/repos/apt/debian/conf
cd /var/www/repos/apt/debian/conf
Create the file "distributions" in the cwd and make sure the gpg key is used to sign the repository, add the following to the file
Origin: Alex Debian repo
Label: alex
Codename: precise
Architectures: amd64 i386 source
Components: main
Description: alex apt repository
DebOverride: override.precise
DscOverride: override.precise
SignWith: 024EC2A2

Create a file called "options" with the following content:
verbose
basedir .
ask-passphrase

Now create an empty file called "override.precise"
touch override.precise

Signing existing packages


dpkg-sig --sign builder /home/alex/demo-package-2.0.6_1.0-1_amd64.deb

Managing the repository


For this task we will use the tool "reprepro" which makes it very straightforward:
Install reprepro:
sudo apt-get install reprepro
Add a package:
reprepro -Vb . includedeb precise /home/alex/demo-package-2.0.6_1.0-1_amd64.deb
Remove a package:
reprepro -b . remove precise demo-package

Please note that when removing we are using the package name as it is described in the package manifest and the the filename itself