nibbles: Usando MacPorts sobre OS X, administrando servicios

Launchctl

"MacPorts, formerly called DarwinPorts is a package management system that simplifies the installation of software on the Mac OS X and Darwin operating systems. It is a free/open source software project to simplify installation of other free/open source software. Similar in aim and function to Fink and the BSDs' ports collections, DarwinPorts was started in 2002 as part of the OpenDarwin project, with the involvement of a number of Apple Inc. employees including Landon Fuller, Kevin Van Vechten, and Jordan Hubbard."
-- from wikipedia [search: macports]

Previo: Usando MacPorts sobre OS X, breve guia!

Dame mi Launchd!

Dice la documentación de OS X que LaunchD (System wide and per-user daemon/agent manager) es la aplicación encargada de administrar los procesos o tareas en background tanto del sistema en lo general como por usuario.


Este proceso es invocado al arranque del sistema por el kernel y es el que se encarga de gestionar el arranque de las demás aplicaciones requeridas en la inicialización del sistema.
Ahora bien, para interactuar con este administrador es necesario usar el comando launchCtl el cual nos permite llevar la administración de los procesos que launchd esta gestionando; dicho de otra manera arrancar servicios, detener servicios, eliminarlos de la lista de arranque, poner procesos en el squeduler, cambiar en nivel de registro de información (log), etcétera.
Así que después de haber trabajado con algunos comandos básicos en la nota anterior usando macports, vamos a ver de que manera al instalar una aplicación que nos provee de un servicio vía macports, afectamos el comportamiento de LaunchD; para esto vamos a tomar dos aplicaciones bastante útiles: OpenSSH, que nos sirve para establecer sesiones remotas seguras con nuestros equipos y PdnsD, que es un servidor DNS con características de Cache y Proxy.


[0001] Nuevamente OpenSSH con una variante

Bueno, hablar de OpenSSH nos llevaría unos cuantas notas (llaves, sesiones y servidores) y de eso ya hemos hecho labor en el pasado, la intención en este momento sera instalar OpenSSH desde MacPorts y darnos cuenta de ciertos detalles a tomar en cuenta.
Lo primero, para instalar OpenSSH vamos a ejecutar lo siguiente:
[ 192.168.1.108 | macuarrita ] ~                   
andresaquino $ sudo port install openssh +ssh_copy_id


Ahora bien, una vez instalado veremos que se nos dará información de como iniciar el servicio el cual será iniciado en el puerto 2222, con la finalidad de no entrar en conflicto con la versión que viene instalada por defecto en OS X.
[ 192.168.1.108 | macuarrita ] ~                   
andresaquino $ sudo port install openssh +ssh_copy_id
--->  Computing dependencies for openssh
--->  Fetching archive for openssh
--->  Attempting to fetch openssh-5.9p1_0+ssh_copy_id.darwin_10.x86_64.tbz2 from ...
--->  Fetching openssh
--->  Attempting to fetch openssh-5.9p1.tar.gz from ftp://ftp3.usa.openbsd.org/pub ...
--->  Verifying checksum(s) for openssh
--->  Extracting openssh
--->  Configuring openssh
--->  Building openssh
--->  Staging openssh into destroot
--->  Creating launchd control script
###########################################################
# A startup item has been generated that will aid in
# starting openssh with launchd. It is disabled
# by default. Execute the following command to start it,
# and to cause it to launch at startup:
#
# sudo port load openssh
###########################################################
--->  Installing openssh @5.9p1_0+ssh_copy_id
--->  Deactivating openssh @5.9p1_0
--->  Cleaning openssh
--->  Activating openssh @5.9p1_0+ssh_copy_id
--->  Cleaning openssh
                  

[0010] /opt/local/etc/ssh/sshd_config 

Este archivo contiene la configuración del servicio de OpenSSH, atención al puerto que viene configurado por defecto 2222

[0011] Contenido de la aplicación

Si observamos la salida después de la instalación, se hace referencia al comando port load, el cual buscará dentro del contenido del paquete un archivo plist, que es la definición del servicio para launchd en OS X; así mismo este archivo contiene una llamada a un script en shell que permitira iniciar y detener la ejecución del servicio OpenSSH.
[ 192.168.1.108 | macuarrita ] ~                   
andresaquino $ sudo port contents openssh
Password:
Port openssh contains:
  /Library/LaunchDaemons/org.macports.OpenSSH.plist
  /opt/local/bin/scp
  /opt/local/bin/sftp
  /opt/local/bin/slogin
  /opt/local/bin/ssh
  /opt/local/bin/ssh-add
  /opt/local/bin/ssh-agent
  /opt/local/bin/ssh-copy-id
  /opt/local/bin/ssh-keygen
  /opt/local/bin/ssh-keyscan
  /opt/local/etc/LaunchDaemons/org.macports.OpenSSH/OpenSSH.wrapper
  /opt/local/etc/LaunchDaemons/org.macports.OpenSSH/org.macports.OpenSSH.plist
  /opt/local/etc/ssh/moduli
  /opt/local/etc/ssh/ssh_config


[0100] OpenSSH.wrapper

Con este guión/script es posible hacer uso de las funciones básicas para administrar este servicio (start, stop)
#!/bin/sh
#
# MacPorts generated daemondo support script
#

#
# Init
#
prefix=/opt/local

