Esta pagina se ve mejor con JavaScript habilitado

Servicio FreeBSD

 ·  🎃 kr0m

Demonizar un programa como servicio es muy sencillo en FreeBSD, tan solo debemos crear un script de RC para ello, en este artículo explicaremos mediante un programa en C muy básico como hacerlo.

Creamos un sencillo programa que no hará nada mas que permanecer en marcha eternamente:

vi kr0mUtility.c

#include <stdio.h>
#include <unistd.h>

int main(){
    while(1) {
        sleep(1);
    }
}

Compilamos el software:

cc kr0mUtility.c -o kr0mUtility

Creamos el script de RC que controlará nuestro programa, lo creamos bajo /usr/local/etc/rc.d/ ya que es un script que NO forma parte del sistema base:

vi /usr/local/etc/rc.d/kr0mUtility

#!/bin/sh
#
# PROVIDE: kr0mUtility
# REQUIRE: DAEMON
# KEYWORD: shutdown

. /etc/rc.subr

name=kr0mUtility
rcvar=kr0mUtility_enable

command="/root/kr0mUtility"
start_cmd="kr0mUtility_start"
pidfile="/var/run/${name}.pid"

kr0mUtility_start(){
    echo "starting kr0mUtility."
    /usr/sbin/daemon -c -f -p ${pidfile} ${command}
}

load_rc_config $name
run_rc_command "$1"

Asignamos los permisos necesarios al script de RC:

chmod 555 /usr/local/etc/rc.d/kr0mUtility
chown root:wheel /usr/local/etc/rc.d/kr0mUtility

NOTA: Si nuestro programa hiciese un fork en background no haría falta un start_cmd ni la función, simplemente con la línea command ya sería suficiente. Si solo se pone esa línea con el programa mostrado cuando arranca la shell se queda “dentro” del programa hasta que presionamos Ctrl+c

Damos de alta nuestro servicio:

vi /etc/rc.conf

kr0mUtility_enable="yes"

Comprobamos el estado del servicio:

bagheera #Root:~> service kr0mUtility status

kr0mUtility is not running.

Lo arrancamos:

bagheera #Root:~> service kr0mUtility start

starting kr0mUtility.

Volvemos a comprobar el servicio:

bagheera #Root:~> service kr0mUtility status

kr0mUtility is running as pid 98683.

Podemos ver el proceso daemon que ha arrancado nuestra utilidad:

bagheera #Root:~> ps aux|grep kr0mUtility

root       98395   0.0  0.0    10812   2364  -  Ss   09:27       0:00.00 daemon: /root/kr0mUtility[98683] (daemon)
root       98683   0.0  0.0    10648   2272  -  S    09:27       0:00.00 /root/kr0mUtility
root       11987   0.0  0.0    11272   2732  0  S+   09:27       0:00.00 grep kr0mUtility

Paramos el servicio:

bagheera #Root:~> service kr0mUtility stop

Stopping kr0mUtility.
Waiting for PIDS: 98683.

Comprobamos el estado:

bagheera #Root:~> service kr0mUtility status

kr0mUtility is not running.

Comprobamos que ya no existe el proceso de la utilidad ni del daemon:

bagheera #Root:~> ps aux | grep kr0mUtility

root       54321   0.0  0.0    11272   2732  0  S+   09:27       0:00.00 grep kr0mUtility

Si nuestra utilidad requiere de algún otro servicio en el script RC debemos indicarlo, el parámetro en cuestión es REQUIRE, podemos sacar un listado de los servicios disponibles con:

grep PROVIDE /etc/rc.d/*
grep PROVIDE /usr/local/etc/rc.d/*

Hay algunas dependencias con las que se han formado grupos para no tener que incluir una por una:

  • NETWORK/NETWORKING: This is a dummy dependency, for services which require networking to be operational before starting.
  • SERVERS: This is a dummy dependency, for early-start servers relying on some basic configuration.
  • DAEMON: This is a dummy dependency, to ensure that general purpose daemons are run after the above are(NETWORKING SERVERS).
  • LOGIN: This is a dummy dependency to ensure user services such as xdm, inetd, cron and kerberos are started after everything else, in case the administrator has increased the system security level and wants to delay user logins until the system is (almost) fully operational.
  • FILESYSTEMS: This is a dummy dependency, for services which require filesystems to be mounted before starting.  It also serves as the default early / late divider; after this point, rc.d directories are rescanned to catch scripts from other filesystems than /.

También nos puede resultar de utilidad las KEYWORDs:

  • nojail: The service is not for jail(8) environment. The automatic startup and shutdown procedures will ignore the script if inside a jail.
  • nojailvnet: only allow vnet-enabled jails
  • nostart: The service is to be started manually or not started at all. The automatic startup procedure will ignore the script. In conjunction with the shutdown keyword, this can be used to write scripts that do something only at system shutdown.
  • shutdown: This keyword is to be listed explicitly if the service needs to be stopped before system shutdown.

En el artículo sobre Django podemos encontrar un ejemplo de un servicio real como es Daphne.

Si te ha gustado el artículo puedes invitarme a un RedBull aquí