viernes, 29 de junio de 2012

Cómo instalar Pandora FMS y Cacti

Una de las acciones más interesantes que podemos llevar a cabo sobre nuestros servidores o sobre una granja de servidores es su monitorización. Para ello, podemos emplear diferentes herramientas existentes como Nagios, Cacti o Pandora FMS entre otros.

En el siguiente vídeo puedes acceder a un videotutorial sobre "Cómo instalar Pandora FMS" realizado por nuestro alumno Juan Antonio Pardo de 2º ASIR del IES Oretania de Linares (Jaén) durante el curso 2011/2012 en el módulo profesional de Administración de Sistemas Operativos.


En este otro videotutorial se muestran los pasos básicos para realizar la instalación del software Cacti, empleado también para monitorización y análisis de datos en servidores y sistemas de comunicaciones en red. Este video ha sido realizado por nuestro alumno Jesús Momblant Quílez de 2º ASIR en el módulo profesional de Administración de Sistemas Operativos durante el curso 2011/2012


jueves, 21 de junio de 2012

Inventario automático de Equipamientos Informáticos

Estaba buscando software libre para llevar a cabo el inventario del equipamiento informático de nuestro departamento bajo Linux y he encontrado dos joyas GLPI y OCS Inventory, ambos software libre que permiten inventariar equipos Linux, Windows, impresoras, ...



Si sigues esta guía sobre cómo integrar GLPI y OCS Inventory paso a paso podrás montar un sistema bastante completo para ello. Repito, paso a paso, que se puede complicar en su desarrollo.

Ten cuidado cuando instales el OCSinventory Agent bajo Windows XP, ya que en el asistente se te preguntará cuál es la URL de tu servidor. Puedes indicarlo con un nombre de dominio o con IP, yo lo hice con http://xxx.xxx.xxx.xxx/ocsinventory  donde xxx.xxx.xxx.xxx es la IP de tu servidor. Aún así puedes echarle un vistazo a este enlace sobre OCS Inventory en el que encontrarás cómo configurar los agentes y la utilización general de estos programas.

Aquí os dejo algunos enlaces importantes para lograr echar a andar esta pareja:

Por cierto, en la web de OCS Inventory, en la sección de descargas teneis máquinas virtuales ya preconfiguradas para que las bajeis y las echeis a andar directamente sin necesidad de llevar a cabo toda la instalación. Yo soy mas partidario de hacerlo desde cero, pero si te ves apurado siempre es una ayuda tirar de una máquina ya preconfigurada. Vosotros mismos.

lunes, 18 de junio de 2012

Un examen completo: gestion de usuarios, grupos, servicios, aplicaciones, ...

A continuación se muestra el enunciado y posible solución para una convocatoria de examen sobre scripts Linux.


ENUNCIADO DEL PROBLEMA


GESTIÓN DE SERVIDORES DE AULA

Para la realización de este script el alumnado debe tener en cuenta las siguientes cuestiones:
  • Se deben utilizar funciones.
  • Todas las peticiones de introducción de datos por teclado deben ser filtradas correctamente.
  • Los comentarios a lo largo del código fuente serán valorados positivamente.
  • El orden del código fuente, tabulaciones y estructura del programa se tendrán muy en cuenta.
  • Se prestará especial atención al funcionamiento y sintaxis de las estructuras condicionales, condicionales múltiples, bucles, etc.

Una vez descritos los requisitos generales que el script debe cumplir, se detalla a continuación el enunciado a resolver.

Función para crear un archivo “log” (4 puntos):
Realiza una función que cree en la carpeta del programa una carpeta llamada “log”. Se ha de comprobar si la carpeta ya existía. Si es así, no se borrará. Si no existía, se creará y se comprobará su correcta creación. Seguidamente, se comprobará si existía un archivo en dicha carpeta llamado “log.txt”. Si es así, no se modificará nada y si no existía, se creará conteniendo en su interior la siguiente cabecera:

REGISTRO DE OPERACIONES REALIZADAS
Programa: <nombre del script>
Alumno/a: <nombre del alumno/a>
Curso: <curso>
2011/2012
Función para escribir en archivo “log” (4 puntos):
Realiza una función genérica para registrar en el archivo “log” del programa, todas aquellas acciones que el enunciado indique que han de anotarse. Para ello, se ha de tener en cuenta la fecha y hora en la que se realiza la anotación, así como la operación realizada. Esta función debe recibir como parámetro la cadena de texto que se quiere escribir en el archivo “log” del programa.

Nota: Si la función se denomina registrar_en_log y queremos escribir en el archivo el mensaje “El usuario Antonio ha sido creado con éxito”, dentro de la función debemos utilizar $1 que representará el parámetro que recibirá la cadena de caracteres. Cuando vayamos a realizar la llamada a la función en nuestro programa principal o desde otra función, tendremos que escribir:
registrar_en_log “El usuario Antonio ha sido creado con éxito”.

De este modo, podremos utilizar esta función genérica desde cualquier parte de nuestro script para insertar las anotaciones que sean necesarias.

Función para instalación de aplicaciones (3 puntos):
Realiza una función genérica que sirva para realizar la instalación de aplicaciones. Se debe solicitar al usuario que introduzca por teclado el nombre de la aplicación a instalar. Antes de intentar instalarla, el programa debe comprobar si esta aplicación ya está instalada en el sistema. Si lo está, se comunicará al usuario. Si no lo está, se lanzará una orden de instalación y se comprobará el resultado de ésta informando al usuario. Para cada acción realizada se debe llevar a cabo una anotación en el archivo “log” del programa.

Función para desinstalación de aplicaciones (3 puntos):
Realiza una función genérica que sirva para realizar la desinstalación de aplicaciones. Se debe solicitar al usuario que introduzca por teclado el nombre de la aplicación a desinstalar. Antes de intentar desinstalarla, el programa debe comprobar si esta aplicación ya está instalada en el sistema. Si lo está, se comunicará al usuario y se lanzará una orden de desinstalación, se comprobará el resultado de ésta informando al usuario. Si la aplicación no está instalada, se informará al usuario. . Para cada acción realizada se debe llevar a cabo una anotación en el archivo “log” del programa.

Función para el chequeo del estado de todos los servicios (2 puntos):
Realiza una función que muestre por pantalla el estado actual de todos los servicios del sistema.

Función para la activación, desactivación o reinicio de servicios (2 puntos):
Realiza una función que solicite al usuario el nombre de un servicio. El script debe comprobar el estado del servicio y mostrarlo por pantalla. Una vez hecho esto, se ha de preguntar al usuario si quiere iniciarlo, pararlo o reiniciarlo. En función de la respuesta, se llevará a cabo dicha acción. Para cada acción que se realice, se debe llevar a cabo una anotación en el archivo “log” del programa.

Función para la preparación del aula (6 puntos):
Realiza una función genérica que sirva para la preparación de un aula. Esta función deberá funcionar como un “asistente” llevando a cabo su trabajo a través de varias preguntas:
  1. Primer paso: Se solicitará al usuario que introduzca el nombre del aula, una vez introducido se comprobará si el aula existe como grupo dentro del sistema. Si no está creado dicho grupo, se creará.
  2. Segundo paso: Se creará en la carpeta del script, una carpeta con el mismo nombre que la del aula.
  3. Tercer paso: Se solicitará al usuario que introduzca el nombre de usuario del profesor. Se ha de comprobar si este usuario existe en el sistema, si no se creará y se integrará en el grupo del aula. Se establecerá su home en el interior de la carpeta correspondiente al aula.
  4. Cuarto paso: Se solicitará al usuario que introduzca el número de usuarios que forman el aula. Se dará de alta a tantos usuarios como se haya indicado, integrando a cada uno de ellos en el grupo del aula. Se establecerá su home en el interior de la carpeta correspondiente al aula. Para cada usuario a crear, se deben realizar las comprobaciones previas necesarias.

Para cada uno de los pasos, se ha de realizar una anotación en el archivo “log” del programa. Estas anotaciones deben realizarse tanto si el aula, profesor o usuarios son creados satisfactoriamente, como si no es así.

Función para mostrar el estado de particiones del servidor (2 puntos):
Realiza una función que muestre por pantalla el estado actual de todas las particiones del sistema, su tamaño, porcentaje de utilización, etc.

Programa principal (2 puntos):

Construye el programa principal que debe crear en primer lugar el archivo “log” del programa. Una vez realizada esta acción, se mostrará por pantalla el siguiente menú de opciones:

1)       Instalar aplicaciones
2)       Desinstalar aplicaciones
3)       Visualizar estado de servicios
4)       Gestionar un servicio
5)       Preparación del aula
6)       Visualizar estado almacenamiento
7)       Visualizar log de operaciones
8)       Salir

Tanto el menú, como las distintas opciones deben gestionarse a través de las estructuras de control adecuadas.




CÓDIGO FUENTE DE UNA POSIBLE SOLUCIÓN

#!/bin/bash

# Función para crear un archivo log
function crea_log()
{
    if [ -d /home/$USERNAME/finalsor/log ]
    then
        echo "La carpeta que alojará el log del programa ya existe, no se creará"
    else
        echo "Creando carpeta para alojar log"
        mkdir /home/$USERNAME/finalsor/log
        if [ $? -ne 0 ]
        then
            echo "Error al crear la carpeta para alojar log"
        else
            echo "Carpeta para alojar log creada con éxito"
        fi
    fi

    echo "Comprobando la existencia de un archivo log..."

    if [ -f /home/$USERNAME/finalsor/log/log.txt ]
    then
        echo "Ya existe un archivo log, no se creará"
    else
        echo "No existe un archivo log, procediendo a su creación..."      
        touch /home/$USERNAME/finalsor/log/log.txt
        if [ -f /home/$USERNAME/finalsor/log/log.txt ]
        then
            echo "Archivo log creado con éxito"
            echo "Insertando cabecera..."
            echo "###################################" >> /home/$USERNAME/finalsor/log/log.txt
            echo "REGISTRO DE OPERACIONES REALIZADAS" >> /home/$USERNAME/finalsor/log/log.txt
            echo "Programa: finalsor.sh" >> /home/$USERNAME/finalsor/log/log.txt
            echo "Alumno/a: profesor" >> /home/$USERNAME/finalsor/log/log.txt
            echo "Curso: 2ºSMR" >> /home/$USERNAME/finalsor/log/log.txt
            echo "2011/2012" >> /home/$USERNAME/finalsor/log/log.txt
            echo "###################################" >> /home/$USERNAME/finalsor/log/log.txt
        else
            echo "Error al crear el archivo log"
        fi
    fi

}

function escribe_en_log()
{
    #Función genérica que escribirá en el archivo log el mensaje que le pasemos como parámetro
    hora=`date +%T`
    fecha=`date +%d/%m/%Y`
    #echo "El mensaje a registrar en el log es: " $1
    #echo "Insertando mensaje en log..."
    echo $fecha" "$hora".............."$1 >> /home/$USERNAME/finalsor/log/log.txt
    if [ $? -eq 0 ]
    then
        echo "Inserción en log realizada con éxito"
    else
        echo "Error al insertar en el log"
    fi
}

function instala()
{
          # Función para instalación de aplicaciones
    echo "INSTALACIÓN DE APLICACIONES"
    while [ -z $programa ]
    do
        read -p "Introduce el nombre de la aplicación a instalar: " programa
    done
    which $programa > /dev/null
    if [ $? -eq 0 ]
    then
        echo "La aplicación: $programa ya está instalada en su sistema"
    else
        echo "La aplicación: $programa no se encuentra instalada, procediendo..."
        sudo apt-get install $programa
        if [ $? -eq 0 ]
        then
            echo "Instalación satisfactoria"
            escribe_en_log "Aplicación: $programa - Éxito en la instalación"
        else
            echo "Error al instalar"
            escribe_en_log "Aplicación: $programa - Error durante la instalación"
        fi
    fi

}

function desinstala()
{
    echo "DESINSTALACIÓN DE APLICACIONES"
    while [ -z $programades ]
    do
        read -p "Introduce el nombre de la aplicación a desinstalar: " programades
    done  
    which $programades > /dev/null
    if [ $? -eq 0 ]
    then
        echo "La aplicación: $programades se encuentra instalada en su sistema, procediendo a su desinstalación..."
        sudo apt-get remove $programades --purge
        if [ $? -eq 0 ]
        then
            echo "Desinstalación satisfactoria"
            escribe_en_log "Aplicación: $programades - Éxito al desinstalar"
        else
            echo "Error al desinstalar"
            escribe_en_log "Aplicación: $programades - Error durante la desinstalación"
        fi
    else
        echo "La aplicación: $programades no se encuentra instalada, no se puede desinstalar"
      
    fi
}

function estado_servicios()
{
    clear
    echo "VISUALIZACIÓN DE ESTADO DE SERVICIOS DEL SERVIDOR"
    service --status-all | more
    read -p "Pulse una tecla para continuar"
}

function gestiona_servicio()
{
    clear
    echo "GESTIÓN DE SERVICIO"
    servicio=""
    while [ -z $servicio ]
    do
        read -p "Introduzca el nombre del servicio a gestionar: " servicio
    done
    echo "El servicio introducido es: " $servicio
    which $servicio  > /dev/null 2>/dev/null
    if [ $? -eq 0 ]
    then
        echo "Estado del servicio $servicio: "
        service $servicio status
        echo "Pulse 1 para detener, 2 para iniciar, 3 para reiniciar"
        operacion=""       
        while [ -z $operacion ]
        do
            read -p "operación: " operacion
        done
       
       
            case $operacion in
                1) echo "Deteniendo servicio: $servicio";
                   sudo service $servicio stop;
                   escribe_en_log "Servicio: $servicio detenido";
                   read -p "Pulse una tecla para continuar";;
   
                2) echo "Iniciando servicio: $servicio";
                               sudo service $servicio start;
                   escribe_en_log "Servicio: $servicio iniciado";
                   read -p "Pulse una tecla para continuar";;
           
                3) echo "Reiniciando servicio: $servicio";
                               sudo service $servicio restart;
                   escribe_en_log "Servicio: $servicio reiniciado";
                   read -p "Pulse una tecla para continuar";;

                *) echo "Opción no válida";

                   read -p "Pulse una tecla para continuar";;
            esac
           
    else
        echo "El servicio: $servicio, no se encuentra disponible"
        read -p "Pulse una tecla para continuar"
    fi
}

function prepara_aula()
{
    clear
    echo "PREPARACIÓN DE AULA"
    aula=""   
    while [ -z $aula ]
    do
        read -p "Introduzca el nombre del aula: " aula
    done
   
    cat /etc/group | grep -w $aula > /dev/null
    if [ $? -eq 0 ]
    then
        echo "El grupo: $aula existe en el sistema, no se creará"
    else
        echo "El grupo: $aula no existe en el sistema, creando..."
        sudo addgroup $aula
        if [ $? -eq 0 ]
        then
            echo "Grupo: $aula creado con éxito"
            escribe_en_log "Grupo: $aula - Éxito al crear"
        else
            echo "Grupo: $aula no creado"
            escribe_en_log "Grupo: $aula - Error al crear"
        fi
    fi


    if [ -d /home/$USERNAME/finalsor/$aula ]

    then
        echo "La carpeta del aula: $aula existe en el sistema"
    else
        echo "Creando ahora la carpeta del aula: $aula..."
        mkdir /home/$USERNAME/finalsor/$aula       
        if [ $? -eq 0 ]
        then
            echo "Éxito al crear la carpeta del aula: $aula"
            escribe_en_log "Carpeta:$aula - Éxito al crear"
        else
            echo "Error al crear la carpeta del aula:$aula"
            escribe_en_log "Carpeta:$aula - Error al crear"
        fi
    fi

    echo "PROFESOR DEL AULA"   

    echo "Creando el usuario del profesor del aula: $aula"
    profesor=""
    while [ -z $profesor ]
    do
        read -p "Introduzca el nombre de usuario del profesor: " profesor
    done
   
    cat /etc/passwd | grep -w $profesor > /dev/null
    if [ $? -eq 0 ]
    then
        echo "El usuario: $profesor del profesor ya existe en el sistema, no se creará"
    else
        echo "El usuario $profesor no existe, creando..."
        sudo adduser --home /home/$USERNAME/finalsor/$aula/$profesor $profesor
        if [ $? -eq 0 ]
        then
            echo "Usuario: $profesor creado con éxito"
            escribe_en_log "Usuario: $profesor - Éxito al crear"
        else
            echo "Usuario: $profesor creado sin éxito"
            escribe_en_log "Usuario: $profesor - Error al crear"
        fi
    fi
   
    echo "ALUMNOS DEL AULA"
    alumnos=""
    while [ -z $alumnos ]
    do
        read -p "Introduzca el número de alumnos del aula $aula: " alumnos
    done
    echo "Ha introducido: $alumnos"
    echo "Comienza la creación automática de los $alumnos alumnos..."
    for ((contador=1;contador<=$alumnos;contador++))
    do
        nombre_alumno=$aula"_alumno"$contador
        cat /etc/passwd | grep -w $nombre_alumno > /dev/null
         if [ $? -eq 0 ]
        then
            echo "El usuario: $nombre_alumno ya existe en el sistema, no se creará"
        else
            echo "El usuario $nombre_alumno no existe, creando..."
            sudo adduser --home /home/$USERNAME/finalsor/$aula/$nombre_alumno $nombre_alumno
            if [ $? -eq 0 ]
            then
                echo "Usuario: $nombre_alumno creado con éxito"
                escribe_en_log "Usuario: $nombre_alumno - Éxito al crear"
            else
                echo "Usuario: $nombre_alumno creado sin éxito"
                escribe_en_log "Usuario: $nombre_alumno - Error al crear"
            fi
        fi
    done   

}


#........................................................................................
# PROGRAMA PRINCIPAL
#........................................................................................
crea_log
opcion=9
while [ $opcion -ne 8 ]
do
    clear
    echo "******************************************"
    echo "*      GESTIÓN DE SERVIDORES DE AULA     *"
    echo "******************************************"
    echo "* 1)Instalar aplicaciones                *"
    echo "* 2)Desinstalar aplicaciones             *"
    echo "* 3)Visualizar estado de servicios       *"
    echo "* 4)Gestionar servicio                   *"
    echo "* 5)Preparación del aula                 *"
    echo "* 6)Visualizar estado almacenamiento     *"
    echo "* 7)Visualizar log de operaciones        *"
    echo "* 8)Salir                                *"
    echo "******************************************"
    read -p "Introduzca una opción: " opcion
    echo "******************************************"
  

    case $opcion in

        1)instala;;
        2)desinstala;;
        3)estado_servicios;;
        4)gestiona_servicio;;  
        5)prepara_aula;;
        6)clear; echo "ESTADO DE ALMACENAMIENTO DEL SISTEMA"; df -h;read -p "Pulse una tecla para continuar";;
        7)clear; echo "VISUALIZANDO LOG DE OPERACIONES"; cat /home/$USERNAME/finalsor/log/log.txt;read -p "Pulse una tecla para continuar";;
        8)clear; echo "GRACIAS POR UTILIZAR ESTE SOFTWARE";exit 0;;
        *)clear; echo "Error, opción no válida. Inténtelo de nuevo";;
    esac
done

lunes, 11 de junio de 2012

Cambiando el hostname a través de un script

En esta ocasión vamos plantear una solución para un proyecto de arranque por red que tenemos entre manos. Se trata de hacer que un equipo cliente que solicita a un servidor una imagen arrancable de un sistema Linux, reciba esta imagen y que se asigne a sí mismo un nuevo nombre de host. El problema se planteaba cuando varias máquinas recibían la imágen y ésta traía preconfigurado un nombre estándar de host, ya que todas aquellas máquinas cliente que se iniciasen de este modo se llamarían exactamente igual en la red.

Para solucionarlo, se nos ocurre incrustar en la imagen que el servidor ofrece un script de arranque que lleve a cabo una modificación automática en el nombre del host, de tal forma que el nuevo nombre asignado sea totalmente diferente entre las diferentes máquinas que soliciten utilizar este servicio de arranque en red. Vamos a ver una posible solución:

#!/bin/bash

#Se analiza el valor de la variable HOSTNAME
#si no empieza por pc@ es que el nombre aún no ha sido
#actualizad al nuevo formato de nombres de hosts


echo $HOSTNAME | grep -w ^"pc@" > /dev/null
if [ $? -ne 0 ]
then
    #Generamos un código semialeatorio tomando los nanosegundos del sistema
    codigo=`date +%N`
         #Vamos a utilizar la cadena "pc@" para comenzar los nombres de nuestros equipos, esta cadena puede modificarse por la que se estime oportuna
    nombre_host="pc@"$codigo
    #Actualizamos la variable de entorno HOSTNAME       
    export HOSTNAME=$nombre_host
    #Actualizamos el contenido del archivo hostname
    echo $nombre_host > /etc/hostname
    if [ $? -ne 0 ]
    then
        echo "Error al reasignar nombre de host"
    fi
fi
  
El último if que comprueba $? podría eliminarse, ya que si buscamos que este script sea totalmente automático, no sería conveniente mostrar nada por pantalla. Hemos probado este script y cuando finaliza su ejecución el cambio de hostname se hace efectivo correctamente.

Podría ampliarse haciendo que se anote en un LOG alojado en el servidor cada nuevo nombre y su ip asociada. De este modo podríamos tener un registro de qué equipos de la red se han creado nuevos y su dirección.

Para hacer que este script se ejecute al inicio (lógicamente debe tener los permisos de ejecución adecuados y ser propiedad del root), debería colocarse en la carpeta /etc/init.d y crear un enlace a él desde las carpetas /etc/rc3.d o /etc/rc5.d, o cualquier otra asociada al nivel de ejecución de Linux donde queremos que el script se inicie.

Nota: existen algunos comandos que nos pueden generar los enlaces automáticamente. Un ejemplo puede ser el comando update-rc.d /etc/init.d/miscript defaults que podría funcionar para Ubuntu. (Asocia el script al boot de Ubuntu). Echale un vistazo a este enlace en el que puedes encontrar más información: asociar scripts a diferentes runlevels.