sábado, 28 de marzo de 2009

Reconstruyendo BBDD yum

Esta mañana me he puesto a trabajar en el portatil, y me he llevado una desagradable sorpresita.

No se debido a que, pero mi BD de yum estaba corronpida, y claro acostumbrarse a yum es muy sencillo pero acostumbrarse a no tenerlo eso es mas complicado ;)

[root@gollum ~]#yum list
Loaded plugins: refresh-packagekit
rpmdb: Thread/process 3137/139866601236208 failed: Thread died in Berkeley DB library
error: db4 error(-30975) de dbenv->failchk: DB_RUNRECOVERY: Fatal error, run database recovery
....

Lo primero que he intentado por supuesto ha sido limpiar la BD a ver si colaba, pero la verdad tenia pocas espectativas de exito.

[root@gollum ~]# yum clean all
Loaded plugins: refresh-packagekit
rpmdb: Thread/process 3137/139866601236208 failed: Thread died in Berkeley DB library
error: db4 error(-30975) de dbenv->failchk: DB_RUNRECOVERY: Fatal error, run database recovery
error: no se pudo abrir índice Packages utilizando db3 - (-30975)

......

Por este motivo y anque parezca un poco drastico, decidi reconstruir por completo la BBDD, eliminandola previamente.

[root@gollum ~]# rm -f /var/lib/rpm/__db*
[root@gollum ~]# rpm --rebuilddb
[root@gollum ~]# yum list
Loaded plugins: refresh-packagekit
Installed Packages

....

Este proceso viene a tardar unos 5 minutos.

Actualización:
Acabo de ver que este error le ha acurrido a más gente, sobre las mismas fechas. Si no recuerdo mal, en mi última actualización del sistema, se actualizó yum (Era algo del entorno gráfico), quiza sea debido a esta update, que se haya corrompido la BBDD.
http://forums.fedoraforum.org/showthread.php?p=1186925

jueves, 19 de marzo de 2009

Vaciando Papelera de Reciclaje "vacia"

Hace unos días, me ocurrió algo bastante curioso con la papelera de marras.
Resulta que haciendo limpieza de algunas unidades de disco USB, deje rastros en la papelera....
Al cabo de unos días intente vaciar la papelera y exactamente un directorio, se negaba a ser borrado.
Después de echar un vistazo vi que el directorio de la papelera está situado en
"$HOME/.local/share/Trash", aquí hay dos directorios "files" y "info", efectivamente los datos a borrar estaban aquí por lo que el comportamiento lógico es eliminarlos desde consola.
"rm -Rf $HOME/.local/share/Trash/files/*"
"rm -Rf $HOME/.local/share/Trash/info/*"

Cual fue mi sorpresa, que no solo no se habian borrado, sino que además, ahora no tenia permisos para acceder a ellos desde el entorno grafico, y además en la ruta mencionada antes ya no existian. La cara que se me quedó fue para grabarla ;)
Estube dando vueltas varios dias hasta que en uno de los intentos me di cuenta que al intentar restaurar, la ruta de origen hacia referencia a una unidad externa, por lo que evidentemente la conecte para dar un vistazo, y ahí estaban, colgando del raiz hay un directorio ".Trah" con "files" e "info" dentro, entonces si me dejo restaurar y posteriormente eliminar definitivamente.
Por esto deduzco que existe una papelera diferente para cada volumen, lo que aun no tengo claro es donde guardaba la informacion de este directorio borrado, si la unidad estaba desmontada y desconectada fisicamente. ;)

viernes, 13 de marzo de 2009

Monitorización - Python


Hace ya tiempo que me picaba el gusanillo de volver a "jugar" tecleando un poco de código de vez en cuando, pero sin pasarse que es adictivo ;))



