Microordenadores - Desarrollos modernos para sistemas retro

Como compilar paquetes en OpenBSD con dpb
13 de Agosto de 2017

dpb (Distributed Ports Builder) es una herramienta de OpenBSD que sirve para compilar paquetes del árbol de ports. Tiene una serie de ventajas frente a la tradicional compilación usando el comando make package:

  • Es más seguro gracias a la separación de privilegios
  • Es más rápido porque realiza compilación en paralelo
  • Permite compilaciones distribuidas en un clúster

En OpenBSD, el árbol de ports es un directorio que contiene las instrucciones para compilar e instalar software de terceros, junto con parches para que funcionen correctamente en este sistema. Aunque no es necesario dpb para compilar ports es muy conveniente ya que crea los usuarios _pfetch y _pbuild con los mínimos privilegios para descargar el código fuente de los programas y para compilarlos, respectivamente. De esta forma, si uno de estos programas tuviera alguna funcionalidad malévola se mitiga el daño que se puede hacer al sistema.

Desde el proyecto recomiendan trabajar con los paquetes precompilados oficiales, aunque las actualizaciones oficiales de los mismos sólo están para la versión current. En el caso de la arquitectura ARM64, los paquetes precompilados aún no están disponibles ya que se trata de una arquitectura soportada de forma muy reciente, por lo que si necesitas usar programas como Nginx o PHP en esta arquitectura no te queda otra que compilar.

Gracias a dpb el proceso es sencillo y te permite usar un clúster de máquinas arm64 soportadas para compilar de forma distribuida, con opciones avanzadas como el uso de chroot para mejorar la seguridad en el proceso de compilación.

Lectura recomendada

Lo primero de todo es aclarar que este tutorial no es sustituto de leer la documentación oficial. Tan sólo son unas notas que he tomado y decido publicar ya que me resultan útiles para tener a mano la información fundamental para el funcionamiento correcto de dpb. Esto funciona a día de hoy en OpenBSD 6.1 tanto en la versión estable como en la de desarrollo (current).

Ten en cuenta que, dependiendo de la cantidad de paquetes que vayas a compilar, puedes necesitar asignar más tamaño a la partición /usr, aunque también puedes compilar en un disco externo a través del puerto USB.

Descarga del árbol de ports

El proceso es sencillo y viene perfectamente explicado en la sección AnonCVS de la web de OpenBSD. En este ejemplo voy a usar el mirror ftp.hostserver.de, concretamente la rama -current que es la que he instalado. Recuerda comprobar el fingerprint (o huella) con la listada en la página de OpenBSD para asegurarte que te estás conectando al servidor legítimo:

$ cd /usr
$ doas mkdir ports
$ doas chmod g+w ports
$ cvs -qd anoncvs@ftp.hostserver.de:/cvs checkout -P ports

Si no tienes doas configurado puedes hacerlo desde root con el comando echo "permit :wheel" >> /etc/doas.conf, que permite a los usuarios del grupo wheel ejecutar comandos como usuario root. Es el reemplazo de sudo y su funcionamiento es muy similar.

Una vez descargado el árbol de ports, que son meras "recetas" para descargar, parchear y compilar los distintos programas, para actualizarlo bastaría con este comando:

$ cd /usr/ports
$ cvs -q up -Pd

Directorios clave y sus permisos

dpb, debido a su característica de la separación de privilegios, utiliza dos usuarios para descargar y compilar los paquetes. Por ello necesita permisos especiales en estos cuatro directorios:

  • /usr/ports/pobj propiedad de _pbuild:_pbuild
  • /usr/ports/distfiles propiedad de _pfetch:_pfetch
  • /usr/ports/plist propiedad de _pbuild:_pbuild
  • /usr/ports/packages propiedad de _pbuild:_pbuild

Además de estos tres directorios crearé otro para la compilación de paquetes que requiera los permisos wxallowed. Se trata de paquetes que no están correctamente programados y para ser compilados violan la política de seguridad de OpenBSD W^X que quiere decir que una zona de la memoria puede ser escribible o ejecutable, pero no ambas a la vez. Para ello conectaré un disco duro externo con una partición y configurado para que se monte en cada arranque del sistema.

