martes, 8 de noviembre de 2011

Pasar Reglas de Iptables a Postgres

Bueno...

el caso es que se tiene uno o varios firewall en linux...

Los mismos funciona bien y se desea pasar dichas reglas del iptables a una base de datos en este caso postgres y a su ves colocarlo en el crontab para que cierto tiempo dicha tabla se mantenga actualizada.

Para realizarlo se utilizo Perl como lenguaje.

PASO 1.

Crear la tabla en nuestra base de datos y darle permiso al usuario y a la ip del firewall.

-- Table: iptables

-- DROP TABLE iptables;

CREATE TABLE iptables
(
  id_iptable serial NOT NULL,
  protocol character varying,
  bytes character varying,
  s_port character varying,
  packets character varying,
  dport character varying,
  state character varying,
  target character varying,
  intf_in character varying,
  d_port character varying,
  to_ip character varying,
  src character varying,
  intf_out character varying,
  sport character varying,
  dst character varying,
  to_port character varying,
  rawx character varying,
  firewall numeric,
  comentario character varying,
  CONSTRAINT pk_id_iptable PRIMARY KEY (id_iptable)
)
WITH (OIDS=FALSE);
ALTER TABLE iptables OWNER TO postgres;
GRANT ALL ON TABLE iptables TO postgres;
GRANT SELECT, INSERT, DELETE ON TABLE iptables TO mi_user;

PASO 2

Tener instalado PERL en el firewall o donde esten las reglas que deseamos pasar a la BD.
En el 99.99% de las distribuciones linux perl viene instalado por defecto.

PASO 3

Instala los modulos necesarios de Perl. Estas son:

- IPTables::Parse
- DBD::Pg (Opcional)
- DBI

Los mismos pueden ser instalados según su preferencia que hasta ahora yo conozco de tres maneras:

1_. Descargando las librerias e instalando con MAKEFILE()
2_. Utilizando CPAN(Es la forma automatizada de la manera 1).
3_. Entrar como root he instalar

#apt-get install libdbd-pg-perl libiptables-parse-perl libclass-dbi-pg-perl

PASO 4

Una vez instalado... creamos un archivo con el siguiente contenido

#!/usr/bin/perl
use IPTables::Parse;
use Data::Dumper;
use DBI;
$firewall = "Nombre del Firewall";
  my %opts = (
      'iptables' => '/sbin/iptables',
      'iptout'   => '',
      'ipterr'   => '',
      'debug'    => 0,
      'verbose'  => 0
  );

  #Creamos los obj necesarios para guardar las reglas y recorrelas

  my $ipt_obj_forward = new IPTables::Parse(%opts)
      or die "[*] Could not acquire IPTables::Parse object";
  my $ipt_obj_input = new IPTables::Parse(%opts)
      or die "[*] Could not acquire IPTables::Parse object";
  my $ipt_obj_snat = new IPTables::Parse(%opts)
      or die "[*] Could not acquire IPTables::Parse object";

    print "Cadena FORWARD por defecto: ",$ipt_obj_forward->chain_policy('filter', 'FORWARD'), "\n";
    @rules_forward = $ipt_obj_forward->chain_rules('filter', 'FORWARD');
        #Realizamos nuestra conexion a la BD
    my $dbh = DBI->connect("DBI:Pg:dbname=mi_bd;host=localhost", "mi_user", "password",  {'RaiseError' => 1});
        #Limpiamos reglas anteriores en la nuestra Tabla
    $sql = "DELETE FROM iptables WHERE firewall = '$firewall'";
        my $rows = $dbh->do($sql);
    $num = 1;
    for ($count = 0; $count < $num; $count++) {
        %xhash =%{$rules_forward[0][$count]};
        $proto = $xhash{protocol};
        $bytes = $xhash{bytes};
        $s_port = $xhash{s_port};
        $packets = $xhash{packets};
        $dport = $xhash{dport};
        $state = $xhash{state};
        $target = $xhash{target};
        $intf_in = $xhash{intf_in};
        $d_port = $xhash{d_port};
        $to_ip = $xhash{to_ip};
        $src = $xhash{src};
        $intf_out = $xhash{intf_out};
        $sport = $xhash{sport};
        $dst = $xhash{dst};
        $to_port = $xhash{to_port};
        $raw = $xhash{raw};
                $extended = $xhash{extended};
        chop($proto);
        if ($raw ne ""){
                        #INSERTO REGLA EN BD 
            @datos = split(/\t/, $raw);
                        $sql = "INSERT INTO iptables(protocol, bytes, s_port, packets, dport, state, target, 
            intf_in, d_port, to_ip, src, intf_out, sport, dst, to_port, rawx,firewall,comentario)VALUES ('$proto', '$bytes', '$s_port', '$packets', '$dport', '$state', '$target', '$intf_in', '$d_port', '$to_ip', '$src', '$intf_out', '$sport','$dst','$to_port','$raw','$firewall','$extended')";
                        my $rows = $dbh->do($sql);
            $num++;
        }
    }
