Dispositivo de sistema por lotes OpenWrt

El sistema operativo OpenWrt se usa comúnmente como firmware para enrutadores. La aplicación típica es configurar y olvidar. Pero si de repente algo no es suficiente para ti, entonces tendrás que entender el kit de distribución.











OpenWrt usa opkg como su administrador de paquetes, o más bien su propia bifurcación . Los ingenieros de Debian lo encontrarán familiar de muchas formas: comandos similares, repositorio y formato de paquete similares.



Quería parchear LUCI (esto no estará en el artículo), pero no encontré una introducción rápida adecuada, tuve que recopilar de forma independiente fragmentos de información de documentación, artículos y ejemplos dispersos, mirando el código y los resultados del trabajo. Como beneficio adicional, recopilé un paquete primitivo (pero inútil en la práctica) que aún no está en el repositorio. Comparto el programa educativo recopilado a continuación.



Dispositivo de repositorio



Hay un archivo en el sistema de archivos OpenWrt /etc/opkg/distfeeds.conf



que especifica la lista de repositorios del sistema (proporcionado por los desarrolladores de OpenWrt y opkg). Se pueden especificar repositorios propios y de terceros en /etc/opkg/customfeeds.conf



. El formato es de una línea, consta de tres palabras:



  1. src



    o src/gz



    , depende de Packages



    si el archivo se descargará o Packages.gz



    . A juzgar por el código, hay otras opciones para la primera palabra, pero no he encontrado ningún repositorio para el que esto sea relevante. A pesar del src



    nombre, este es un repositorio de paquetes binarios. Opkg no tiene un formato de repositorio especial para paquetes fuente similar al que se usa en Debian / APT.
  2. El nombre del repositorio o "feed" en terminología opkg / OpenWrt.
  3. La URL que contiene el Packages



    / Packages.gz



    .


Cuando se ejecuta , o se agrega opkg update



a la URL , la lista de paquetes y firmas se guarda en , el archivo se nombra según la segunda palabra en la lista de repositorios. Hay dos conclusiones importantes de esto:/



Packages



Packages.gz



/tmp/opkg-lists







  1. Al reiniciar, la caché se borrará. En sistemas integrados como enrutadores, esto tiene mucho sentido.
  2. Puede /etc/opkg/customfeeds.conf



    anular los feeds del sistema con los suyos, dándoles el mismo nombre. opkg jurará, pero se tragará la anulación, agregando el archivo deseado en lugar del cargado previamente.


Al mismo tiempo, se cargará Packages.sig



, que debe contener el hash de la lista de paquetes desempaquetada. La lista en sí simplemente enumera los paquetes, hay varios valores para cada paquete, los valores para los diferentes paquetes están separados por una línea vacía. Estos son los campos más importantes para cada paquete:



  • Package



    , Nombre del paquete;
  • Version



    , versión, si hay varios paquetes con el mismo nombre, puede seleccionar la versión, la última se instalará por defecto;
  • Depends



    , dependiendo de otros paquetes, el administrador de paquetes instalará los paquetes enumerados si no están presentes en el sistema;
  • Filename



    , la ruta al archivo es relativa a la URL base del repositorio, normalmente el repositorio es plano y todo está en el mismo lugar que `Packages.gz`;
  • SHA256sum



    el hash del paquete declarado por el repositorio.


Si desea más detalles, simplemente puede leer una de estas listas directamente en su navegador .



Paquetes binarios



Los paquetes binarios son casi idénticos a los paquetes Debian. La diferencia es la siguiente:



  1. Extensión en .ipk



    lugar de .deb



    .
  2. `tar` gzip



    , . Debian ar



    , .tar.xz



    , .


Si cambia la extensión del paquete para OpenWrt a .tar.gz



y la descomprime, encontrará dos archivos y un archivo de texto dentro. El archivo se nombra debian-version



, contiene la versión del formato de archivo binario y no es muy interesante para nosotros, en los sistemas modernos esta versión siempre es igual a 2.0



.



El archivo data.tar.gz



contiene archivos ejecutables, archivos de configuración y todo para lo que está instalado el paquete. Si lo descomprime en la raíz del FS, obtendrá todos los archivos esperados en los lugares correctos /usr/bin/



, /etc/



y así sucesivamente.



Y dentro hay control.tar.gz