Así que he decidido instalarme Eclipse, por eso de tener una interfaz mas amigable, y empezar otra vez, por lo menos para desoxidar.
Después de esto vino el gran dilema, ¿En que lenguaje?........
Las opciones pasaban entre C y C++ que era lo que más conocía o Java(El cual aborrecí en mis tiempos de facultad ;)), fue entonces cuando pensando que hacer me vino a la cabeza "python", que era totalmente nuevo para mi y del que había oído hablar maravillas, así que la decisión estaba tomada.
Bueno lo primero que he hecho es un pequeño script para monitorizar el estado de una máquina, es una tontería pero para ir soltándose no está mal, así que por si a alguien le sirve ahí lo dejo.

#!/usr/bin/python

# -*- coding: utf-8 -*-
"""
Copyright: Manolo Alambra Giner
Licencia: Affero GPL V3

Script para monitorizar sistemas.

Uso:
----

Ejecute en una línea de comandos:

$ python monitoriza.py

"""

import commands
import os
import sys
import subprocess

#######################################
##Definicion de las funciones empleadas
#######################################
def MandaMail():
# Obtiene el texto de la Monitorizacion
f = open("/tmp/monitoriza_temp", "r")
mssg = f.read()
f.close()
#Genera y manda el mail
SENDMAIL = "/usr/sbin/sendmail"
p = os.popen("%s -t" % SENDMAIL, "w")
p.write("To: maalgi@ono.com\n")
p.write("Subject: Monitorizacion\n")
p.write("\n")
p.write(mssg)
sts = p.close()



#Obtiene la Swap libre y la ocupada y determina si se esta usando o no mas del 50%
def ObtConSwap():
result1=commands.getoutput('cat /proc/meminfo|grep "SwapTotal:"|tr -s "'" "'"|cut -d "'" "'" -f 2')
result2=commands.getoutput('cat /proc/meminfo|grep "SwapFree:"|tr -s "'" "'"|cut -d "'" "'" -f 2')
result3=int(result1)-int(result2)
if int(result3)>int(result1)/2:
cont=0
else:
cont=1
return cont


#Devuelve 1 si encuentra un valor superior a 90 sino devuelve 0
#Al final del comando con sed eliminamos el ultimo caracter que era un '%' por ''
def ObtOcuPart():
cont=0
result=commands.getoutput('df -h|tr -s "'" "'"|cut -d "'" "'" -f 5|grep %|sed -e "'"1d"'"|sed "'"s/.$//g"'"')
ruta="/tmp/monitoriza_temp2"
wfich(str(result),ruta)
f=open(ruta,"r")
for linea in f.readlines():
if linea[:-1]!="":
if int(linea[:-1])>90:
cont=1
return cont

#Obtiene la media tiempo ocioso de la CPU para 10 iteraciones
#Con sed eliminamos las 2 primeras lineas
def ObtConCPU():
iter=10
result=commands.getoutput('vmstat 5 '+str(iter)+'|sed -e "'"1,2d"'"|tr -s "'" "'"|cut -d "'" "'" -f 16')
ruta="/tmp/monitoriza_temp2"
wfich(str(result),ruta)
f=open(ruta,"r")
s=0
for linea in f.readlines():
if linea!="":
s=int(s)+int(linea)
result1=int(s)/int(iter)
f.close()
commands.getoutput('rm -f'+ruta)
return result1

#Obtiene el numero de interfaces con errores
def ObtEstInterfaces():
result=commands.getoutput('/sbin/ifconfig -a|grep errors|tr -s "'" "'"|cut -d "'" "'" -f 4|grep -v errors:0|wc -l')
return result

#Obtiene el numero de interfaces con colisiones
def ObtEstInterfaces2():
result=commands.getoutput('/sbin/ifconfig -a|grep collisions|tr -s "'" "'"|cut -d "'" "'" -f 2|grep -v collisions:0|wc -l')
return result

#Obtiene el nombre de la maquina
def ObtNom():
result=commands.getoutput('uname -a')
return result