#
# Start
#
Start()
{
 if [ -x /opt/local/sbin/sshd ]; then
        if [ ! -f /opt/local/etc/ssh/ssh_host_key ]; then
            /opt/local/bin/ssh-keygen -t rsa1 -f \
            /opt/local/etc/ssh/ssh_host_key -N "" -C `hostname`
        fi
        if [ ! -f /opt/local/etc/ssh/ssh_host_dsa_key ]; then
            /opt/local/bin/ssh-keygen -t dsa -f \
            /opt/local/etc/ssh/ssh_host_dsa_key -N "" -C `hostname`
        fi
        if [ ! -f /opt/local/etc/ssh/ssh_host_rsa_key ]; then
            /opt/local/bin/ssh-keygen -t rsa -f \
            /opt/local/etc/ssh/ssh_host_rsa_key -N "" -C `hostname`
        fi
        /opt/local/sbin/sshd
        fi
}

[0101] org.macports.OpenSSH.plist

Este archivo (plist: Property List) es la definición del servicio OpenSSH para que pueda ser administrado por LaunchD.
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd" >
<plist version='1.0'>
<dict>
<key>Label</key><string>org.macports.OpenSSH</string>
<key>ProgramArguments</key>
<array>
 <string>/opt/local/bin/daemondo</string>
 <string>--label=OpenSSH</string>
 <string>--start-cmd</string>
 <string>/opt/local/etc/Launch/org.macports.OpenSSH/OpenSSH.wrapper</string>
 <string>start</string>
 <string>;</string>
 <string>--stop-cmd</string>
 <string>/opt/local/etc/Launch/org.macports.OpenSSH/OpenSSH.wrapper</string>
 <string>stop</string>
 <string>;</string>
 <string>--restart-cmd</string>
 <string>/opt/local/etc/Launch/org.macports.OpenSSH/OpenSSH.wrapper</string>
 <string>restart</string>
 <string>;</string>
 <string>--pid=none</string>
</array>
<key>Debug</key><false/>
<key>Disabled</key><true/>
<key>KeepAlive</key><true/>
</dict>
</plist>


[0110] Modificar configuración de arranque en LaunchD 

Bien, hasta el momento hemos observado los archivos de configuración que requiere MacPorts en OS X para administrar el servicio de OpenSSH. Ahora será necesario ejecutar los siguientes pasos:

  • Detener el servicio oficial ya que es el que usa el puerto 22
  • Modificar nuestro archivo para que en lugar de usar el puerto 2222 use el 22
  • Modificar el script plist para indicarle que vamos a iniciar el servicio bajo demanda
  • Cargar nuestra definición de servicio en LaunchD
  • Iniciar el servicio de OpenSSH
Luego entonces, procedamos:

Detener el servicio oficial ya que es el que usa el puerto 22, esto es usando las preferencias del sistema, en el catálogo de servicios (Sharing), la opción "Remote Login" y dehabilitámos.

Modificar nuestro archivo para que en lugar de usar el puerto 2222 use el 22, vamos a ejecutar un sudo sobre el archivo y hacemos las modificaciones necesarias.

Modificar el script plist para indicarle que vamos a iniciar el servicio bajo demanda, esto es que vamos a modificar/agregar la bandera (OnDemand = true) presente en el archivo plist antes de cargarlo en nuestro catálogo de servicios en LaunchD.

Cargar nuestra definición de servicio en LaunchD, usando el comando launchctl vamos a cargar la definición del servicio y validaremos que se haya registrado correctamente.

Iniciar el servicio de OpenSSH, ya que le hemos indicado al administrador de servicios LaunchD que la carga de OpenSSH se va a realizar bajo demanda, ¿esto qué significa? pues que una de las funcionalidades de LaunchD es que si detecta que el servicio deja de ejecutarse intentará iniciarlo nuevamente, lo cual no nos va a permitir detenerlo de ninguna manera ya que en ese momento se encuentra bajo el control de LaunchD.

Y listo, en este momento ya podemos detenerlo o iniciarlo según nuestras necesidades, sencillo!
Si prestamos atención a los detalles de la salida que nos ofrece LaunchCtl observaremos que incluso podemos obtener el Process ID (PID), lo cual nos puede ahorrar camino al momento de indagar el estado del servicio en nuestro sistemas.

[0111] Iniciar manualmente un servicio en LaunchD 

Ahora bien, esto no necesariamente tiene que ser así. Habrá casos donde no se quiera iniciar un servicio mediante una definición en un plist, así que haremos uso de la linea de comandos, con la opción submit de LaunchCtl vamos a declarar una nueva definición y al mismo tiempo la estaremos iniciando. Dice el manual es la siguiente:
submit -l label [-p executable] [-o path] [-e path] -- command [args]
  A simple way of submitting a program to run without a configuration file.
  This mechanism also tells launchd to keep the program alive in the event of
  failure.

    -l label
    What unique label to assign this job to launchd.

    -p program
    What program to really execute, regardless of what follows the --
    in the submit sub-command.

    -o path  Where to send the stdout of the program.

    -e path  Where to send the stderr of the program.

Y en este caso lo usaremos para iniciar el servicio de PdnsD, el cual no cuenta con una definición de servicio, pero que por el momento no la necesitamos; solo para realizar unas pruebas, así que vamos a iniciarla..
[ 192.168.1.108 | macuarrita ] ~                   
andresaquino $ sudo launchctl submit \
 ..> -l org.macports.pdnsd \
 ..> -p /opt/local/sbin/pdnsd \
 ..> -o /opt/local/var/log/pdnsd.log \
 ..> -e /opt/local/var/log/pdnsd.log \
 ..> -- \
 ..> /opt/local/sbin/pdnsd \
 ..> --debug
                  

Y listo, ahora podremos detener o iniciar el servicio según sea necesario.
Como podrán darse cuenta el manejo de servicios, daemons, jobs no es complicado; ciertamente requiere de leer un poco el manual de usuario y atreverse a hacer "picar piedra". Dejaremos para otros post la cuestión de la organización de servicios vía el squeduler (like Cron).

Referencias


kualli ohtli | buen camino!

Popular Posts