archivos auxiliares para el administrador de paquetes. Esta secuencia de comandos que se debe ejecutar antes o después de la instalación y el retiro ( preinst



, postinst



, prerm



,postrm



), información sobre archivos que son de configuración y metainformación sobre el paquete, que es en gran medida la misma que contiene Packages



.



Sistema de construcción de paquetes



El sistema de ensamblaje (también conocido como SDK) se realiza en forma de Make-framework. El marco no implica que creará paquetes por separado, su tarea principal es crear repositorios completos.



El SDK x86_64



está en git . Hay un archivo (el enlace estará desactualizado pronto, pero no es difícil encontrar uno nuevo) que le ahorrará tiempo al compilar la cadena de herramientas para el ensamblaje. En el interior, el archivo es de especial interés feeds.conf.default



. El formato es simple, separado por un espacio:



  1. Palabra clave src-git



    . No solo se admite git , sino que ahora no hay repositorios en otros VCS.
  2. Nombre de la alimentación.
  3. Una URL de repositorio de git donde puede especificar una confirmación o etiqueta. Si conoce el nombre de dicha especificación, dígamelo.


El repositorio con paquetes en sí es lo más simple posible: en la raíz del repositorio hay una categoría de paquete, en el segundo nivel hay un directorio con el nombre del paquete, y dentro de él está Makefile



, opcionalmente, `Config.in` para opciones adicionales durante la ejecución make menuconfig



y un subdirectorio patches



con el contenido correspondiente. Solo para el paquete más simple Makefile



. Por ejemplo, puede mirar el espejo del repositorio principal .



Prueba de construcción



Intenté construir GNU Hello para probar cómo funciona el SDK. Este es un Hello World relativamente monstruoso, escrito en estricta conformidad con las pautas del proyecto GNU, y su único propósito es ilustrar esas pautas. No creé un repositorio separado para él, sino que lo "deslicé" en los paquetes básicos del SDK, desde donde lo compilé.



Para el funcionamiento del SDK Rodeado de los paquetes Debian necesarios libncurses-dev



(para el montaje del menú), build-essential



(de GCC y otros programas estándar, dependiendo de la C), gawk



, unzip



, file



, rsync



y python3



. Además, para crear un repositorio a partir de los paquetes recopilados, necesitará una utilidad para generar claves usign



. No está en el repositorio, por lo que también necesitará `cmake` para compilar. Esta herramienta se puede reemplazar con GPG ysignify-openbsd



pero es recomendado y desarrollado por el proyecto OpenWrt y es mucho más agradable de usar.



Compilamos e instalamos usign



:



git clone https://git.openwrt.org/project/usign.git
cd usign
cmake .
make
sudo make install 
      
      





En lugar de establecer ( sudo make install



), simplemente puede recordar dónde está el binar para poder seguir tirando de él con las manos.



Ahora la configuración básica del SDK:



git clone https://git.openwrt.org/openwrt/openwrt.git
cd openwrt
./scripts/feeds update -a
./scripts/feeds install -a
      
      





Permítame recordarle que en lugar de clonar desde git, puede descargar y descomprimir el archivo con la cadena de herramientas precompilada. ¡No olvide descargar la última versión!



Al ejecutar, ./scripts/feeds update -a



clonamos / actualizamos todos los repositorios de feeds.conf (.default), verificamos las dependencias y preparamos un directorio staging_dir/host/bin



con archivos ejecutables (estos son principalmente enlaces simbólicos a utilidades del sistema). El siguiente comando ./scripts/feeds install -a



,, introduce enlaces simbólicos package/feeds



, de donde se tomarán para su compilación. Estos dos comandos no son necesarios para crear mi paquete personalizado.



Siguiente se ejecutamake menuconfig



... Puede omitirlo, pero al compilar el paquete, seguirá mostrando la ventana correspondiente. En él, basta con cambiar el objetivo y el subobjetivo para que todo se compile bajo x86_64 y salga, acordando guardar la configuración. También deberá recopilar herramientas de ensamblaje auxiliares ( make tools/install



) y cadena de herramientas ( make toolchain/install



). Si descargó el SDK del archivo, make menuconfig



no se le mostrarán opciones para elegir un objetivo y no es necesario ensamblar el kit de herramientas y la cadena de herramientas, todo ya está en su lugar.



Ahora creo un directorio package/devel/hello



en el que coloco el Makefile



siguiente contenido:



Makefile
include $(TOPDIR)/rules.mk