#Obtiene la fecha y hora de la maquina
def ObtFecha():
result=commands.getoutput('date')
return result

#Obtiene el % de memoria usada
def checkmem():
result1 = commands.getoutput('free|grep Mem:|tr -s "'" "'" |cut -d "'" "'" -f 2')
result2 = commands.getoutput('free|grep Mem:|tr -s "'" "'" |cut -d "'" "'" -f 3')
result3=int(result2)*100/int(result1)
return result3

#Escribe machacando el contenido en un fichero
def wfich(linea,fichero):
fich_maquinas=open(fichero, "w")
fich_maquinas.write(linea)
fich_maquinas.close()

#Escribe anyadiendo el contenido al final de en un fichero
def afich(linea,fichero):
fich_maquinas=open(fichero, "a")
fich_maquinas.write(linea)
fich_maquinas.close()


###################################
##Comienza el main de la aplicacion
###################################

#Ruta del fichero temporal a generar con los resultados de la monitorizacion
ruta1="/tmp/monitoriza_temp"

#Escribe a fichero la fecha de la monitorizacion, iniciando el fichero, creandolo o machacandolo
fech=ObtFecha()
fech1=str(fech)+'\n\n'
wfich(str(fech1),ruta1)

#Escribe a fichero el nombre de la maquina, iniciando el fichero para anyadir al final
nom=ObtNom()
nom1=str(nom)+'\n\n'
afich(str(nom1),ruta1)

#Si el consumo de memoria RAM es superior al 85% escribe un aviso si es menor otro
mem=checkmem()
if int(mem)>85:
afich('ERROR - Ocupacion de memoria ELEVADA ->'+str(mem)+'%\n\n',ruta1)
else:
afich('OK - Ocupacion de memoria Correcta ->'+str(mem)+'%\n\n',ruta1)


#Si el numero de interfaces con errores es superior a 0 escribe un aviso si es =0 escribe otro
inter=ObtEstInterfaces()
if int(inter)>0:
afich('ERROR - Existen errores en algunas interfaces\n\n',ruta1)
else:
afich('OK - Todas las interfaces sin errores\n\n',ruta1)

#Si el numero de interfaces con colisiones es superior a 0 escribe un aviso si es =0 escribe otro
inter=ObtEstInterfaces2()
if int(inter)>0:
afich('ERROR - Existen colisiones en algunas interfaces\n\n',ruta1)
else:
afich('OK - Todas las interfaces sin colisiones\n\n',ruta1)

#Si el consumo de CPU es mayor de 75 escribe un aviso si no lo da como correcto
id=ObtConCPU()
if int(id)<75:
afich('ERROR - El consumo de CPU es demasiado elevado ->'+str(id)+'% id\n\n',ruta1)
else:
afich('OK - El consumo de CPU es correcto ->'+str(id)+'% id\n\n',ruta1)

#Si la ocupacion de una particion supera el 90% deja un aviso sino lo da como correcto
part=ObtOcuPart()
if int(part)==1:
afich('ERROR - Hay particiones con una ocupacion mayor al 90%\n\n',ruta1)
else:
if int(part)==0:
afich('OK - Ocupacion de las particiones correcta\n\n',ruta1)
else:
afich('Error al monitotizar las particiones\n\n',ruta1)

#Determina si se esta usando mas del 50% de la Swap
sw=ObtConSwap()
if sw==0:
afich('ERROR - Mas del 50% de la Swap esta siendo usada\n\n',ruta1)
else:
if sw==1:
afich('OK - El uso de la Swap es correcto menor al 50%\n\n',ruta1)
else:
afich('Error al monitotizar la Swap\n\n',ruta1)

#Enviamos los resultados por mail
MandaMail()

martes, 3 de marzo de 2009

Instalar y Configurar Snort - Centos4.7


