Compilar "Bind" en PkgSrc para SmartOS con la opción de "dnstap"

Mi servidor DNS estándar es Bind sobre SmartOS, pero el paquete nativo disponible no tiene soporte dnstap de serie. Hay que compilarlo desde cero.

Los pasos son, en realidad, bastante sencillos si conoces cómo funciona SmartOS, su gestión de paquetes y el entorno PkgSrc:

  1. Tengo una zona nativa SmartOS con el software PkgSrc. En mi caso uso la versión trunk:

    [root@xXx ~]# imgadm avail|grep -i pkgbuild-trunk
    99412e46-9a55-11ec-a6b4-8b38513aaa54  pkgbuild-trunk                  20220302      smartos  zone-dataset  2022-03-02
    7f33bfaa-fed7-11ec-82ce-0f7efc84d370  pkgbuild-trunk                  20220708      smartos  zone-dataset  2022-07-08
    
  2. Entro en la zona pkgsrc-trunk por SSH y le pido que cree un entorno virtual de compilación:

    [root@PkgSrc-trunk ~]# run-sandbox trunk-x86_64
    
    It looks like this is the first sandbox creation for this pkgbuild.  It
    will take longer than normal, as support packages need to be downloaded
    first.  Subsequent runs will be much faster after they have been cached.
    
    [...]
    
    Unpacking bootstrap-trunk-x86_64 into /data/chroot/dev-trunk-x86_64...done.
    Setting up environment...done.
    Installing additional tools packages...done.
    Logging in.  WARNING: On logout the sandbox will be destroyed.
    
      ,---.                   |     ,---. ,---.
      `---. ,-.-. ,---. ,---. |---  |   | `---.  pkgbuild-trunk
          | | | | ,---| |     |     |   |     |  20220708
      `---' ` ' ' `---' `     `---' `---' `---'
    
    --<root@PkgSrc-trunk>-(/data/chroot/dev-trunk-x86_64)-<~>--
    ->
    
  1. Dentro de ese entorno vamos al directorio donde está Bind:

    -> cd /data/pkgsrc/net/bind916/
    
  2. Si lanzamos la compilación en ese directorio, nos generará los paquetes que necesitamos. Pero nos hemos metido en este lío porque necesito compilar Bind con dnstap. Por suerte no hay nada que parchear, dnstap es una opción de compilación disponible de serie, aunque desactivada:

    -> bmake show-options
    Any of the following general options may be selected:
            bind-dig-sigchase       Enable dig(1) option +sigchase for DNSSEC signature chasing.
            bind-json-statistics-server     Enable building in the statistics server with JSON in bind95 and later.
            bind-xml-statistics-server      Enable building in the statistics server with XML output in bind95 and later.
            blacklist        Enable blacklist support.
            blocklist        Enable blocklist support.
            dlz-filesystem   Dynamically Loadable Zones filesystem support.
            dnstap   Enable DNSTAP packet logging support.
            geoip    Enable IP-to-country-lookup.
            ldap     Enable LDAP support.
            lmdb     Enable lmdb support.
            mysql    Enable MySQL support.
            pgsql    Enable PostgreSQL support.
            pkcs11   Use certificate-on-a-stick (or card) support.
            readline         Enable use of GNU readline library.
            threads  Enable threads support.
            tuning   Specify server tuning for large.
    
    These options are enabled by default:
            readline threads
    
    These options are currently enabled:
            bind-json-statistics-server bind-xml-statistics-server
            geoip ldap readline threads
    
    You can select which build options to use by setting PKG_DEFAULT_OPTIONS
    or PKG_OPTIONS.bind916.
    
  3. Compilemos Bind con soporte dnstap. Este proceso llevará su tiempo, sobre todo la primera vez que lo lancemos, ya que tendrá que descargar y compilar muchas dependencias:

    -> bmake PKG_OPTIONS.bind916=dnstap package
    [...]
    => Creating binary package /home/pbulk/build/net/bind916/work/.packages/bind-9.16.33.tgz
    ===> Building binary package for bind-9.16.33
    => Creating binary package /data/packages/SmartOS/trunk/x86_64/All/bind-9.16.33.tgz
    --<root@PkgSrc-trunk>-(/data/chroot/dev-trunk-x86_64)-</data/pkgsrc/net/bind916>--
    ->
    
  4. Como le hemos pedido que genere el paquete, tras la compilación tendremos el paquete disponible en el directorio /data/packages/SmartOS/trunk/x86_64/All/:

    -> ls -la /data/packages/SmartOS/trunk/x86_64/All/bind*
    -rw-r--r--   2 root     root     5110512 Nov 11 19:25 /data/packages/SmartOS/trunk/x86_64/All/bind-9.16.33.tgz
    
  5. De ahí podemos copiarlo a las máquinas que necesitemos e instalarlo utilizando el comando pkg_add.

  6. Un detalle importante es que pkg_add, por un lado, no instala las dependencias de ese paquete que no estén ya instaladas en el sistema y, por otro lado, pueden existir dependencias no disponibles a través de la paquetería estándar SmartOS. En mi caso eso es posible porque estoy compilando en trunk, que compila paquetes más modernos que los que tendré luego en mi zonas SmartOS normal.

    Una forma evidente de resolver el segundo problema es utilizar una zona PkgSrc configurada con la versión que estamos usando en las zonas de producción.

    Podemos ver las dependencias de un paquete con:

    --<root@PkgSrc-trunk>-(/data/chroot/dev-trunk-x86_64)-</data/pkgsrc/net/bind916>--
    -> pkg_info /data/packages/SmartOS/trunk/x86_64/All/bind-9.16.33.tgz
    Information for /data/packages/SmartOS/trunk/x86_64/All/bind-9.16.33.tgz:
    
    Comment:
    Berkeley Internet Name Daemon implementation of DNS, version 9.16
    
    Requires:
    openldap-client>=2.4.48nb1
    openssl>=1.1.1pnb1
    GeoIP>=1.3.4nb1
    fstrm>=0.4.0
    protobuf>=3.19.0nb1
    zlib>=1.2.3
    protobuf-c>=1.3.3nb3
    libxml2>=2.9.13nb1
    json-c>=0.14
    readline>=6.0
    libuv>=1.6
    gcc10-libs>=10.3.0
    [...]
    
  7. Vamos intentando instalar el paquete en una zona limpia de usar y tirar (para no contaminar zonas de producción) y afinamos el procedimiento de instalación:

    [root@abc /tmp]# scp pkgsrc-trunk:/data/packages/SmartOS/trunk/x86_64/All/bind-9.16.33.tgz .
    [root@abc /tmp]# pkg_add bind-9.16.33.tgz
    pkg_add: no pkg found for 'protobuf-c>=1.3.3nb3', sorry.
    pkg_add: Can't install dependency protobuf-c>=1.3.3nb3
    pkg_add: Expected dependency protobuf-c>=1.3.3nb3 still missing
    pkg_add: 1 package addition failed
    
    [root@abc /tmp]# pkgin search protobuf-c
    protobuf-c-1.3.3nb2  Protocol Buffers implementation in C
    ruby26-protobuf-cucumber-3.10.8nb1  Google Protocol Buffers serialization and RPC implementation
    ruby27-protobuf-cucumber-3.10.8nb1  Google Protocol Buffers serialization and RPC implementation
    ruby30-protobuf-cucumber-3.10.8nb1  Google Protocol Buffers serialization and RPC implementation
    
    =: package is installed and up-to-date
    <: package is installed but newer version is available
    >: installed package has a greater version than available package
    

    Aquí vemos que Bind requiere una versión de protobuf-c igual o superior a 1.3.3nb3 y la versión disponible en el sistema de paquetes de Sistema Operativo es 1.3.3nb2.

    Por suerte al compilar Bind se han compilado también sus dependencias. Podemos copiar el paquete e instalarlo:

    [root@abc /tmp]# scp pkgsrc-trunk:/data/packages/SmartOS/trunk/x86_64/All/protobuf-c-1.4.1.tgz .
    [root@abc /tmp]# pkg_add protobuf-c-1.4.1.tgz
    [root@abc /tmp]# pkg_add bind-9.16.33.tgz
    pkg_add: no pkg found for 'libxml2>=2.9.13nb1', sorry.
    pkg_add: Can't install dependency libxml2>=2.9.13nb1
    pkg_add: Expected dependency libxml2>=2.9.13nb1 still missing
    pkg_add: 1 package addition failed
    
    [root@abc /tmp]# pkgin search libxml2
    libxml2-2.9.12nb2 =  XML parser library from the GNOME project
    

    Aquí tenemos el mismo caso, el Bind que hemos compilado requiere una versión de libxml2 superior a la disponible como paquete del Sistema Operativo. Lo resolvemos igual, aprovechando el paquete que se ha compilado como dependencia cuando hemos compilado el Bind:

    [root@abc /tmp]# scp pkgsrc-trunk:/data/packages/SmartOS/trunk/x86_64/All/libxml2-2.9.14nb1.tgz .
    [root@abc /tmp]# pkg_add libxml2-2.9.14nb1.tgz
    pkg_add: A different version of libxml2-2.9.14nb1 is already installed: libxml2-2.9.12nb2
    pkg_add: 1 package addition failed
    

    Aquí la cosa es más peliaguda, porque tenemos un conflicto de versiones. Podemos probar a instalar todos estos paquetes en otro sitio o arriesgarnos y suponer que una versión superior de la biblioteca libxml2 sea compatible con la versión antigua. Para esto es útil utilizar zonas SmartOS de usar y tirar, hacer pruebas, etc. Los cambios no son persistentes, podemos reaprovisionar la zona desde cero y probar las cosas sin peligro ni interferencias. En este caso vamos a forzar instalar la nueva versión. Si causa interferencias con otros programas, lo detectaremos en las pruebas y tomaremos las medidas necesarias:

    [root@abc /tmp]# pkg_add -u libxml2-2.9.14nb1.tgz
    pkg_add: no pkg found for 'gcc12-libs>=12.2.0', sorry.
    pkg_add: Can't install dependency gcc12-libs>=12.2.0
    pkg_add: Expected dependency gcc12-libs>=12.2.0 still missing
    pkg_add: 1 package addition failed
    [root@abc /tmp]# pkgin install "gcc12-libs>=12.2.0"
    reading local summary...
    processing local summary...
    gcc12-libs>=12.2.0 is not available in the repository
    calculating dependencies...done.
    nothing to do.
    [root@abc /tmp]# scp pkgsrc-trunk:/data/packages/SmartOS/trunk/x86_64/All/gcc12-libs-12.2.0.tgz .
    [root@abc /tmp]# pkg_add gcc12-libs-12.2.0.tgz
    [root@abc /tmp]# pkg_add -u libxml2-2.9.14nb1.tgz
    [root@abc /tmp]# pkg_add bind-9.16.33.tgz
    bind-9.16.33: Creating group ``named''
    bind-9.16.33: Creating user ``named''
    passwd: password information changed for named
    bind-9.16.33: copying /opt/local/share/examples/bind9/bind.keys to /opt/local/etc/bind.keys
    ===========================================================================
    This package has SMF support.  You may use svcadm(1M) to 'enable', 'disable'
    or 'restart' services.  To enable the instance(s) for this package, run:
    
            /usr/sbin/svcadm enable -r svc:/pkgsrc/bind:default
    
    Use svcs(1) to check on service status.  See smf(5) for more information.
    ===========================================================================
    [root@abc /tmp]#
    

    Ha costado algunos pasos, pero ya sabemos que necesitamos instalar los siguientes paquetes si queremos utilizar el Bind compilado por nosotros, e instalarlos en este orden:

    protobuf-c-1.4.1.tgz
    gcc12-libs-12.2.0.tgz
    libxml2-2.9.14nb1.tgz
    bind-9.16.33.tgz
    

Actualización 20230204: Más sobre este tema en Compilar "Bind" en PkgSrc para SmartOS con la opción de "dnstap" (II).