Mini-dinstall

De Astillas.net
Versión
0.6.28.1
Página principal
http://packages.debian.org/squeeze/mini-dinstall
Observaciones


Conceptos

El programa mini-dinstall permite mantener un repositorio privado de paquetes Debian. Es uno de los citados en la página del wiki en la que además existen otras referencias que también pueden ser útiles.

Lo que pretendo conseguir es:

  • Debe funcionar con un mínimo de permisos del sistema y sin privilegios administrativos (o los menos posibles).
  • Debe ser fácilmente alimentable con paquetes empleando las herramientas tradicionales.
  • Debe ser igualmente sencillo de usar desde el gestor de paquetes de Debian, esto es, es necesario que exista un URL sencillo o fácil de recordar.

Instalación

Preparación del entorno

Dado que pretendo que no emplee permisos administrativos decido crear un usuario y un grupo sencillo y, con ellos, una estructura de directorios bajo su propiedad.

$ sudo addgroup debpkg
$ sudo adduser  --ingroup debpkg --shell /bin/sh debpkg 
$ sudo install --group debpkg --owner debpkg --mode=2770 -d /var/lib/debian
$ install --group debpkg --owner debpkg --mode=2770 -d /var/lib/debian/mini-dinstall

empleando el 'setgid' para que todos los archivos creados en ellos mantengan el mismo grupo y permisos para el grupo. Con el archivo de configuración adecuado el programa mini-dinstall creará la estructura completa, que incluye un directorio llamado incoming que será el que monitorice la llegada de paquetes.

Archivo de configuración

El archivo de configuración es muy variable. Anoto aquí el que empleo aunque puede variar mucho según las circunstancias:

[DEFAULT]

# Raíz del repositorio
archivedir = /var/lib/debian

# Variables para mensajes de error y notificaciones
mail_log_level = ERROR
mail_to = victor@example.net
mail_log_flush_level = ERROR
mail_log_flush_count = 10
mail_on_success = 1

# Parámetros de funcionamiento básicos entre los 
# que desatacan:
# - verify_sigs si no se va a firmar los paquetes
# - chown_changes_files porque el usuario que envía
#   los paquetes no es 'debpkg'
trigger_reindex = 1
verify_sigs = 0
incoming_permissions = 2777
dynamic_reindex = 1
chown_changes_files = 1
use_dnotify = 1
poll_time = 30
max_retry_time = 172800

# Parámetros del respositorio como un alias, 
# arquitecturas, estilo de almacenamiento 
# y otros
alias = stable
architectures = all, i386, amd64
archive_style = simple-subdir
keep_old = 1
generate_release = 1
release_description = Repositorio personal
experimental_release = 0

# Rama local del respositorio
[local]
poll_time = 40

Funcionamiento

Si no se le indica otra cosa el programa se lanza como demonio y vigila el directorio incoming hasta que encuentre nuevas entradas. Entonces las procesa y -siguiendo las directrices anteriores- actualiza las listas de paquetes.

Desde la cuenta de administración se puede lanzar el proceso demonio como:

# su debpkg -c "/usr/bin/mini-dinstall -c /etc/mini-dinstall.conf"
mini-dinstall [140603691898624] WARNING: No process running at 3574, removing lockfile

Observaciones:

  • En el ejemplo el mensaje aparece porque una ejecución anterior falló y no se efectuó la limpieza correspondiente.
  • debpkg como nombre de usuario es arbitrario y curiosamente coincide con el nombre de un programa del paquete devscripts.

Debian

En Debian es bastante sencillo incluirlo como servicio. Basta con crear un programa de arranque empleando el archivo /etc/init.d/skeleton con el siguiente encabezado:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          mini-dinstall
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Repositorio local de paquetes Debian
# Description:       Demonio de mantenimiento del repositorio de paquetes Debian local 
### END INIT INFO

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Repositorio de paquetes Debian local"
NAME=mini-dinstall
DAEMON=/usr/bin/mini-dinstall
DAEMON_ARGS="--config /etc/mini-dinstall.conf"
SCRIPTNAME=/etc/init.d/mini-dinstall
PIDFILE=/var/lib/debian/mini-dinstall/mini-dinstall.lock

# ...

Uso y empleo

Sólo como referencia rápida indico las dos formas de uso de un repositorio de este tipo asumiendo que está instalado en el servidor example.net y el puerto '8889':

  • Directamente desde APT
deb http://example.net:8889/debian/ local/$(ARCH)/
deb http://example.net:8889/debian/ local/all/
deb-src http://example.net:8889/debian/ local/source/
# /etc/approx/approx.conf
myrepo http://example.net:8889/debian
# /etc/apt/sources.list
deb http://apt:9999/myrepo local/all/
deb-src http://apt:9999/myrepo local/source/

Repositorio seguro

Conceptos

El programa apt incluye ciertos mecanismos para asegurarse de que descarga los paquetes correctos. Un repositorio contiene un archivo llamado Release cuyo contenido es la suma de verificación de varios otros archivos.