Hace ya bastante tiempo que llevo la idea de montar un equipo con snort, para poder probar un IDS. Pero como suele pasar nunca encontramos el momento.:) Bueno pues ha llegado el momento, y me he decidido a probarlo sobre una máquina virtual con Centos4.7





Instalación


Debemos descargar los fuentes desde el sitio oficial y descomprimirlos.



[root@centos4 ~]# cd /tmp/

[root@centos4 tmp]# wget http://www.snort.org/dl/snort-2.8.3.2.tar.gz
[root@centos4 tmp]# tar -zxvf snort-2.8.3.2.tar.gz
[root@centos4 tmp]# cd snort-2.8.3.2


Tras descomprimir, antes de instalar tenemos que asegurarnos de que mysql esta arrancado, y si no es así hay que arrancarlo.
Debería estar configurado para arrancar en el inicio, así que lo dejamos preparado ya.
Como también necesitaremos Apache mas adelante, hacemos lo mismo para este servicio.

[root@centos4 snort-2.8.3.2]# /etc/init.d/mysqld status
mysqld está parado
[root@centos4 snort-2.8.3.2]# /etc/init.d/mysqld start
Iniciando base de datos MySQL: [ OK ]
Iniciando MySQL:
[ OK ]
[root@centos4 snort-2.8.3.2]#chkconfig --level 35 mysqld on
[root@centos4 snort-2.8.3.2]#chkconfig --level 35 httpd on

Procedemos a compilar, para nuestra instalación.

[root@centos4 snort-2.8.3.2]# ./configure --with-mysql

Si no queremos usar mysql, usamos la opción que más se nos ajuste. Para ver las opciones disponibles, basta con ejecutar:

[root@centos4 snort-2.8.3.2]# ./configure -h

En mi caso, la compilación lanza un error:

ERROR! Libpcre header not found

Instalamos Libpcre-devel desde yum

[root@centos4 snort-2.8.3.2]# yum install pcre-devel.i386

Y... compilamos de nuevo..... y.... un nuevo error.

ERROR! Libpcre library version >= 6.0 not found.

Resulta que en Centos4.7 la versión de este paquete no es la esperada, la versión que tenia instalada, era:

[root@centos4 snort-2.8.3.2]# rpm -qa |grep pcre
pcre-4.5-4.el4_6.6
pcre-devel-4.5-4.el4_6.6

Así que vamos a instalar la versión correcta desde los fuentes. Como siempre... descargar, descomprimir y compilar.

[root@centos4 tmp]# wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-7.6.tar.gz
[root@centos4 tmp]# tar -zxvf pcre-7.6.tar.gz
[root@centos4 tmp]# cd pcre-7.6
[root@centos4 pcre-7.6]# ./configure
[root@centos4 pcre-7.6]# make
[root@centos4 pcre-7.6]# make install

Ahora si, instalamos snort

[root@centos4 pcre-7.6]# cd ../snort-2.8.3.2
[root@centos4 snort-2.8.3.2]# ./configure --with-mysql
[root@centos4 snort-2.8.3.2]# make
[root@centos4 snort-2.8.3.2]# make install



Configuración y Actualización de reglas.

Primero debemos crear el usuario y el grupo que usará snort.

[root@centos4 snort-2.8.3.2]# groupadd snortgrp [root@centos4 snort-2.8.3.2]# useradd -g snortgrp snortusr


Creamos los directorios y ficheros que vamos a necesitar. Tanto para almacenar las reglas como los logs.

[root@centos4 snort-2.8.3.2]# mkdir -p /etc/snort/rules [root@centos4 snort-2.8.3.2]# mkdir /var/log/snort [root@centos4 snort-2.8.3.2]# touch /var/log/snort/snort.log [root@centos4 snort-2.8.3.2]# touch /var/log/snort/alert

Asignamos los propietarios.

[root@centos4 snort-2.8.3.2]# chown -R snortusr:snortgrp /var/log/snort

