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;
}
}