#Imprimo cantidad de reglas de dicho Filtro.
print $num."\n";

print "Cadena INPUT por defecto: ",$ipt_obj_input->chain_policy('filter', 'INPUT'), "\n";
    @rules_input = $ipt_obj_input->chain_rules('filter', 'INPUT');
$num = 1;
    for ($count = 0; $count < $num; $count++) {
        %xhash =%{$rules_input[0][$count]};
        $proto = $xhash{protocol};
        $bytes = $xhash{bytes};
        $s_port = $xhash{s_port};
        $packets = $xhash{packets};
        $dport = $xhash{dport};
        $state = $xhash{state};
        $target = $xhash{target};
        $intf_in = $xhash{intf_in};
        $d_port = $xhash{d_port};
        $to_ip = $xhash{to_ip};
        $src = $xhash{src};
        $intf_out = $xhash{intf_out};
        $sport = $xhash{sport};
        $dst = $xhash{dst};
        $to_port = $xhash{to_port};
        $raw = $xhash{raw};
        $extended = $xhash{extended};
        chop($proto);
        if ($raw ne ""){
            #INSERTO REGLA EN BD         
            @datos = split(/\t/, $raw);
                        $sql = "INSERT INTO iptables(protocol, bytes, s_port, packets, dport, state, target, 
            intf_in, d_port, to_ip, src, intf_out, sport, dst, to_port, rawx,firewall,comentario)VALUES ('$proto', '$bytes', '$s_port', '$packets', '$dport', '$state', '$target', '$intf_in', '$d_port', '$to_ip', '$src', '$intf_out', '$sport','$dst','$to_port','$raw','$firewall','$extended')";
                        my $rows = $dbh->do($sql);
            $num++;
        }
    }
#Imprimo cantidad de reglas de dicho Filtro.
print $num."\n";

print "Cadena NAT por defecto: ",$ipt_obj_snat->chain_policy('nat', 'POSTROUTING'), "\n";
    @rules_snat = $ipt_obj_snat->chain_rules('nat', 'POSTROUTING');
$num = 1;
    for ($count = 0; $count < $num; $count++) {
        %xhash =%{$rules_snat[0][$count]};
        $proto = $xhash{protocol};
        $bytes = $xhash{bytes};
        $s_port = $xhash{s_port};
        $packets = $xhash{packets};
        $dport = $xhash{dport};
        $state = $xhash{state};
        $target = $xhash{target};
        $intf_in = $xhash{intf_in};
        $d_port = $xhash{d_port};
        $to_ip = $xhash{to_ip};
        $src = $xhash{src};
        $intf_out = $xhash{intf_out};
        $sport = $xhash{sport};
        $dst = $xhash{dst};
        $to_port = $xhash{to_port};
        $raw = $xhash{raw};
        $extended = $xhash{extended};
        chop($proto);
        if ($raw ne ""){
            #INSERTO REGLA EN BD 
            @datos = split(/\t/, $raw);
                        $sql = "INSERT INTO iptables(protocol, bytes, s_port, packets, dport, state, target, 
            intf_in, d_port, to_ip, src, intf_out, sport, dst, to_port, rawx,firewall,comentario)VALUES ('$proto', '$bytes', '$s_port', '$packets', '$dport', '$state', '$target', '$intf_in', '$d_port', '$to_ip', '$src', '$intf_out', '$sport','$dst','$to_port','$raw','$firewall','$extended')";
                        my $rows = $dbh->do($sql);
            $num++;
        }
    }