PKG_NAME:=hello
PKG_VERSION:=2.9
PKG_RELEASE:=1
PKG_LICENSE:=GPL-3.0-or-later

PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@GNU/hello/
PKG_HASH:=ecbb7a2214196c57ff9340aa71458e1559abd38f6d8d169666846935df191ea7

include $(INCLUDE_DIR)/package.mk

define Package/hello
        SECTION:=devel
        CATEGORY:=Development
        TITLE:=GNU Hello
        URL:=https://www.gnu.org/software/hello/
endef

define Package/hello/description
        The GNU Hello program produces a familiar, friendly greeting. Yes,
        this is another implementation of the classic program that prints
        “Hello, world!” when you run it. However, unlike the minimal version
        often seen, GNU Hello processes its argument list to modify its
        behavior, supports greetings in many languages, and so on. The primary
        purpose of GNU Hello is to demonstrate how to write other programs that
        do these things; it serves as a model for GNU coding standards and GNU
        maintainer practices.
endef

define Package/hello/install
        $(INSTALL_DIR) $(1)/usr/bin
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/hello $(1)/usr/bin/
endef

$(eval $(call BuildPackage,hello))
      
      





Básicamente, todo debe quedar claro sin explicación. Los archivos del marco están conectados, los parámetros principales del paquete se describen, se @GNU



reemplazan con los espejos del proyecto GNU (definidos en el marco), y la ruta consta de dos partes: PKG_SOURCE_URL



que especifica la URL base para todas las versiones y se expande concatenando el nombre del archivo PKG_SOURCE



con una barra. Que Package/hello/install



contiene instrucciones para el montaje de los binarios en un archivo data.tar.gz



. Las opciones de construcción adicionales, si es necesario, están disponibles en la documentación . Por cierto, no olvides que make es muy exigente con la sangría, tenía pestañas individuales en lugar de espacios iniciales.



Llama de nuevomake menuconfig



, compruebe que el paquete hello esté marcado en el apartado indicado (Desarrollo en mi caso) y salga guardando la configuración. Finalmente, armamos el paquete en tres pasos; descargar, desempaquetar y compilar:



make package/hello/download
make package/hello/prepare
make package/hello/compile
      
      





Como resultado, recibí un paquete bin/packages/x86_64/base/hello_2.9-1_x86_64.ipk



. Puedes construir un repositorio. Generamos un par de claves ( usign -G -c 'openwrt test repo' -s key-build -p key-build.pub



la clave privada debe ser llamado `llave-build`), y recoger el repositorio: make package/index



. En esta etapa, el conjunto puede jurar a la ausencia usign



en el directorio con herramientas auxiliares, decidí problema enlace simbólico: ln -s `which usign` staging_dir/host/bin/usign



. Ahora, junto al paquete, está el conjunto completo necesario para el repositorio.



Comprobando el repositorio junto con el paquete



Puede verificar todo en un enrutador real (solo recuerde elegir el objetivo correcto), pero usé Docker. En Dokerhabe tener una imagen de OpenWrt para x86_84, que se puede ejecutar, la formación de hielo dentro del directorio contenedor con el SDK: sudo docker run -it --name openwrt_test -v $PWD:/opt openwrtorg/rootfs



. Presione el botón Enter hasta que aparezca el mensaje Bash.



Copio la clave del directorio reenviado (el cp /opt/key-build.pub /etc/opkg/keys/usign -F -p /opt/key-build.pub



nombre de la clave debe coincidir necesariamente con el identificador), agrego mi repositorio local ( echo src/gz local file:///opt/bin/packages/x86_64/base >> /etc/opkg/customfeeds.conf



), actualizo el repositorio ( opkg update



). La conclusión comienza con texto alentador, todo está firmado correctamente:



# opkg update
Downloading file:///opt/bin/packages/x86_64/base/Packages.gz
Updated list of available packages in /var/opkg-lists/local
Downloading file:///opt/bin/packages/x86_64/base/Packages.sig
Signature check passed.
      
      





Solo queda instalar y verificar:



root@34af2f6e849b:/# opkg install hello
Installing hello (2.9-1) to root...
Downloading file:///opt/bin/packages/x86_64/base/hello_2.9-1_x86_64.ipk
Configuring hello.
root@34af2f6e849b:/# hello
Hello, world!
      
      





¡Hurra, está hecho! A pesar de la documentación dispersa en los artículos, el proceso de creación de paquetes es bastante sencillo.










All Articles