Mostrando entradas con la etiqueta Desarrollo. Mostrar todas las entradas
Mostrando entradas con la etiqueta Desarrollo. Mostrar todas las entradas

jueves, 19 de julio de 2012

Otrs stat from last week, last month, last everyday


Hace unos días había tenido la necesidad de automatizar el envió de reportes en OTRS (3.1.2), lo que buscábamos era enviar el reporte de las actividades realizadas en los últimos N días, por ejemplo enviar automáticamente cada domingo por la noche un reporte semanal de los tickets creados en la semana actual.

El problema: Las estadísticas con objetos dinámicos no permiten especificar un parámetro como "LastWeek", solo permite dos opciones
  • Definir un rango de fechas estéticamente.
  • Dejar a elección del usuario escoger la fecha en la interface web.

¿Que pasa con el script de generación de estadísticas?
El script otrs.GenerateStats.pl recibe algunos parámetros como el ID de la estadística, el directorio destino donde colocara el archivo, el formato en que entregara la estadística (csv, pdf). Incluso una opción "-p" que recibe valores para Format, GraphSize, StatID  y ExchangeAxis. Debo mencionar que esta parte tiene una documentación muy pobre.

Como la idea es automatizar el proceso, tenemos que pensar en cron job, pero cron implica otrs.GenerateStats.pl, y este ultimo no tiene el soporte que ocupamos, esperando que esta descripción sea clara ¿quien podrá ayudarnos?

La solución:  Construcción de un script traductor.

En la base de datos de OTRS, las estadísticas se almacenan en "xml_storage", cada generación de estadísticas consultara las fechas primeramente en un cache y luego en la tabla

select * from xml_storage where xml_key=29



xml_typexml_keyxml_content_keyxml_content_value
Stats29[0]{'otrs_stats'}[1]{'UseAsRestriction'}[1]{'TimeStop'} 2012-07-18 23:59:59
Stats29[0]{'otrs_stats'}[1]{'UseAsRestriction'}[1]{'TimeStart'} 2012-07-11 00:00:00


Es recomendable crear un usuario en mysql con acceso de select/update a nuestra tabla y nada mas, este para ser usado en nuestro script. Con esta información preliminar les presento el script resultante:
#!/bin/bash

################################################
# Martin Edmundo, [ Julio 2012 ]
# @martinedmundo
# www.elrincondemartin.org
# Funcion: Script de generacion de estadisticas
#          basado en los ultimos dias.
# Release: OTRS 3.1.2
################################################

#Definicion de variables usadas
OTRS_DIR=/opt/otrs
OTRS_BIN=$OTRS_DIR/bin
BODYMAIL=/usr/local/sbin/bodymail.txt

DBUSER='otrsstat'
DBPASSWD='xxxxxx'
DBNAME='otrs'
DBTABLE='xml_storage'

STATNUM='';
TARGETDIR=$HOME;
DAYSNUM='7';
FILENAME='';

FILENAMESTAT='';
PREFIXFILENAMESTAT='Estad';
datestart=''
datestop=''

function phelp {
        echo -e "Usage: $0 -n  -o  -d  | -h"
        echo -e "  -n Numero de estadistica."
        echo -e "  -o Directorio destino de la estadistica. [ Predeterminado: $HOME ]"
        echo -e "  -d Rango de fechas de los utimos dias hasta hoy. [ Predeterminado: 7 ]"
        echo -e "  -h Ayuda, este mensaje.\n"
}