#Imprimo cantidad de reglas de dicho Filtro.
print $num."\n";

$dbh->disconnect();

CON EL NOMBRE Script_iptables_bd.pl

Como veran repetimos el ciclo 3 veces las mismas se realizan de esta manera porque
en IPTABLES existen tres tablas: FILTER, NAT Y MANGLE

- FILTER: En esta tabla hay tres cadenas INPUT, OUTPUT y FORWARD.
Adicionalmente, los target como ACCEPT y DROP son otra cosa
- NAT: En esta tabla hay tres cadenas PREROUTING, POSTROUTING, OUTPUT.
Adicionalmente, los target como SNAT y DNAT son otra cosa
- MANGLE: En esta tabla hay tres cadenas PREROUTING, INPUT, OUTPUT, FORWARD y
POSTROUTING.

Cada tabla de Iptables contiene información y se extrae cambiando el siguiente codigo

$ipt_obj->chain_rules($tabla, $cadena);

Ejemplo

$ipt_obj_forward->chain_policy('filter', 'FORWARD');

PASO 5

Una vez guardado el archivo...pues lo corremos.

de la siguiente manera:

#perl Script_iptables_bd.pl

El mismo va a imprimir algo como esto:

Cadena FORWARD por defecto: DROP
1698
Cadena INPUT por defecto: DROP
21
Cadena NAT por defecto: ACCEPT
30


Y listo lo ponemos en el crontab la siguiente linea:

0 7 * * * /home/usuario/perl Script_iptables_bd.pl

claro esta ponemos cada cuanto tiempo se ejecutara!!!

Y listo.

Eso es todo.


Más información:


http://cpan.uwinnipeg.ca/htdocs/IPTables-Parse/IPTables/Parse.html

lunes, 7 de noviembre de 2011

Backup de Postgres - Crontab - Linux

Siempre tenemos que saber como realizar un backup y que lo haga solito de una BD en postgres.

Así que estos son los pasos.

1_. Creamos un archivo .pgpass dentro de la raiz de root que contenga la siguiente linea:

localhost:puerto:mibasedatos:usuario:password

ejm:

10.xx.xx.xx:5432:BD_EJEMPLO:root:123456

2_. Creamos un archivo backup_bd dentro de la raiz de root que contenga la siguiente linea:

FECHA=$(date +%Y%m%d%H%M)
pg_dump -h localhost -p 5432 -U root -F c -b -v -f "/home/user/bd_$FECHA.backup" mibasededatos

3_. Y luego editamos el crontab

y le colocamos la siguiente linea según cada cuanto tiempo se debe ejecutar.(Leer sobre crontab)

#crontab -e
y editamos poniendo la siguiente linea. En mi caso todos los dias a las 7am.

0 7 * * * /root/backup_bd



Bueno espero que le sirva... Suerte...

miércoles, 31 de agosto de 2011

Reiniciar Postgres en Solaris 10

Buenas....

Para reiniciar desde la consola el servicio de Postgres

Lo hice de la siguiente manera ya que no conseguí una mejor forma....con ayuda de un compañero..

Revisamos que proceso tenemos arriba:

# svcs -a | grep postg

o tambien

# ps -ef|grep postg

y con el primero vemos la ruta a deshabilitar y lo colocamos:

# svcadm disable svc:/application/database/postgresql_83:default_32bit

Y volvemos a verificar si se deshabilito...

o simplemente matamos el proceso:

# ps -ef|grep postg
# pkill postgres

Y volvemos a habilitarlo:

# svcadm enable svc:/application/database/postgresql_83:default_32bit

Y verificamos:

# ps -ef|grep postg

eso es todo...





viernes, 3 de junio de 2011

Envio Sencillo de email con JAVA

Otra vez medio fastidiado asi que escribo un poco y hoy me gusto este caso para que el que lo necesite.

Bueno algo muy sencillo por si necesitan enviar correos a traves de java.

Para ello adicionamos las librerias necesarias:

mail.jar //La conseguimos en la siguiente direccion:

http://www.oracle.com/technetwork/java/index-138643.html

y la otra es:

jaf.jar

http://www.oracle.com/technetwork/java/jaf102-139581.html

Listo ahora agregamos los jar a nuestras librerías.

una vez hecho eso creamos un package llamado mail y creamos una clase con el nombre de Enviar correo.
luego agregamos el código a continuación y lo llamamos pasando los parámetros que nos pide..

A por cierto en el smtpHost podemos poner la ip de nuestro servidor de correo o su nombre....

Es muy sencillo!!! espero que les ayude..

/**
 *
 * @author icano
 */
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;

public class EnviarCorreo {
  public int EnviarCorreo (String remitente, String asunto, String destinatario,String cuerpo) {
      int status = 1;
      String from = remitente;
      String to = destinatario;
       // Se obtienen las propiedades del sistema y se establece el servidor SMTP
      String smtpHost = "10.xx.xx.xx"; //Direccion de nuestro servidor Tambien se puede poner correo.empresa.com
      Properties props = System.getProperties();
      props.put("mail.smtp.host",smtpHost);
      // Se obtiene una sesión con las propiedades anteriormente definidas
      Session sesion = Session.getDefaultInstance(props,null);
      // Capturar las excepciones
      try {
        // Se crea un mensaje vacío
        Message mensaje = new MimeMessage(sesion);
        // Se rellenan los atributos y el contenido
        // Asunto
        mensaje.setSubject(asunto);
        // Emisor del mensaje
         mensaje.setFrom(new InternetAddress(from));
         // Receptor del mensaje
         mensaje.addRecipient( Message.RecipientType.TO,new InternetAddress(to));
         // Cuerpo del mensaje
         mensaje.setText(cuerpo);
         // Se envía el mensaje
         Transport.send(mensaje);
      } catch (MessagingException e) {
         System.err.println(e.getMessage());
         status = 0;
      }
      return status;
  }
}

jueves, 31 de marzo de 2011

Autenticación LDAP con JAVA

Bueno esta vez me toco autenticar cualquier usuario contra el LDAP con JAVA.

Como cosa rara siempre uno se consigue la piedrita en el camino. La piedra era que la información que uno consigue en la web funcionaba chevere pero esta vez el ldap con el que se trabajaba posee un sin fin de ramificaciones y la BASE (dn) era diferente para cada grupo de usuarios pertenecientes a una unidad organizativa.

Así que bueno. Aquí les dejo el código que conseguí en la web con algunas modificaciones que permite buscar y autenticar un usuario (uid) contra el LDAP sin necesidad de alguna librería extra (.jar) y perteneciente a cualquier parte del arbol del LDAP.

Espero que les ayude.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package conexionldap;

/**
 *
 * @author icano
 */
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;

public class ValidarPassword {
public ValidarPassword(){
}
    private String url = "ldap://10.XX.XX.XX:389";
    private String contexto = "com.sun.jndi.ldap.LdapCtxFactory";
    private String tipoAuth = "simple";
    

public int validarLdap(String login, String password) {
 int valido = 0;
 Hashtable<String,String> env = new Hashtable<String,String>();
 //UID CONOCIDO Y BASE CONOCIDA PARA PODER CONECTARSE AL LDAP
 String username = "uid=uid_conocido,ou=Administradores,ou=Usuarios,ou=Cuentas,dc=xxx,dc=xxx";
 String password1 = "XXXXX";
 env.put(Context.INITIAL_CONTEXT_FACTORY, contexto);
 env.put(Context.SECURITY_AUTHENTICATION, tipoAuth);
 env.put(Context.SECURITY_PRINCIPAL, username);
 env.put(Context.SECURITY_CREDENTIALS, password1);
 env.put(Context.PROVIDER_URL, url);
 try {
  //CONEXION CON EL LDAP
  DirContext ctx = new InitialLdapContext(env, null);
  SearchControls searchCtls = new SearchControls();
  //ITEMS A TRAER EN EL CASO QUE LO NECESITEMOS
  String returnedAtts[] = { "uid","sn","givenName","mail"};
  searchCtls.setReturningAttributes(returnedAtts);
  searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
  String searchFilter = "(uid="+login.toLowerCase()+")";
  String searchBase = "ou=Usuarios,ou=Cuentas,dc=xxx,dc=xxx";
  NamingEnumeration<SearchResult> results = ctx.search(searchBase, searchFilter, searchCtls);
  while (results.hasMoreElements()) {
   SearchResult searchResult = (SearchResult) results.next();
   Attributes attrs = searchResult.getAttributes();
   //OPTENEMOS LA UNIDAD ORGANIZATIVA DEL UID BUSCADO CON SU UID Y LO COMPLETAMOS CON LA BASE
   String dn = searchResult.getName()+","+searchBase;
   if (attrs != null)
   {
       //EL UID EXISTE AHORA VALIDAR PASSWORD
       valido = validarAuth(dn,password); 
       //SI VALIDO ES "0" PASSWORD INCORRECTO, SI ES "1" PASSWORD CORRECTO
   }
  }
  ctx.close();
 } catch (NamingException e) {
  e.printStackTrace();
 }
//RETORNAMOS EL VALOR A QUIEN LO LLAMO SIENDO POR DEFECTO "0" EN EL CASO DE QUE EL UID NO EXISTA O PASSWORD INVALIDO
 return valido; 
}
private int validarAuth(String dn,String password){
    int valido = 0;
    Hashtable<String,String> env1 = new Hashtable<String,String>();
    env1.put(Context.INITIAL_CONTEXT_FACTORY, contexto);
    env1.put(Context.SECURITY_AUTHENTICATION, tipoAuth);
    env1.put(Context.SECURITY_PRINCIPAL, dn);
    env1.put(Context.SECURITY_CREDENTIALS, password);
    env1.put(Context.PROVIDER_URL, url);
    try {
        DirContext ctx1 = new InitialLdapContext(env1, null);
        valido = 1;
        ctx1.close();
    } catch (NamingException e) {
        e.printStackTrace();
    }
    return valido;
}
}

lunes, 23 de agosto de 2010

Como capturar Mac Address de Cliente

Bueno señores escribo del tema porque como cosa rara al principio me parecio algo sencillo pero cuando lo comence hacer no fue así.

Para capturar la Mac Address de los clientes que visitan tu aplicación lo hice con JAVA.

Hay que tomar en cuenta que la Mac no viaja por ninguno de los protocolos de la red,  como TCP/IP.  Y tampoco se encuentra en la cabecera de la información que viaja por tu pagina Web.

Entonces como capturamos la Mac Address del cliente que nos visita???

En la red hay mucha información tal es el caso de algunas paginas como esta:

http://www.kodejava.org/examples/250.html

o esta

http://www.easywayserver.com/forum/viewtopic.php?t=1241

Pero a mi ninguna me sirvio

Las opciones de esos link los probe pero solo funcionan para obtener la mac address del servidor donde se aloja el contenedor de nuestra aplicación más no la del cliente.