Origin: root
Label: root
Suite: local
Codename: local/all
Date: Fri, 12 Apr 2013 17:57:20 UTC
Architectures: all
Description: Programas y datos de Empresa
MD5Sum:
 2ae85fc4cccc8ecfb86b7f40084daa65          210416 Packages
 5b6eeaf75de6226b71b80097c405ef8e           26693 Packages.gz
 e2bd821e23322b3f845c35c865d1d883           23714 Packages.bz2
SHA1:
 b8091f8bd96f9a15db5333add99b58d353a262c2          210416 Packages
 e32228e9832d0f1154c0d47b90dcece74a576eed           26693 Packages.gz
 8ee75ee8e6a07eb6afa47f50f24bcadd963c5b29           23714 Packages.bz2
SHA256:
 9832e828c3ff013647dce57994edec3783e8934813541e53c6ad89a483e7b110          210416 Packages
 0412706487ec62cb996149a4aa2a345e18a6be7fc58f851a9c9fec4ec03ebde4           26693 Packages.gz
 290ade4b62c1a7952160cc5a0ebf2c9decdc3901937b0d279a476368349ac392           23714 Packages.bz2

A su vez, cada archivo Packages contiene más sumas de verificación por cada paquete descrito en él

Package: empresa-fonts
Priority: optional
Section: perl
Installed-Size: 2459
Maintainer: Victor Moral <victor@taquiones.net>
Architecture: all
Source: libempresa-perl
Version: 0.4.1
Depends: texlive-binaries
Filename: local/all/empresa-fonts_0.4.1_all.deb
Size: 1608138
MD5sum: 0deeda3ec716187400adc87a81c17bef
SHA1: c134b8ae9cbbd2cbb8e7b1483d959202cc287088
SHA256: 5ecf5d802a52106b3be1f7acb9c3f7ca530cccfa3cceea65da49fd3ce44dc18d

creando una cadena de confianza en la que existe un único eslabón suelto: el propio archivo Release. Para remediarlo se añade una firma GPG a este archivo de manera que la comprobación antes de instalar un paquete sigue este orden:

  1. Verifica que el archivo Release está correctamente firmado.
  2. Comprueba que el archivo Packages es correcto mediante la suma del archivo Release.
  3. Comprueba que el paquete deb es también correcto mediante la suma contenida en el archivo Packages.

El primer paso puede obviarse empleando el parámetro --allow-unauthenticated de apt mientras que cualquiera de los otros dos produce un error grave y el proceso se detiene.

De lo anterior se deduce que cada vez que se añade un paquete deb a un repositorio todos los demás archivos tienen que ser reconstruídos y, como el mecanismo de seguridad de los archivos Release es una firma digital, éste tiene que volver a firmarse en cada ocasión.

Claves GPG

Al utilizar GPG para el firmado se emplea una clave asimétrica con dos versiones: la versión pública es la que tiene que ser instalada en cada cliente para que pueda verificar el archivo Release, mientras que la versión privada es la que utiliza el administrador del repositorio para firmar dicho archivo resumen.

La lista de claves públicas de repositorios de los que va a instalar paquetes se guarda /etc/apt/trusted.gpg y se manipula mediante el programa apt-key.

El administrador de un repositorio debe realizar las siguientes operaciones:

  1. Crear una clave GPG
  2. Obtener una versión textual de la clave pública para los clientes del repositorio
  3. Cada vez que se envíe un paquete al repositorio:
    1. Esperar a que se regenere el archivo Release
    2. Recuperar una copia del mismo
    3. Firmar la copia y crear la versión Release.gpg
    4. Enviar la firma de nuevo al repositorio

Configuración y uso

Ya que es necesario añadir una firma al archivo Release cada vez que se añade un paquete tenemos dos posibilidades tal y como describe Stefano Zacchiroli en sus páginas.

La primera consiste en almacenar las dos partes de la clave, pública y privada, en el servidor donde se aloja el repositorio e indicarle en la configuración que utilice un script para firmar según termine. Esto tiene la ventaja de que permite mantener el método descrito de envío de paquetes que los copia en un directorio vigilado por mini-dinstall. No hay que hacer nada más.

La segunda posibilidad consiste en desactivar la vigilancia sobre el directorio de subida de paquetes y forzar la actualización y la firma desde la máquina del desarrollador del paquete.

En mi caso voy a emplear la primera opción ya que se trata de un servidor interno bajo el que tengo algo más de control.

Stefano publica un script que permite la firma y para el cual hay que modificar la configuración del servidor.

En el archivo /etc/mini-dinstall.conf hay que añadir la siguiente estrofa:

# Según la documentación este script será llamado dentro del 
# directorio que contenga el archivo Release para firmar y debería
# aceptar el nombre del archivo como primer parámetro. 
# En caso de recibir un archivo temporal (con otro nombre) el programa
# creará la firma en un archivo llamado Release.gpg
#
release_signscript = ~/bin/sign-release.sh

Creación de clave GPG

Para crear la clave GPG se debe emplear la siguiente orden desde el usuario debpkg:

# su --login --shell /bin/bash debpkg
$ gpg --homedir /var/lib/debian/.secretgpgdir --gen-key 
...