function chdb {
        #Se define el rango de fechas para los ultimos DAYSNUM dias
        datestart=`date --date="-$DAYSNUM day" +"%F "`00:00:00;
        datestop=`date +"%F %H:%M:%S"`;

        #Limpiamos cache de estadisticas
        rm $OTRS_DIR/var/tmp/CacheFileStorable/XML/* 2> /dev/null

        #Actualizamos fechas de estadisticas
        mysql -u $DBUSER -p$DBPASSWD --database=$DBNAME --execute="UPDATE $DBTABLE SET xml_content_value='$datestart' WHERE xml_key=$STATNUM and xml_content_key LIKE '%TimeStart%'"
        mysql -u $DBUSER -p$DBPASSWD --database=$DBNAME --execute="UPDATE $DBTABLE SET xml_content_value='$datestop' WHERE xml_key=$STATNUM and xml_content_key LIKE '%TimeStop%'"
}

function sendmail_ {
        #Nos vamos al diretorio de los reportes
        cd $TARGETDIR

        #Se revisa los destinatarios de correo
        for mail in `cat $FILENAME`; do
                isComment=`echo "$mail" | cut -d "#" -f1`

                #Si no es un comentario, analizamos
                if [ -n "$isComment" ]; then
                        #Se requiere mejorar la expresion regular para correo
                        isMail=`echo "$mail" | grep ".*@.*"`

                        #Enviamos correo electronico
                        if [ "$?" = "0" ]; then
                                ( echo -e "Reporte de actividades correspondientes al siguiente periodo: \n
[ $datestart a $datestop ]"; uuencode $FILENAMESTAT Reporte_$STATNUM.pdf  ) | mail -s "Servicios update" $mail
                        else
                                echo "Formato de correo desconocido: $mail"
                        fi
                fi
        done
}

while getopts n:o:d:f:h OPT
do
        case $OPT in
                n) STATNUM="$OPTARG" ;;
                o) TARGETDIR="$OPTARG" ;;
                d) DAYSNUM="$OPTARG" ;;
                f) FILENAME="$OPTARG" ;;
                h)
                        phelp
                        exit 0
                ;;
                ?)
                        phelp
                        exit 1
                ;;
                esac
done

if [ -z "$STATNUM" ]; then
        echo "*** Ocurrio un error o hace falta el parametro -n"
        phelp
        exit 1;
fi

#Se actualiza la base de datos
chdb

#Se genera el reporte
rm $TARGETDIR/*.pdf 2> /dev/null
FILENAMESTAT=`$OTRS_BIN/otrs.GenerateStats.pl -n $STATNUM -o $TARGETDIR -f Print 2> /dev/null | grep -o "$PREFIXFILENAMESTAT.*pdf"`

#¿Quiere que se envie por correo?
if [ -n "$FILENAME" ]; then
        if [ -f $FILENAME ]; then
                sendmail_
        else
                echo "No existe el archivo $FILENAME"
                exit 1;
        fi
fi

exit 0;

Como lo usamos:
martinbarriga@monitoreo:/usr/local/sbin$ ./otrs.GenerateStats.sh -h
Usage: ./otrs.GenerateStats.sh -n  -o  -d  | -h
 -n Numero de estadística.
 -o Directorio destino de la estadistica. [ Predeterminado: /home/user ]
 -d Rango de fechas de los utimos dias hasta hoy. [ Predeterminado: 7 ]
 -h Ayuda, este mensaje.

lunes, 7 de mayo de 2012

Construcción de Plugin Nagios/Centreon para HP Printer

Hace unas horas termine un script en bash para monitorear los consumibles de unas impresoras HP, la idea de agregarlas a centreon es para darnos conocer en buen momento cuando uno de los consumibles se están por terminar así como un histórico (usando las graficas) de cuanto se esta consumiendo. A posteriori, este script se tendría que poder usar en cualquier impresora HP con SNMP activado, los modelos de impresoras que tenemos son las siguientes:
  • HP LaserJet 4700 Color
  • HP LaserJet 4600 Color
  • HP LaserJet 4250
Requerimientos del script:
  • awk
  • snmpwalk
  • A nivel de red, acceso al segmento de las impresoras.
  • bash
  • etc.
#!/bin/bash
# Martin Barriga 2012

# Default options
COMMUNITY="public"
HOSTNAME="127.0.0.1"
CONSUMMABLE="black"
WARNING=20
CRITICAL=10
SNMPVERSION=2c
SHEETCOUNT="0"
sheetcount=""

#used MIBs
MAINMIB="mib-2.43.11.1.1.6.1"
SHEETMIB="enterprises.11.2.3.9.4.2.1.4.1.10.5.1.1"

# Plugin return codes
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3

# Option processing
function phelp {
  echo -e "Usage: $0 -H  -C  -v  -o  -w  -c   [ -l | -s ] | -h "
  echo -e "  -H IP Addres HP Printer"
  echo -e "  -C SNMP Community. Default 'public'"
  echo -e "  -v SNMP Version. Default '2c'"
  echo -e "  -o Color Tonner: black, cyan, magenta, yellow, transfer, fuser. Default 'black'"
  echo -e "  -w Warning Value. Default '80'"
  echo -e "  -c Critical Value. Default '90'"
  echo -e "  -l List consumible support."
  echo -e "  -s Print with sheet count available."
  echo -e "  -h Help, this message.\n"
}

function list {
        allinfo=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $MAINMIB`;
        echo "$allinfo" | ( while read line; do
                echo $line | cut -d "\"" -f2;
        done )
}

function withsheetcount {
        index=`echo "$1" | cut -d "." -f8`;
        count=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $SHEETMIB.$index | cut -d " " -f4`;
        sheetcount=", Sheet Available: $count";
}

while getopts H:C:v:o:w:c:slh OPT
do
  case $OPT in
    H) HOSTNAME="$OPTARG" ;;
    C) COMMUNITY="$OPTARG" ;;
    v) SNMPVERSION="$OPTARG" ;;
    o) CONSUMMABLE="$OPTARG" ;;
    w) WARNING=$OPTARG ;;
    c) CRITICAL=$OPTARG ;;
    s) SHEETCOUNT="1" ;;
    l)
       list
       exit $STATE_UNKNOWN
    ;;
    h)
       phelp
       exit $STATE_UNKNOWN
    ;;
    #V)
    #  print_version
    #  exit $STATE_UNKNOWN
    #  ;;
   esac
done

info=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $MAINMIB | grep -i $CONSUMMABLE`
if [ "$info" != "" ]; then
        name=`echo "$info" | cut -d "\"" -f 2`;
        mib=`echo "$info" | cut -d " " -f 1 | cut -d ":" -f 3`;
        newmib=`echo "$info" | cut -d " " -f 1 | cut -d ":" -f 3 | awk -F. -v OFS=. '{$6=8}1'`;
        size=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $newmib | cut -d " " -f4`;
        newmib=`echo "$info" | cut -d " " -f 1 | cut -d ":" -f 3 | awk -F. -v OFS=. '{$6=9}1'`;
        value=`snmpwalk -c $COMMUNITY -v $SNMPVERSION $HOSTNAME $newmib | cut -d " " -f4`;
        let porcent=($value*100)/$size;

        #If sheet count is required
        if [ "$SHEETCOUNT" = "1" ]; then
                withsheetcount $mib
        fi

        if [ "$porcent" -le "$CRITICAL" ]; then
                echo "$name: Status: $value/$size $porcent% available [ CRITICAL ] | size=$size used=$value";
                exit $STATE_CRITICAL;
        else
                if [ "$porcent" -le "$WARNING" ]; then
                        echo "$name: Status: $value/$size $porcent% available [ WARNING ] | size=$size used=$value";
                        exit $STATE_WARNING;
                else
                        echo "$name: Status: $value/$size $porcent% available [ OK ] | size=$size used=$value";
                        exit $STATE_OK;
                fi
        fi
else
        echo "No se encuentra consumible $CONSUMMABLE en $HOSTNAME [ UNKNOW ]"
        exit $STATE_UNKNOWN
fi

martes, 27 de marzo de 2012

Exportando M$ Active Directory a MySQL

El siguiente script me ayudo para exportar las cuentas de Active Directoy a una base de datos en MySql. El problema y/o interés surgió debido a la implementación de otrs, una solución para la gestión de servicios IT y help desk, donde se pretendía centralizar las cuentas locales de Active Directory como clientes en el contexto de la aplicación (otrs).
Para la solución de este problema (pensando en la automatización) había que hacer dos cosas, llenar la tabla de clientes con los datos de cada cuenta en la base de datos y cambiar el tipo de autentificación usando ldap.

Requisitos:
  • awk
  • openLdap
  • mysql-client

Script: ldap2mysql.sh

#!/bin/bash
# Martin Edmundo 2012
# Orden del listado AD: sn, givename, userPrincipalName

#Inicialización de variables
dbUser="otrs";
dbPasswd="/Gvxsn1CFaj5Q";
dbName="otrs";
let _i=0;

searchBase="DC=PGJ,DC=MICH";
bindDistinguishedName="account@domain";
ldapPasswd="AcbjdaIQ6P/9g";
ldapHost="ldap://172.16.1.2";

apellido="";
nombre="";
user="";

#Leemos el arbol completo de usuarios
tree=`ldapsearch -x -z 0 -b $searchBase -D $bindDistinguishedName -w $ldapPasswd "(objectclass=user)" -H $ldapHost | egrep "userPrincipalName|givenName|sn\: "`

#Leemos el ultimo customer_id que se tiene en la BD, sobre ese se incrementaran los siguientes INSERT
let lastCustomer=`mysql -u $dbUser -p$dbPasswd --database=$dbName --execute="select max(customer_id) as a from customer_user" | awk 'BEGIN{FS="\n"; RS="\n\n";}{print $2}' `

echo "$tree" | (
while read linea;
do
te_conozco=`echo $linea | cut -c1-2`
if [ "$te_conozco" = "sn" ]; then
apellido=`echo $linea | cut -f2 -d" "`;
fi
if [ "$te_conozco" = "gi" ]; then
nombre=`echo $linea | cut -f2 -d" "`;
fi
if [ "$te_conozco" = "us" ]; then
user=`echo $linea | cut -f2 -d" "`;
if [ "$apellido" != "" -a "$nombre" != "" ]; then
let lastCustomer+=1;
uid=`echo $user | cut -f1 -d"@"`
daleDale=`mysql -u $dbUser -p$dbPasswd --database=$dbName --execute="select login from customer_user where login='$uid'" | awk 'BEGIN{FS="\n"; RS="\n\n";}{print $2}'`

#Si la cuenta no esta ya registra en DB, se hace el INSERT
if [ "$daleDale" == "" ]; then
let _i+=1;
sqlStm="INSERT INTO customer_user (login, email, customer_id, pw, title, first_name, last_name, valid_id, create_time, create_by, change_time, change_by) VALUES ('$uid', 'informaticapgjmich@gmail.com',$lastCustomer, '', 'Importado por openLdap', '$nombre', '$apellido', 1, '2012-03-23 20:00:00', 1, '2012-03-23 20:00:00', 1)";
#echo "$sqlStm"
mysql -u $dbUser -p$dbPasswd --database=$dbName --execute="$sqlStm";
echo "*** Importado ($_i): $uid"
fi

fi
apellido="";
nombre="";
fi
done
)

viernes, 13 de mayo de 2011

Arbol de directorios con objeto Tree de java IceFaces.

Saludos, en esta ocación y de manera muy rapida tengo para ustedes un breve ejemplo de como llenar un objeto Tree en JavaIceFaces.



public class Page3 extends AbstractPageBean {
private static final String DIR_OPEN_ICON = "./xmlhttp/css/xp/css-images/tree_folder_open.gif";
private static final String DIR_CLOSE_ICON = "./xmlhttp/css/xp/css-images/tree_folder_close.gif";
private static final String DIR_LEAF_ICON = "./xmlhttp/css/xp/css-images/tree_document.gif";

private void get_tree(String dir, DefaultMutableTreeNode parent){
//Apertura del directorio
File a = new File(dir);
//Conseguimos un listado de los archivos y subdirectorios
String[] ficheros = a.list();
int i = 0;

//Agregamos los nodos al arbol, por cada archivo encontrado
try{
while ( i < ficheros.length ){
File tmp = new File( a.getCanonicalPath() +"/"+ ficheros[i]);

DefaultMutableTreeNode branchNode = new DefaultMutableTreeNode();
IceUserObject branchObject = new IceUserObject(branchNode);
branchObject.setText( ficheros[i] );
branchObject.setBranchContractedIcon(DIR_CLOSE_ICON);
branchObject.setBranchExpandedIcon(DIR_OPEN_ICON);
branchObject.setLeafIcon(DIR_LEAF_ICON);
branchObject.setExpanded(false);

//Si el archivo es un directorio volvemos a invocar el metodo.
if ( tmp.isDirectory() ){
branchObject.setLeaf( false );
this.get_tree( a.getCanonicalPath() +"/"+ ficheros[i] , branchNode);
}
else
branchObject.setLeaf( true );

branchNode.setUserObject(branchObject);
parent.add(branchNode);
i++;
}
}
catch (IOException e){
this.setLblCurrentDir("Error: " + e.getMessage());
}
}

private void lectura2(){
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
IceUserObject itemx = new IceUserObject(root);
itemx.setText("Directorios");
itemx.setExpanded(true);
itemx.setLeaf(false);
itemx.setBranchContractedIcon(DIR_CLOSE_ICON);
itemx.setBranchExpandedIcon(DIR_OPEN_ICON);
itemx.setLeafIcon(DIR_LEAF_ICON);
root.setUserObject(itemx);

//Directorio a visualizar
this.get_tree("..", root);

DefaultTreeModel model = new DefaultTreeModel(root);
this.tree1Model.setModel(model);
}
}


jueves, 12 de agosto de 2010

Catching process from devil with Bash

Cuando se tiene la necesidad de buscar procesos que consuman mucho recurso de computo como memoria o cpu, pero una limitante es lo poco practico de estar detras del comando top todo el tiempo, se nos obliga a pensar el automatizar esta busqueda y que asi nos de tiempo de salir a comer algo o dormir un poco.

En esta ocacion les presento un script que nos ayuda a buscar procesos que consumen mas de 50% de cpu y nos guarda en una bitacora la informacion de este procesos. Desde luego que se le pueden hacer mejoras pero las dejaremos al criterio del usuario. Espero les sea de utilidad.



#!/bin/bash
#Variable para solo encontrar un proceso
status=0

while [ $status -eq 0 ] ;
do
cont=`ps aux | awk '$3>50 { print }' | wc -l`
if [ $cont -gt 0 ]; then
ps aux | awk '$3>50 { print }' >> procesos.txt
date >> procesos.txt
#Podriamos ponerlo a 1 para solo encontrar 1 proceso
status=0
fi

echo scanning...
#esperamos 5 minutos para volver a buscar
sleep 300
done

martes, 22 de junio de 2010

Bash Scripting: Recursive Search inside text files

Anteriormente había tenido la necesidad de hacer búsquedas recursivas de alguna cadena, en todos los archivos de texto de un árbol de directorios. Un ejemplo típico es un parámetro o valor usado por algún aplicativo y que no recordamos claramente en que archivo de conflagración esta, en este contexto es donde personalmente he tenido la necesidad de una herramienta así.

Les quiero compartir un script que realiza precisamente este tipo de búsquedas, este script bien se puede adaptar para realizar operaciones sobre estos archivos, permisos, modificaciones, borrados, etc. Sin embargo eso ya queda de tarea de acuerdo a sus necesidades.


#!/bin/bash

if [ "$#" != "1" ]; then
echo "usage: finder ";
exit 1;
fi

#Se consigue un listado recursivo de los archivos en el directorio actual y subdirectorios
du -a * | awk 'BEGIN{"pwd" | getline LOCAL_PATH}{print LOCAL_PATH "/" $2}' | (
#Hacemos la lectura "filebyfile" o "linebyline"
while read line; do
#Solo buscamos en archivos de texto
file $line | grep text > /dev/null;
if [ "$?" -eq "0" ]; then
echo "*** Archivo de texto: $line";
cat $line | grep $1;
echo "";
fi
done
);
exit 0;

martes, 18 de mayo de 2010

Un vistazo a Iptables con DMZ


Revisando el baúl de los recuerdos me encontré con algunos trabajos escolares, y me se me ocurrió que era buena idea comentar alguno de ellos. Definitivamente uno de mis favoritos es iptables, y en este ejemplo hacemos una implementación de esas reglas para una arquitectura con DMZ.

Les voy a compartir un script, que lo que hace es activar un firewall usando iptables y que a la vez tiene finalidad de ayudarnos a protegernos a nivel de capa de red y transporte. El único requerimiento es tener instalado awk, e iptables en linux.

#!/bin/bash
#Re-adaptado por:
#Martin Edmundo Barriga Orozco

#Revisamos la dependencia de AWK
awk --version > /dev/null
if [ "$?" != "0" ]; then
echo "Se requiere AWK para continuar"
exit 1
fi

echo "Preparando interfaces..."
echo 1 > /proc/sys/net/ipv4/ip_forward

#Interfaces de red que usamos para la red LAN, DMZ e Internet
if_lan="eth1"
if_dmz="eth2"
if_pub="eth0"

#Direcciones que tenemos en cada interface
ip_pub="10.27.46.145"
ip_lan="172.16.1.254"
ip_dmz="192.168.1.254"

#Direcciones IPs conocidas.
web_server="192.168.1.1"
mail_server="192.168.1.3"
dhcp_server="192.168.1.129"
dns_server="192.168.1.2"

id_lan="172.16.0.0/16"
id_dmz="192.168.1.0/24"

#Configuracion final con el usuario
read -p "Habilitar uso para DMZ [y/N]: " enable_dmz
if [ "$enable_dmz" = "y" ]; then
if [ -n "$if_dmz" ]; then
#call metodo_valida_interfaz
echo "invocamos al metodo de validacion de interfaz"
else
echo " Interfaces Disponibles:"
#Imprimimos el listado de interfaces
ifconfig -a | awk 'BEGIN{FS="[ ]+" ; RS=""} $1!~/lo/{print " " NR ") " $1}'
read -p " Nombre de la interfaz a usar: " if_dmz

#call metodo_valida_interfaz
#echo "invocamos al metodo de validacion de interfaz"

echo -n " >>IP: " ;
#Se imprime la direccion IP de la interfaz $if_dmz
ifconfig $if_dmz | grep 'inet:' | awk 'BEGIN{FS="[ ]+"} {print $3}' | awk 'BEGIN{FS=":"}{print $2}'
read -p " Desea conservar esta IP para esta interfaz [y/N]: " tmp_ans
if [ "$tmp_ans" != "y" ]; then
read -p " Nueva IP: " ip_dmz
ifconfig $if_dmz $ip_dmz
fi
fi
fi

read -p "Habilitar el modo paranoico [y/N]: " enable_paranoico_mode


echo "Aplicando reglas del firewall..."


#Borrado de las reglas aplicadas actualmente (flush)
iptables -F #flush todas las cadenas
iptables -t nat -F
iptables -X #Borra cadenas definidas por el usuario
iptables -Z

#Activamos bitacora de reenvio
iptables -t nat -A PREROUTING -j LOG
iptables -t nat -A POSTROUTING -j LOG

#Politicas por defecto (INPUT OUTPUT FORWARD)
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT

#REDIRECCIONAMIENTO A SERVIDOR WEB EN DMZ DESDE LA LAN Y RED PUBLICA
iptables -t nat -A PREROUTING -i $if_lan -s $id_lan -d $ip_lan -p tcp --dport 80 -j DNAT --to 192.168.1.1:80
iptables -t nat -A PREROUTING -i $if_pub -d $ip_pub -p tcp --dport 80 -j DNAT --to 192.168.1.1:80
#iptables -t nat -A PREROUTING -i $if_lan -s 0.0.0.0 -d 255.255.255.255 -p udp --dport 67 -j DNAT --to 192.168.1.129:67

#ABRIENDO PUERTOS PARA INPUT, OUTPUT, FORWARD: TRABAJO SUCIO PERO HAY QUE HACERLO!

#Aceptamos peticiones de ICMP para la LAN.
iptables -A INPUT -i $if_lan -s $id_lan -d $ip_lan -p icmp -j ACCEPT
iptables -A OUTPUT -o $if_lan -s $ip_lan -d $id_lan -p icmp -j ACCEPT

if [ "$enable_dmz" = "y" ]; then
#Aceptamos peticiones e ICMP para la DMZ.
iptables -A INPUT -i $if_dmz -s $id_dmz -d $ip_dmz -p icmp -j ACCEPT
iptables -A OUTPUT -o $if_dmz -s $ip_dmz -d $id_dmz -p icmp -j ACCEPT
fi

#Aceptamos peticiones ICMP desde la red publica.
iptables -A INPUT -i $if_pub -s 0/0 -p icmp --icmp-type 8 -j ACCEPT
iptables -A OUTPUT -o $if_pub -d 0/0 -p icmp --icmp-type 0 -j ACCEPT

#Aceptamos el flujo para el DNS para la LAN. REVISAR
iptables -A INPUT -i $if_lan -p udp --dport 67 -j ACCEPT
iptables -A OUTPUT -o $if_lan -p udp --sport 67 -j ACCEPT

if [ "$enable_paranoico_mode" != "y" ]; then
#Aceptamos navegar en la web. (Opcional)
iptables -A INPUT -i $if_pub -p tcp --sport 80 -j ACCEPT
iptables -A OUTPUT -o $if_pub -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i $if_pub -p tcp --sport 443 -j ACCEPT
iptables -A OUTPUT -o $if_pub -p tcp --dport 443 -j ACCEPT

#Aceptamos las peticiones de MSNP, tenemos tolerancia. xD (Opcional)
iptables -A INPUT -i $if_pub -p tcp --sport 1863 -j ACCEPT
iptables -A OUTPUT -o $if_pub -p tcp --dport 1863 -j ACCEPT
fi

#Aceptamos el flujo de DNS para la red publica. REVISAR
iptables -A INPUT -i $if_pub -p udp --sport 53 -j ACCEPT
iptables -A OUTPUT -o $if_pub -p udp --dport 53 -j ACCEPT

if [ "$enable_dmz" = "y" ]; then
#Permitimos el flujo de de comununicacion entre el WEB server de la DMZ y los clientes de la LAN
#Evitamos rafagas de paquetes syn.
iptables -A FORWARD -i $if_lan -o $if_dmz -s $id_lan -d $web_server -p tcp --dport 80 -m limit --limit 3/minute --limit-burst 3 state --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $if_dmz -o $if_lan -s $web_server -d $id_lan -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

#Permitimos el flujo de de comununicacion entre el DNS server de la DMZ y los clientes de la LAN
iptables -A FORWARD -i $if_lan -o $if_dmz -s $id_lan -d $dns_server -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -i $if_dmz -o $if_lan -s $dns_server -d $id_lan -p udp --sport 53 -j ACCEPT

#Permitimos el flujo de de comununicacion entre el MAIL server de la DMZ y los clientes de la LAN
iptables -A FORWARD -i $if_lan -o $if_dmz -s $id_lan -d $mail_server -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $if_dmz -o $if_lan -s $mail_server -d $id_lan -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT

#Permitimos el flujo de de comununicacion entre el MAIL server de la DMZ y los clientes de la LAN
iptables -A FORWARD -i $if_lan -o $if_dmz -s $id_lan -d $mail_server -p tcp --dport 110 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $if_dmz -o $if_lan -s $mail_server -d $id_lan -p tcp --sport 110 -m state --state ESTABLISHED -j ACCEPT

#Permitimos el flujo de de comununicacion entre el MAIL server de la DMZ y los clientes de la LAN
iptables -A FORWARD -i $if_lan -o $if_dmz -s $id_lan -d $mail_server -p tcp --dport 143 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $if_dmz -o $if_lan -s $mail_server -d $id_lan -p tcp --sport 143 -m state --state ESTABLISHED -j ACCEPT

#Permitimos el flujo de ICMP hacia el servidor web
iptables -A FORWARD -i $if_lan -o $if_dmz -s $id_lan -d $web_server -p icmp -j ACCEPT
iptables -A FORWARD -i $if_dmz -o $if_lan -s $web_server -d $id_lan -p icmp -j ACCEPT

#Permitimos a nuestro servidor DNS, solicitar direcciones al DNS del ITMorelia
iptables -A FORWARD -i $if_dmz -o $if_pub -s $dns_server -d 200.33.171.1 -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -i $if_pub -o $if_dmz -s 200.33.171.1 -d $dns_server -p udp --sport 53 -j ACCEPT

#iptables -A FORWARD -i $if_dmz -o $if_pub -p udp --dport 53 -j ACCEPT
#iptables -A FORWARD -i $if_pub -o $if_dmz -p udp --sport 53 -j ACCEPT

#Permitimos a nuestro servidor DNS, solicitar direcciones al DNS del ITMorelia
iptables -A FORWARD -i $if_dmz -o $if_pub -s $dns_server -d 200.33.171.8 -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -i $if_pub -o $if_dmz -s 200.33.171.8 -d $dns_server -p udp --sport 53 -j ACCEPT

#Permitimos exponer nuestro webserver a la red publica.
iptables -A FORWARD -i $if_pub -o $if_dmz -d $web_server -p tcp --dport 80 -m limit --limit 5/minute --limit-burst 5 -j ACCEPT
iptables -A FORWARD -i $if_dmz -o $if_pub -s $web_server -p tcp --sport 80 -j ACCEPT
else
#Sino hay DMZ permitimos a los clientes LAN consultar DNS externos
iptables -A FORWARD -i $if_lan -o $if_pub -s $id_lan -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -i $if_pub -o $if_lan -d $id_lan -p udp --sport 53 -j ACCEPT
fi

#Permitimos a las personas de la LAN, navegar en la web.
iptables -A FORWARD -i $if_lan -o $if_pub -s $id_lan -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $if_pub -o $if_lan -d $id_lan -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $if_lan -o $if_pub -s 172.16.1.21 -p tcp --dport 443 -j ACCEPT ##1863 :1503 3389
iptables -A FORWARD -i $if_pub -o $if_lan -d 172.16.1.21 -p tcp --sport 443 -j ACCEPT

#Permitimos el uso del MSNP en la computadora del SysAdmin dentro de la LAN
iptables -A FORWARD -i $if_lan -o $if_pub -s 172.16.1.21 -p tcp --dport 1863 -j ACCEPT ##1863 :1503 3389
iptables -A FORWARD -i $if_pub -o $if_lan -d 172.16.1.21 -p tcp --sport 1863 -j ACCEPT
iptables -A FORWARD -i $if_lan -o $if_pub -s 172.16.1.21 -p udp --dport 1863 -j ACCEPT
iptables -A FORWARD -i $if_pub -o $if_lan -d 172.16.1.21 -p udp --sport 1863 -j ACCEPT

#ENMASCARAMIENTO DE LA RED Y LA DMZ
iptables -t nat -A POSTROUTING -o $if_pub -s $id_lan -j MASQUERADE
if [ "$enable_dmz" = "y" ]; then
iptables -t nat -A POSTROUTING -o $if_pub -s $dns_server -p udp --dport 53 -j MASQUERADE
iptables -t nat -A POSTROUTING -o $if_pub -s $id_dmz -j MASQUERADE
iptables -t nat -A POSTROUTING -o $if_dmz -s $id_lan -d $web_server -p tcp --dport 80 -j SNAT --to-source $ip_dmz
iptables -t nat -A POSTROUTING -o $if_dmz -s ! $id_lan -d $web_server -p tcp --dport 80 -j SNAT --to-source $ip_dmz
#iptables -t nat -A POSTROUTING -o $if_dmz -s 0.0.0.0 -d $dhcp_server -p udp --dport 67 -j SNAT --to-source $ip_dmz
fi

echo "Reglas aplicadas correctamente :)"

sábado, 8 de agosto de 2009

OpenLaszlo: dataset timeout && events problems

Have a problem with some dataset, i wanna execute query and then fast as Ana Guevara, to get the data from dataset that has been executed. But, i have a warning: timeout. This is result from next code:

//we launched the first query, and the data is store in opEnfermedades
var p=new LzParam();
p.addValue("id", "myarg1", true);
canvas.datasets.opEnfermedades.setQueryString(p);
canvas.datasets.opEnfermedades.doRequest();

//get the data from dataset
this.txtBox1.setAttribute('dataset', 'opEnfermedades:/xml/resultado[1]/@id');


The debbuger show me a timeout in txtBox1 properties, in fact the parent view apparently is correct, can see the dataset property with my xml struct and consequently the data.

I try to resolve this problem, thinking for 3 thing:
  • loop persistence: using a global var that is edited when the data is arrival (inside from a event), then a loop persistence check this var for know 'when' the data is ready. This idea i dont like, because must be using a globar var and i lost independence from clases, and my application is bloking a little bit.
  • Using a timer: When i use a timer, the data is update correctly. The bad idea is because the time to reply is changeable, in my notebook could to reply fine but in internet is very very dificult to calculate this.
  • Using Envents: i develop this. I must explain:
//we launched the first query, and the data is store in opEnfermedades
var p=new LzParam();
p.addValue("id", "myarg1", true);
canvas.datasets.opEnfermedades.setQueryString(p);
canvas.datasets.opEnfermedades.doRequest();


When the data arrival, opEnfermedades dataset make a event called "ondata", i used this event for update my text box widget, but openlaszlo acting weird, i dont know. I need this for do a second query using the data catched as param. I think that to resolv this send all data in only one query and that my view model work (PHP, JSP) for me.

I must apologize me, but my english is bad, i wish do it. I hope a comments. Tnx.

jueves, 30 de julio de 2009

Paso de parametros en OpenLaszlo

Continuando con mi trabajo en OpenLaszlo, he tenido necesidad de hacer otro tipo de cosas en LZX (el lenguaje), necesito comunicar dos instancias de clases, tomar y modificar atributos de las mismas. Una solucion que siempre se metia (y sin invitacion) a mi mente era la de variables globales, pero no me latia por que pense que perderia algo de independencia de clases y terminaria dependiendo de ese tipo de datos.

Espero que esto le pueda servir a alguien, la documentacion de laszlo es muy superficial, y no profundizan en algunos detalles que hacen que al final nos demos unos 6 o 7 golpes en la cabeza. A continuacion dejo un ejemplo de un codigo con paso de parametros, instancias de clases, herencia, metodos y atributos.


El paso de parametros es parecido a lo que vi en Java (tengo poca experiencia en OOP), cuando enviamos un tipo de dato primitivo es paso por valor y cuando enviamos una instancia es paso por referencia, asi de simple y en el ejemplo estoy mandando una instancia con el operador this.

La idea del ejemplo es que..., tenemos dos ventanas en una metemos datos al texbox computamos y mandamos los valores a la otra ventana haciendo un paso por referencia.Les dejo un enlace donde pueden ver el ejemplo funcinando.

lunes, 20 de julio de 2009

Vim's scripting language

Hace unos dias leyendo las noticias de cofradia me encontre con información sobre vim scripting, como algunos de uds tal vez imaginen, puedo decir que Vim es mi edito de textos favoritos por que es muy rapido, y sobre todo por el espacio en disco.

La idea de hacer a mi vim un poco mas robusto o simplemente conocerlo mas, me entusiasmo y me puse a leer el articulo. El lenguaje de scripts de vim, segun el articulo es un lenguaje con muchas caracteristicas como variables, espresiones, control de flujo, estructuras de datos, funciones, IO file, excepciones, debugger, entre muchas cosas.

Como comenzar, pues bien rapidamente ocupamos los paquetes vim y vim-scripts, desde luego que la documentacion que en caso de tenerla podemos consultarla de la siguiente manera.
:help vim-script-intro

Como mandar a ejecucion nuestras pruebas
:source /full/path/to/the/scriptfile.vim

El resto es comenzar a adentrarnos en este lenguaje.

domingo, 21 de junio de 2009

Java: comparacion de String Class en una sentencia Case

Hace unos dias platicando con mi amigo Ernesto, le comente que trabajando con el String Class y sus comparaciones con if-then-else me estaba creando un codigo no muy estetico en cuanto a las identaciones y anidamientos que debia tener dentro de mi codigo.

Buscando soluciones esteticas y sobre todo eficientes, Ernesto me comento que habia la posibilidad de resolver este problema con una tabla hash, asi que me di a la tarea de ver las APIs de las clases que me podrian servir. La implementacion es como sigue:


//Instancia del hashtable, se agregan los valores que esperamos recibir
Hashtable action = new Hashtable();

//Se registran las cadenas y los valores que van a tener en hashtable
action.put("list", new Integer(1));
action.put("new", new Integer(2));
action.put("edit", new Integer(3));
action.put("rm", new Integer(4));

//Se intenta capturar la excepcion en el caso de que llegue
//otro valor distinto a los esperados en hashtable
try{
switch( (Integer) action.get( myString ) ){
case 1:
//codigo para cuando llega una cadena "list"
case 2:
//codigo para cuando llega una cadena "new"
case 3:
//codigo para cuando llega una cadena "edit"
case 4:
//codigo para cuando llega una cadena "rm"
}
}
//En caso de llegar cadena no registrada se captura la excepcion
catch(NullPointerException e){
//codigo de exepcion, algo asi como un "default" dentro del case
}

jueves, 12 de febrero de 2009

Rendimiento en Laszlo

Trabajando nuevamente con laszlo, la necesidad de una aplicacion mas rapida desperto mi interes por analizar los tiempos con que se invocan metodos y funciones en laszlo. No encontre mucho en el manual, hablan de variables locales y otras cosas pero nada al respecto de lo que hablaremos aqui.

Rapidamente una explicacion en 30,000ms :) Los procedimientos que tenemos pueden estar en funciones JS o en metodos de nuestros objetos.

En el siguiente codigo, hay dos funciones JS, como vemos la funcion principal es despachador(), la cual invoca a script_js() 9000 veces. Como se ve en la linea comentada, frmCiudades.metodo_local(), es un metodo de un objeto frmCiudades y podemos conmutar entre uno y otro, cambiando los comentarios.

<script> <![CDATA[
function despachador(){
var begin = (new Date).getTime();
for (var i = 0; i < 9000; i++){
script_js();
//frmCiudades.metodo_local();
}
var end = (new Date).getTime();
var total = end - begin;
colocar.setAttribute('text',total);
}

function script_js(){
frmCiudades.setAttribute('title','updating...');
}
]]>
</script>


La alternativa a eso es tener un despachador2 en la clase frmCiudades, pero ahora como metodo y ver como responde. A continuación vemos el codigo.

<method name="metodo_local" >
frmCiudades.setAttribute('title','updating... Metodo');
</method>
<method name="despachador2"> <![CDATA[
var begin = (new Date).getTime();
for (var i = 0; i < 9000; i++){
//script_js();
metodo_local();
}
var end = (new Date).getTime();
var total = end - begin;
colocar.setAttribute('text',total);

]]>
</method>


Lo que hice aqui es medir los tiempos que Laszlo se tarda en:
Caso 1. Desde la funcion JS despachador() invocar el metodo metodo_local()
Caso 2. Desde la funcion JS despachador()invocar la otra funcion JS script_js()
Caso 3. Desde el metodo despachador2() invocar la funcion JS script_js()
Caso 4. Desde el metodo despachador2() invocar el metodo metodo_local()

Aqui la hipotesis es saber que combinacion nos da mejores resultados, o que sistemas (funciones JS o metodos locales) operan mas rapido. La actividad realizada fue que ejecutaba mi programa y en cada uno de esos casos 20 veces, dando asi pequeñas muestras de cada caso.

Los promedios resultados son:
Caso 1. 1341.95ms
Caso 2. 1318.10ms
Caso 3. 1360.75ms
Caso 4. 1383.15ms

Estos resultados me indican que las funciones de JS son mas rapidas, y la alternativa mas rapida es invocar una funcion desde otra funcion en JS.

viernes, 30 de enero de 2009

Escritorio Remoto Funcionamiento

No crean que lo había olvidado, aun me quedaba por dar al menos una explicación al respecto de este proyecto que empecé en las residencias. Se trataron de cubrir la mayoría de requisitos pero no fue posible, por problemas de los cuales no hablare aquí. Se presenta un prototipo funcional.

Este es el diagrama del funcionamiento una vez implementado (uno de los faltantes pero se que funciona). Deberemos usar dos servidores uno de ellos debe ser un web server, como apache, cherokee; incluso paginas dinámicas, lo que pasa es que ocupamos que vía web pasemos un applet al cliente web. Esta parte de applet se pude cambiar por una aplicación Java Web Start.

Entonces via web se solicita la aplicacion java, se manda al cliente y esta aplicacion debe saber a donde se conecta para permitir ser controlado por ese servidor al que se conecta.

Ya se que esta arquitectura trae consigo muchos problemas de seguridad y dolores de cabeza, para eso se sugiere implementar mecanismos de firmas digitales para tratar de asegurar la Irrefutabilidad, como dice Gunnar Wolf en uno de sus artículos de Infraestructura de llaves publicas.

Una vez que se ejecute este procedimiento, en la computadora de Servidor 1 (ver imagen), se podrá controla atravez de un Frame la PC cliente remota, sin importar su S.O., ni el browser que use, solo se ocupa que tenga JRE y listo. Los puertos que se usan en el Server 1 para poder librar al firewall son los puertos TCP 80 y 25.

Si a alguien le interesa conocer alguna parte del código que hace alguna cosa, comenten y listo.

lunes, 26 de enero de 2009

Mi primer script en Perl

El lenguaje perl es un lenguje interpretado, el cual puede ser muy usando en tareas de adminitracion de sistemas, como manipulacion de archivos y procesos.

A continuacion les muestro un pequeño script que escribi hace algunos meses y que recibe como parametro un archivo de texto con una direccion url por linea, con el fin de descargar el archivo que se encuentre en esa url.

================
#!/usr/bin/perl

#se busca la url que debe existir en cada pagina
sub with_loop{
#Se abre en modo lectura (predeterminado)
open(IN, $_[0] );
#Comenzamos la lectura linea por linea
#y cada linea la mandamos como parametro a wget
while( $line =
){
open (COMM, "wget -c --progress=bar $line |" );
print COMM;
close (COMM);
}
close(IN);
}

#Comienzo del script, se verifican parametros
if( $#ARGV != 0 ){
print "usage: " . $0 . "
\n";
}
else{
#Si el archivo existe y se puede leer
if (-r $ARGV[0]){
#Invocacion del metodo with_loop
do with_loop( $ARGV[0] );
}
else{
print "El archivo " . $ARGV[0] . ", no existe o no hay permisos de lectura\n";
}
}
===============

David por favor recuerdame cual era el otro script que se pretendia hacer, gracias.

miércoles, 19 de noviembre de 2008

Video Demostrativo

Como les habia prometido aqui les traigo un video de como funcionan las clases esas, le pido una disculpa pues mi compu me piede... no no, me exije a gritos mas memoria 512Mb ya no es suficiente y el video se ve un poco cortado.


Aqui solo sigo el rastro del mouse, pero ya tengo las otras implementaciones donde puedo controlar a mi volutad el mouse remoto. Saludos, espero comentarios

sábado, 15 de noviembre de 2008

Seguimiento y control del mouse con Java

Bien, tratare de ser breve ya es la 1:10am y acabo de terminar un pequeño prototipo. Como algunos de uds saben (o David pues es el unico que creo que lee jejeje), estoy trabajando en un sistema de escritorio remoto, basado en Java, ¿por que java? bueno yo no elegi el lenguaje (aunque no hice nada para cambiar eso).

Hasta el momento me han comentado algunos aspectos en los cuales debo concentrarme:
  • Remote Desktop que pueda pasar sin problemas en firewall de tu empresa o ISP, operar incluso en comunicacion entre red publica-privada y el caso contrario tambien.
  • Se debera evitar que el usuario instale algun programa, como estara basado en web, solo los plugins del browser nos valen.
  • Facilidad de uso.
Por lo tanto para administrar un equipo remoto, necesitamos poder manipular algunos de sis dispositivos de entrada, como el mouse y el keyboard. Siendo el lenguaje Java, de momento me di cuenta de que existe algo que se llama JNI (Java Native Interface), con la cual podemos hacer invocacion a metodos y funciones escritos en lenguaje C/C++, con el objetivo principal de accesar a los recursos de la maquina. ¿Pero al ser web como envio los binarios? podria tratar de resolver esto de algunas maneras que no se me hicieron muy practicas, asi que segui buscando y vi algo en las librerias de AWT, con lo que puede resolverme ese detalle.

Lo dejare en suspenso para la proxima publicacion, donde les comentare que clases me sirvieron y de la misma manera le compartire un video demostrativo del funcionamiento del prototipo. Les dejo solo el screen, cada ventana viene en un proceso independiente los cuales comunico con un socket, si yo muevo el mouse en la ventana de la izquierda, automaticamente le hago un seguimiento de su rastro en la otra venta, es decir estoy mandando coooredenas, y sobre esas coordenadas yo movere mi mouse en el equipo remoto, asi o mas facil.


Como nota final, quiero comentar que buscando en la red, como hacer esto, la informacion no me fue muy util ya que veo que se mal interpreta, controlar el mouse con monitorear el mouse y recibir sus eventos. Para mi controlar el mouse es moverlo por software y monitorerear es recibir sus eventos.

domingo, 27 de julio de 2008

Mi primera Interfaz Grafica de Usuario con Laszlo

Saludos, pues despues de un rato de estar metido en lo mismo, por fin les trago algo mas concreto, y eso es la GUI de Clientes de la aplicacion que estamos haciendo. He tenido algunos problemas relacionados con el despliege de datos, dentro del grid que se muestra.

Lo que no habia revisado bien es que, dentro de laszlo existen gerarquias de objetos, y estaba tratado de accesar a un lugar de esa jerarquia sin especificar exactamente donde esta ese objeto, dentro de la estructura de xml. La estructura de los datos que estoy cargado es la siguiente:

<clientes>
<registro nombre="Martin Edmundo" direccion="Jose A. Romero 18" rfc="BAOM831012" cp="58170" tel="2951176" />
<registro nombre="Miguel Gonzalez" direccion="Mario Molina 23" rfc="GOMI741012" cp="78170" tel="2922376" />
<registro nombre="Jose Antonio" direccion="Morones Prieto 43" rfc="SAJA830512" cp="58170" tel="3161201" />
<registro nombre="Fabiola Romero" direccion="Morelos 23" rfc="ROLF880421" cp="05140" tel="2932346" />
<registro nombre="Jaqueline Gaona" direccion="Poliducto 190" rfc="GARJ830703" cp="58170" tel="2492346" />
</clientes>
Estos solo son datos de prueba, asi que no hay nada oficial, lo que esto me deja es saber como se cargan dentro del grid. Si alguien esta interesado o quiere compartir experiencias al respecto pues adelante.

Por ultimo como se imaginan, esta ventana es mostrada en el navegador favorito que cada persona tenga instalado en su sistema, es esto lo que llamamos aplicacion basada en web.

lunes, 14 de julio de 2008

OpenLaszlo

Como les habia quedado a deber, les tengo los detalles de la herramienta que estamos usando, OpenLaszlo. Es una herramienta para el desarrollo de aplicaciones web, y por esto debemos entender formularios llevados al web, un posible equivalente visual que recuerdo seria los applets de Java.

Aqui hacemos uso del lenguaje de programacion LZX, que es muy parecido a xml, y java script. El lenguaje es orientado a objetos.

En cuanto a la arquitectura, necesitamos un servidor que nos pueda compilar el codigo lzx, este servidor esta dentro de otro servidor y viejo amigo nuestro: tomcat, servidor de jsp. Este detalle de tener un servidor dentro de otro servidor, en mi punto de vista es comprometer el rendimiento de nuestras aplicaciones, aunque la gente de laszlo diga que su codigo es muy muy optimizado, en pequeñas pruebas que he realizado pues no lo veo rapido :(

Aun asi es una buena alternativa para el desarrollo de este tipo de soluciones llevadas al web.
Por ultimo ya solo les dejo la referencia al editor de OpenLaszlo en linea, con el cual podemos hacer pruebas sin la necesidad de tener todo los requerimientos de software instalados en nuestro equipo. [ editor ].