Tambien existe otra forma que es con ActiveX Control pero solo funciona con IE y el cliente tendria que habilitar opciones que violan niveles de seguridad  en su navegador. Y como solo funcionaba con IE y mis clientes son de 80% software libre esa opción no es un camino.

Bueno la solución la consegui.... la mac address se encuentra en la capa 2 del modelo OSI y no la podemos leer tan facilmente del cliente y mucho menos sin autorización.

Los pasos resumidamente son:
Paso 1:
El cliente debe tener instalado un plugin de Java (JRE) Este debe ser JRE 6u20 si es otra versión no se garantiza que funcione.
Y se puede verificar aquí:

http://www.java.com/es/download/installed.jsp

Y nuestra pagina debe verificar si lo tiene instalado.

Se puede hacer con el siguiente codigo Javacript:

var L = navigator.plugins.length;
var exis = 0;
for(var i=0; i<L; i++) {   
switch(navigator.plugins[i].name)
{
    case "Java(TM) Platform SE 6 U20": //Para SO basados en Windows
        exis = 1;
    break;
    case "Java(TM) Plug-in 1.6.0_20":  //Para SO basados en Debian
        exis = 1;
    break;
    case "IcedTea NPR Web Browser Plugin (using IcedTea6 1.7.3(suse-2.1.1i386))": //Para SO basados en Slackware
        exis = 1;
    break;
    case "IcedTea Java Web Browser Plugin": //Para SO basados en Red Had
        exis = 1;
    break;
}
}

Si exis es igual a 0 el cliente no tiene instalado el plugin, si es 1 el cliente lo tiene instalado.

Paso 2:

Descargue el siguiente archivo que contiene los ejemplos y el codigo fuente:

http://www.softwaresamurai.com/Agwego/mac/macaddressapplet-1.0.tar.gz 

Una vez descargados los descomprimen sea cual sea el caso en linux o windows busque como descomprimirlos.

Paso 3:
Luego adapte mi aplicación a lo que descargue.

colocando el siguiente codigo en el body

<embed type="application/x-java-applet"
           name="macaddressapplet"
           width="0"
           height="0"
           code="MacAddressApplet"
           archive="macaddressapplet.jar"
           pluginspage="http://java.sun.com/javase/downloads/index.jsp"
           style="position:absolute; top:-1000px; left:-1000px;">
        <noembed>
            <object classid="clsid:CAFEEFAC-0016-0000-FFFF-ABCDEFFEDCBA"
                    type="application/x-java-applet"
                    name="macaddressapplet"
                    style="position:absolute; top:-1000px; left:-1000px;">
                <param name="code" value="MacAddressApplet"/>
                <param name="archive" value="macaddressapplet.jar" />
                <param name="mayscript" value="true"/>
                <param name="scriptable" value="true"/>
                <param name="width" value="0"/>
                <param name="height" value="0"/>
              </object>
        </noembed>
    </embed>

<script type="text/javascript">
        function getMacAddressesJSON1()
            {
                document.macaddressapplet.setSep( ":" );
                document.macaddressapplet.setFormat( "%02x" );
                var macs = eval( String( document.macaddressapplet.getMacAddressesJSON() ) );
                var mac_string = "";
                for( var idx = 0; idx < macs.length; idx ++ )
                    mac_string += "\t" + macs[ idx ] + "\n ";
                document.getElementById("txtMACAdress").value = mac_string;               
            }
      
       </script>

Las primeras lineas son para importar las librerias necesarias para el uso de las funciones que descargamos.


Y las ultimas llama a la función getMacAddressesJSON1 me trae las mac address del cliente incluyendo mac de maquinas virtuales que pudiera tener el cliente. Guardando los datos en un input de tipo texto "tXtMACAdress"


Y guala con el dato en un input puedo utilizarlo para lo que se desee...

Cualquier pregunta escribame y con gusto los ayudaré...


Espero sus comentarios a ver si me motivo a escribir de diferentes temas tecnológicos...