Para esto usaré el directorio /usr/local/pobj, aunque si necesitas más espacio puedes montar un disco externo y configurarlo con la opción wxallowed en el archivo /etc/fstab.

$ cd /usr/ports
$ doas mkdir pobj distfiles plist packages
$ doas chown _pbuild:_pbuild pobj packages
$ doas chown _pfetch:_pfetch distfiles 

Como añadir un disco externo

Conecta el disco y ejecuta sysctl hw.disknames para encontrar la correspondencia entre el identificador y el dispositivo. Con el comando dmesg puedes ver el nombre del disco para estar seguro. En la sección Disk Setup del FAQ de OpenBSD se explica como formatear discos por lo que no lo voy a repetir aquí. Una vez que tengas la partición hecha agrégalo a fstab(5) con la opción wxallowed si necesitas compilar paquetes como python o ruby:

73abb038093b6131.a /mnt ffs rw,wxallowed,nodev 1 2

Con esto la primera partición del disco se montará en cada arranque, aunque no es necesario reiniciar ya que puedes montarlo al momento con doas mount /mnt.

Aparte de eso tendrás que especificar este directorio en el archivo /etc/mk.conf (ver mk.conf(5) de esta forma, para que los programas se vayan compilando en el directorio /mnt/pobj, que debe pertenecer a _pbuild:_pbuild:

WRKOBJDIR=/mnt/pobj

Como compilar los paquetes

Lo primero de todo haz un enlace simbólico para que dpb esté disponible haciendo doas ln -s /usr/ports/infrastructure/bin/dpb /usr/local/binHay dos directorios que te resultarán fundamentales para resolver problemas; uno contiene los logs del proceso y otro los archivos de bloqueo que tendrás que borrar si falla algo y quieres que empiece el proceso:

  • /usr/ports/logs/amd64/packages contiene los logs
  • /usr/ports/logs/amd64/locks contiene ficheros de bloqueo

Una vez que tengas todo esto en orden ya puedes empezar a compilar con dpb como usuario root, es decir, sin usar doas. A nivel de cantidad de paquetes a compilar hay tres formas de funcionamiento que muestro a continuación con un ejemplo:

  • Compilar sólo un paquete con sus dependencias mediante # dpb -c net/irssi
  • Compilar una lista de paquetes en el archivo de texto /usr/ports/pkg-list
  • Compilar todo el árbol de ports usando el comando dpb sin parámetros

Si hay algún problema aparecerá en los archivos de log mencionados anteriormente que te darán las pistas necesarias para solucionarlo. dpb es el programa usado por el proyecto para compilar todos los paquetes a diario en cada snapshot, por lo que funciona estupendamente, aunque al principio puede parecer un poco lioso. La opción -c limpia los archivos existentes y es recomendable al volver a usar dpb si ha habido algún error.

A veces, por algún error la compilación de algún paquete se puede quedar bloqueada, indicado como L=nombre_de_paquete. Se puede borrar el contenido del directorio de locks mientras el proceso dpb está en marcha sin ningún problema: doas rm -rf /usr/ports/logs/logs/amd64/locks/*

Una vez que tengas todos los paquetes que necesitas compilados el siguiente paso es firmarlos. Para ello OpenBSD dispone de la herramienta signify.

Como firmar los paquetes

Lo primero de todo lee la página de manual de pkg_sign. Con estos dos comandos crearé un par de llaves para firmar y firmaré todos los paquetes de /usr/ports/packages/aarch64/all de forma que las versiones firmadas con esta clave se guardarán en /usr/ports/packages/aarch64/signed:

# signify -G -n -s /etc/signify/obsd-pkg.sec -p /etc/signify/obsd-pkg.pub
# pkg_sign -s signify2 -s /etc/signify/obsd-pkg.sec -S /usr/ports/packages/aarch64/all/ -o /usr/ports/packages/aarch64/signed

Ten en cuenta que para instalar los paquetes firmados necesitarás copiar la llave pública /etc/signify/obsd-pkg.pub en el directorio /etc/signify de la máquina donde vayas a instalar los paquetes.


Contenido relacionado: