viernes, 23 de septiembre de 2011

Instalacion de ntop en Debian 6


Instalación de ntop en Debian 6

   Necesitamos esta aplicación en la red de la oficina para detectar problemas y consumos elevados de tráfico. En la versión 6 de debian parece ser que la instalación del Ntop tiene algún problema y hemos tenido que compilar la aplicación nosotros mismos.

Instalación

   Primero una serie de dependencias que fueron apareciendo a media que se configuraba la aplicación.

apt-get install libtool
apt-get install m4
apt-get install autoconf automake
apt-get install libpcap0.8-dev
apt-get install gdbm
apt-get install libgdbm-dev
apt-get install librrd-dev
apt-get install python-dev
apt-get install libgeoip-dev

   Ahora procedemos a compilar la aplicación.

make

   Y ahora la instalamos...

make install

Post instalación

   Ahora generamos un usuario para que ejecute el ntop. El directorio para el usuario (parámetro -d) es /usr/local/share/ntop, que es donde se instala la aplicación. -M para no crear el directorio home ya que está creado y como shell ponemos /bin/false (parámetro -s) para que no se puedan conectar al sistema con este usuario. Por último, ponemos el nombre del usuario.

useradd -d /usr/local/share/ntop -M -s /bin/false ntop


   Necesitamos un script de arranque para que el Ntop se ejecute con el arranque de la maquina. Cogí el fichero ntop que se generó para la versión 5 de Debian desde aquí. El fichero original lo descargué de esa página con el nombre [ntop_3.3.orig.tar.gz]. De este fichero extraigo el fichero que se instala en /etc/init.d y se llama ntop. Luego lo modifico un poco a mi gusto y añadimos el script /etc/init.d/ntop al arranque de la maquina.

   update-rc ntop defaults

   La salida del comando es la que sigue:

insserv: warning: script 'ntop' missing LSB tags and overrides

   El error que arroja la consola, nos indica que el script no está preparado para el nuevo modelo de arranque de Debian (y otros). Ahora hay que especificar las dependencias del script añadiendo las lineas siguientes al script de arranque. Información sobre esto en debian-wiki.


### BEGIN INIT INFO
# Provides:             Nombre del script de arranque.
# Required-Start:    Servicios que tienen que estar arrancados antes que éste script.
# Required-Stop:    Este script debe de terminar antes de que terminen estos Servicios.
# Should-Start:       Servicios que deberían estar arrancados pero no indispensables.
# Should-Stop:       Servicios que se tienen que parar tras parar este script.
# Default-Start:       Por defecto iniciar en los runlevels...
# Default-Stop:       Por defecto parar en los runlevels...
# Short-Description: Una descripción corta.
# Description: Una descripción larga.
#
### END INIT INFO


   Definitivamente el script queda como se muestra.


#! /bin/sh
# ntop script
#
# NOTE: Copy this script in /etc/init.d/ntop
#
# Author:
# Paul Mansfield <paul.mansfield@uk.worldpay.com>
# Worldpay - 20020218
#
# Fixed by L.Deri - May 2007
#
# Modificado por Salvador Gonzalez para mi instalacion en Debian 6


### BEGIN INIT INFO
# Provides:          ntop
# Required-Start:    $local_fs $network $syslog
# Required-Stop:     $network 
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: ntop daemon
# Description: ntop daemon para monitorizar trafico.
#
### END INIT INFO


set -e


NAME=ntop
DAEMON=/usr/local/bin/ntop
NTOPPID=/var/run/ntop.pid


test -x $DAEMON || exit 0


start_ntop() {
    echo -n "Starting ntop "
    $DAEMON -u ntop > /var/log/ntop.out &
    echo " ...done"
}


stop_ntop() {
    echo -n "Stopping ntop "
    if test -f $NTOPPID ; then
kill `cat $NTOPPID`
echo -n " killed pid `cat $NTOPPID`"
rm $NTOPPID
    fi
    echo " ...done"
}


case "$1" in
  start)
    start_ntop
    ;;

  stop)
    stop_ntop
    ;;

  restart)
    stop_ntop
    start_ntop
    ;;

  *)
    echo "Usage: /etc/init.d/$NAME {start|stop|restart}"
    exit 1
    ;;
esac
exit 0


Configuración de ntop para el primer arranque

   Es necesario generar un usuario y clave para el Ntop. No confundir con el usuario que ejecuta el Ntop en nuestro sistema. Ejecutamos el ntop con el parametro -A para ponerle la clave al admin. Pero aparece el siguiente error:


ntop -A
ntop: error while loading shared libraries: libntopreport-4.1.0.so: cannot open shared object file: No such file or directory

   Busco las librerías del ntop en el sistema y me las encuentro ubicadas en /usr/local/lib. Así que edito el fichero vi /etc/ld.so.conf y añado el texto include /usr/local/lib para indicarle al sistema ejecutado ldconfig que debe añadir las librerías de dicho directorio al sistema. Hay muchas maneras de hacer esto, pero esta es sencilla.

Arranque de ntop

/etc/init.d/ntop start


   Verificamos que el ntop está arrancado buscando el puerto 3000 en modo escucha. Si atacamos este puerto por medio del navegador debemos ver la información de la aplicación.


ps aux | grep ntop
ntop      2882  0.3  2.9 222704 30008 pts/0    Sl   11:26   0:00 /usr/local/bin/ntop -u ntop

   Aquí vemos que hay proceso ntop en memoria y levantado por el usuario ntop.

netstat -an | grep 3000
tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN

   Y aquí vemos que hay un proceso a la escucha en el puerto 3000. Si pedimos una lista de los servicios de la maquina en escucha vemos lo siguiente. (sólo una parte)

netstat -a

tcp        0      0 *:ssh                   *:*                     LISTEN     
tcp        0      0 *:3000                  *:*                     LISTEN 


   Aquí vemos que el sistema no sabe que escucha en el puerto 3000. Modificamos el fichero /etc/services e incluimos en su sitio (están ordenados por el número del servicio) la línea ntop 3000/tcp # ntop. De este modo el comando netstat -a da la siguiente salida que es más bonita e informativa.


tcp        0      0 *:ssh                   *:*                     LISTEN     
tcp        0      0 *:ntop                  *:*                     LISTEN


Monitorización

   Desde el navegador atacamos al servidor donde instalamos el ntop al puerto 3000. http://servidor:3000 y debemos ver algo como esto:


Retoques finales

   El log del ntop se crea como /var/log/ntop.out. Lo comprobamos para ver si hay algún problema y así solucionarlo. En el log, la linea **ERROR** RRD: Disabled - unable to create base directory (err 13, /usr/local/var/ntop/rrd) nos indica que hay un error. Lo corregimos creando el directorio que necesita. También se observa que podemos mandar la salida del log y tratarla por medio del rsyslogd. NOTE: -L | --use-syslog=facility not specified, child processes will log to the default (24).


  Hacemos que el log del ntop lo gestione el demonio rsyslog. Para conseguirlo he colocado la siguiente entrada en el fichero /etc/rsyslog.conf.


# Modificaciones para ntop
local5.* /var/log/ntop.log
:msg, contains, "ntop" /var/log/ntop.log


   y le indiqué al script de arranque /etc/init.d/ntop que se ponga en modo demonio y la salida al syslog con la facility local5.


start_ntop() {
    echo -n "Starting ntop "
    $DAEMON -d -u ntop --use-syslog=local5 -L
    echo " ...done"
}


   Parece que sin la configuracion :msg, contains, "ntop" no funciona la salida al log de la aplicación.

Rotación de los logs

   Para rotar el fichero /var/log/ntop.log creamos un fichero ntop en el directorio /etc/logrotate.d con el contenido que se muestra a continuación.


/var/log/ntop.log {
        daily
        missingok
        rotate 3
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
                /etc/init.d/ntop restart > /dev/null
        endscript
}


miércoles, 21 de septiembre de 2011

Script para hacer backup de maquinas virtuales vmware

   Bueno, aunque últimamente me siento mucho más cómodo haciendo scripts y trabajando con Linux, hay veces que tienes que hacer cosas en Windows. Ahora le ha tocado el turno a la Powershell de Windows. Digan lo que digan, es una consola de comandos al estilo Linux, siempre se copia lo bueno.

   He creado este script, copiando un poco de aquí y poco de allí, para hacer copias de maquinas virtuales de VMWare que estan arrancadas. La idea es generar un Snapshot de la máquina, luego se copia a un datastore destino y luego se elimina el snapshot. Además de esa funcionalidad, queríamos una programación rudimentaria de los backups (fecha de lanzamiento y número de copias).

   El script se lanza todos los días. Se comprueba un fichero csv y si el fichero indica que se debe hacer backup de una maquina se lanza. Por último, la máquina se mueve a una carpeta y se dejan sólo un número finito de copias, también indicadas por el fichero csv.

   El fichero csv tiene el siguiente formato:

VMMaquina,DestinoBackup,n_copias,planificaciones
XXXXY,vmbackup,2,1;20
YYYYX,vmbackup,1,2

   El primer parámetro se corresponde con el nombre de la maquina a clonar. El segundo es el datastore destino de la copia. El tercero es el número de copias a conservar. El último parámetro separa por ";" las fechas en que lanzar el backup.

   El Script:

# Nos aseguramos de que la PowerShell sepa que tiene que cargar
add-pssnapin VMware.VimAutomation.Core

##########  Funciones
# VMMaquina --> Maquina virtual a clonar
# DestinoBackup --> Datastore destino para la maquina clonada

function clonarMaquinaVirtual($VMMaquina, $DestinoBackup) {

    if ( (($VMMaquina -ne $null) -and ($DestinoBackup -ne $null)) ) {
        Echo "Copiar ($VMMaquina) en ($DestinoBackup)"

        # Formato de la fecha
        $date = Get-Date -Format "yyyyMMdd"

        #Connect to vCenter - Instalado en XXXXX
        Connect-VIServer "XXXXXXXX"

        $vm = get-VM $VMMaquina
       
        if ($vm -eq $null) {
            Echo "No se encontro la maquina $VMMaquina en el VC."
        } else {
            #Generamos el Snapshot
            $cloneSnap = $vm | New-Snapshot -Name "Snapshot de Backup"

            # Obtenemos la maquina a  clonar
            $vmView = $vm | Get-View
           
            # Desde donde clonamos
            $cloneFolder = $vmView.parent
           
            # Parametros de la maquina clonada
            $cloneSpec = new-object Vmware.Vim.VirtualMachineCloneSpec
            $cloneSpec.Snapshot = $vmView.Snapshot.CurrentSnapshot

            # Donde la clonamos
            $cloneSpec.Location = new-object Vmware.Vim.VirtualMachineRelocateSpec
            $cloneSpec.Location.Datastore = (Get-Datastore -Name $DestinoBackup | Get-View).MoRef
            $cloneSpec.Location.Transform =  [Vmware.Vim.VirtualMachineRelocateTransformation]::sparse

            #Nombre de la copia
            $cloneName = "$vm-$date"
           
            ############# Clonamos la Maquina ###############
            $vmView.CloneVM( $cloneFolder, $cloneName, $cloneSpec )
           
            # Nombre la maquina clonada
           Get-VM $cloneName

            # Quitamos el Snapshot
            Get-Snapshot -VM (Get-VM -Name $VMMaquina) -Name $cloneSnap | Remove-Snapshot -confirm:$False

            # Quitar del inventario la maquina clonada
            Remove-VM -VM $cloneName -confirm:$False
        }
       
        # Desconectamos
        Disconnect-VIServer -Confirm:$false
    }

}

# Reorganizamos en carpetas los backups
#

# vm --> Nombre de la maquina virtual
# copies --> Numero de copias a mantener de la maquina clonada

function reorganizarDS($vm, $copies) {
    # Conectamos la Unidad Z: a \\xxxxxxxxxxx\vmbackup (samba)
    $net = new-object -ComObject WScript.Network
    $net.MapNetworkDrive("z:", "\\xxxxxxxxxx\vmbackup", $false, "USER", "PASS")
   
    $rutaMaquina = "z:\" + $vm
    $origenRutaMaquina = "z:\" + $vm + "-*"
   
    # Reorganizamos la maquina
    if (-not (Test-Path $rutaMaquina)) {
        Echo "Creamos una carpeta para la maquina en ($rutaMaquina)."
        New-Item $rutaMaquina -type directory
    }
    # Movemos las maquinas al directorio
    Echo "Movemos desde ($origenRutaMaquina) a ($rutaMaquina)."
   
    Move-Item $origenRutaMaquina $rutaMaquina

    Echo "Realizamos limpieza de ($vm) y dejamos ($copies) copias"

    # Cuantas maquinas hay almacenadas
    $numCopias = $(Get-Item "$rutaMaquina\*").count
    Echo "Hay ($numCopias) copias de la maquina"
   
    if ($numCopias -gt $copies) {
        Echo "Borrando maquinas"
        do {
            dir $rutaMaquina | sort lastwritetime | select -first 1 | remove-item -recurse -force
            $numCopias = $(Get-Item "$rutaMaquina\*").count
            Echo "Ahora quedan ($numCopias) maquinas."
        } until ($numCopias -eq $copies)
    }

    Echo "Limpieza terminada"
   
    # Desconectamos la unidad Z:
    $net.RemoveNetworkDrive("z:")
}   

########## Fin funciones


# Import Backup CSV
$backupinfo =  Import-Csv C:\scripts\MaquinasBackups.csv

# Recorremos la lista de maquinas
foreach ($datosBackup in $backupinfo) {
    if ($($datosBackup.VMMaquina) -eq "") {
        Echo "Hay una maquina en blanco..."
    } else {
        # Buscamos que dia del mes es hoy
        $todayIs = Get-Date -Format "dd"
        # Cambiamos los dias 0X por X
        $todayIs = [int] $todayIs
       
        Echo "Hoy es ($todayIs)."
       
        Echo "Comprobando maquina ($($datosBackup.VMMaquina)) que debe quedar con ($($datosBackup.n_copias)) copias."
        Echo "Se debe lanzar los dias..."
        # Parseamos el ultimo parametro. Los dias se separan por ;
        $backupDates = ($($datosBackup.planificaciones)).split(";")
        foreach ($backupDate in $backupDates) {
            Echo "El dia ($backupDate) se tiene que hacer backup."
            if ($todayIs -eq $backupDate) {
                $backupVM = $($datosBackup.VMMaquina)
                $backupDest = $($datosBackup.DestinoBackup)
                Echo "Lanzamos el backup de ($backupVM) en ($backupDest)"
               
                # Llamamos al script c:\scripts\BackupVms.ps1
                Echo "Lanzando la copia"
                clonarMaquinaVirtual $backupVM $backupDest
                Echo "Copia terminada"
               
                # Como hemos hecho backup es necesario limpiar lo viejo
                reorganizarDS $backupVM $($datosBackup.n_copias)
            }
           
        }
    }
}