Copiamos los ficheros de configuración, para esto recordar que debemos estar en el directorios donde descomprimimos.

[root@centos4 snort-2.8.3.2]# cp etc/* /etc/snort/

Ahora vamos a actualizar las reglas de snort a la última "versión", que hay de distribución libre. Esto es debido a que si estas suscrito, tienes acceso a las ultimas reglas de snort, aunque esta opción es pagando, si por el contrario solo estamos registrados, lo cual es gratuito, tenemos acceso a las reglas, una vez han transcurrido 30 días de su publicación.
[root@centos4 snort-2.8.3.2]# cd /etc/snort/rules/
[root@centos4 rules]# wget http://www.snort.org/pub-bin/downloads.cgi/Download/sub_rules/snortrules-snapshot-CURRENT_s.tar.gz


NOTA. Al descomprimir este archivo, solo nos interesa el contenido de la carpeta rules. Este contenido lo dejaremos en "/etc/snort/rules" La captura de este paso, no aparece ya que perdí el fichero de captura ;) Con esto, tenemos nuestro snort configurado y actualizado. Ya falta menos para poder trastear con el.

Configuración de Mysql

Accedemos a mysql como root, en mi caso al ser una maqueta, la cuenta no tiene password. Practica evidentemente nada recomendable.

[root@centos4 snort]# mysql -u root

Creamos ahora la BBDD que va a utilizar snort.

mysql> create database snort;
Query OK, 1 row affected (0.00 sec)

Otorgamos permisos para root desde localhost.

mysql> grant INSERT, SELECT on root.* to snort@localhost;
Query OK, 0 rows affected (0.00 sec)

Otorgamos permisos para el usuario de snort.

mysql> grant INSERT, SELECT on snort.* to snort@localhost;
Query OK, 0 rows affected (0.00 sec)

Creamos un password para el usuario snort de mysql

mysql> set PASSWORD for snort@localhost=PASSWORD('XXXXXX');
Query OK, 0 rows affected (0.01 sec)

mysql> grant CREATE, INSERT, SELECT, DELETE, UPDATE on snort.* to snort@localhost;
Query OK, 0 rows affected (0.00 sec)

mysql> grant CREATE, INSERT, SELECT, DELETE, UPDATE on snort.* to snort;
Query OK, 0 rows affected (0.00 sec)

Salimos de mysql

mysql> exit


Configuración inicial de Snort.

Ahora pasamos a configurar snort propiamente dicho, ya tenemos la aplicación instalada, con las reglas actualizadas y la BBDD preparada, así que ahora debemos decirle a snort como comportarse....

El fichero de configuración principal esta ubicado en:

[root@centos4 ~]# vi /etc/snort/snort.conf

En el debemos definir cosas como la red. Indicamos a snort cual es la red que debe tomar como local y cual la que debe tomar como esquerna. Las variable estándar para este ejemplo son suficientes aunque se puede definir fácilmente variables nuevas hasta adecuarlo a las necesidades particulares de cada problemática.

#HOME_NET es la red o redes internas ej. var HOME_NET [192.168.1.0/24,192.168.2.0/24]

var HOME_NET [192.168.1.0/24]


Con la sintaxis "!" se niega, por lo que !$HOME_NET es lo contrario de $HOME_NET, esto es útil para referirnos al resto de redes.

#Cualquiera distinta de HOME_NET

var EXTERNAL_NET !$HOME_NET


En la variable RULE_PATH, definimos la ruta donde tenemos nuestras reglas.

#Ruta de las reglas

var RULE_PATH /etc/snort/rules


Ahora solo resta configurar el acceso a BBDD. Esta sección esta comentada, hay que descomentarla y cambiarla por los valores que tengamos en cada caso.

output database: log, mysql, user=snort password=XXXXXX dbname=snort host=localhost

Una vez configurado esto, deberíamos poder arrancar el servicio desde la consola, usando para ello el usuario que hemos creado.

[root@centos4 ~]# snort -u snortusr -g snortgrp -c /etc/snort/snort.conf

Cuando paremos la ejecución con "Ctrl+c" deberíamos obtener unas estadísticas de lo que ha recogido:

Packet Wire Totals:
Received: 257
Analyzed: 237 (92.218%)
Dropped: 18 (7.004%)
Outstanding: 2 (0.778%)

Ahora vamos a configurar Snort para que arranque en el inicio. Para esto creamos un script en "init.d" que se ejecute como un demonio.

[root@centos4 ~]# cd /etc/init.d/
[root@centos4 init.d]# vi snortstart


Este script contiene lo siguiente:

!#/bin/bash
#Iniciamos snort
/usr/local/bin/snort -Dq -u snortusr -g snortgrp -c /etc/snort/snort.conf


Tras esto solo nos queda dar permisos de ejecución y crear los links pertinentes en los niveles de ejecución.

[root@centos4 init.d]# chmod 755 snortstart
[root@centos4 init.d]# cd /etc/rc3.d/
[root@centos4 rc3.d]# ln -s ../init.d/snortstart S95snortstart
[root@centos4 rc3.d]# cd ../rc5.d/
[root@centos4 rc5.d]# ln -s ../init.d/snortstart S95snortstart


Tras esto restaría rebotar para ver que efectivamente snort, arranca como es debido.

[root@centos4 ~]# ps -ef|grep snort
snortusr 3020 1 0 02:35 ? 00:00:00 /usr/local/bin/snort -Dq -u snortusr -g snortgrp -c /etc/snort/snort.conf
root 3706 3665 0 02:58 pts/0 00:00:00 grep snort


NOTA. Unas variables que pueden ser interesantes, por lo menos en mi ejemplo son estas dos.

#var HTTP_SERVERS $HOME_NET
var HTTP_SERVERS 192.168.1.110
# example, if you run a web server on port 8081, set your HTTP_PORTS variable
portvar HTTP_PORTS [80,8080]


Instalando "BASE"

Esta muy bien lo de tener snort en ejecución pero sin un visor para toda la información recogida en BBDD, la herramienta resultaría cuanto menos inútil.
Existen varios visores para snort, en este ejemplo vamos a configurar "BASE", ya que es uno de los mas extendidos, y mejor documentados.
Esta parte está mas que documentada así, que será rápido....

Instalamos desde yum "php-gd"

[root@centos4 yum.repos.d]# yum install php-gd

Vamos al directorio "www" de apache, y descargamos
"adodb"

[root@centos4 snort-2.8.3.2]# cd /var/www/

[root@centos4 www]# wget http://easynews.dl.sourceforge.net/sourceforge/adodb/adodb462.tgz

Descomprimimos...

[root@centos4 www]# tar -zxvf adodb462.tgz

Descargamos "BASE"

[root@centos4 www]# wget http://downloads.sourceforge.net/secureideas/base-1.3.9.tar.gz?use_mirror=puzzle

Movemos el archivo a nuestra "DomunetRoot", por defecto "html"

[root@centos4 www]# mv base-1.3.9.tar.gz html/

Descomprimimos....

[root@centos4 html]# tar -zxvf base-1.3.9.tar.gz

Movemos el directorio a base

[root@centos4 html]# mv base-1.3.9 base

Y editamos el php de configuración.

[root@centos4 base]# cp base_conf.php.dist base_conf.php

[root@centos4 ~]# vi /var/www/html/base/base_conf.php

Aquí configuramos el acceso a BBDD

$alert_dbname = 'snort';

$alert_host = 'localhost';

$alert_port = '';

$alert_user = 'snort';

$alert_password = 'xxxxxx';

Y...... Navegamos :)

http://192.168.1.157/base1/base_main.php


















A partir de aquí... como todo, a ir viendo que posibilidades y opciones nos ofrece ;)