jueves, 25 de noviembre de 2010

Balanceo con mod_proxy_balancer

Una opción de balanceo de carga que nos ofrece apache a partir de la versión 2.1 es mod_proxy_balancer. Hoy he realizado una pequeña configuración para balancear una aplicación que correo sobre dos tomcat. Básicamente la configuración consiste en lo siguiente (esto lo configuro dentro de un virtual):


<VirtualHost *:80>

ServerName prueba.dominio.es

ErrorLog logs/error.log

CustomLog logs/access.log common

RewriteEngine On



ProxyPreserveHost on

<Proxy balancer://cluster>

BalancerMember http://tomcat1:8080 loadfactor=1 route=clustnode1

BalancerMember http://tomcat2:8080 loadfactor=1 route=clustnode2

Order Deny,Allow

Allow from all

</Proxy>



<Location /aplicacion>

ProxyPass balancer://cluster/aplicacion stickysession=JSESSIONID

ProxyPassReverse balancer://cluster/aplicacion

Order Deny,Allow

Allow from all

</Location>



<Location /balancer-manager>

SetHandler balancer-manager

Order Deny,Allow

Allow from all

</Location>


</VirtualHost>

Por partes:


ProxyPreserveHost on

<Proxy balancer://cluster>

BalancerMember http://tomcat1:8080 loadfactor=1 route=clustnode1

BalancerMember http://tomcat2:8080 loadfactor=1 route=clustnode2

Order Deny,Allow

Allow from all

</Proxy>


Se define el balanceo (miembros, factor de carga, ruta, ...). Importante poner "ProxyPreserveHost on", porque si no se pone, al quitar una máquina del balanceo, si estabas en ella, cuando intentes acceder otra vez te redirige a la otra máquina, pero con la ip en vez de la url. También debes definir en route el valor que tengas puesto en cada uno de los jvmRoute (en server.xml) de los tomcat:


<Engine name="Catalina" defaultHost="localhost" jvmRoute="clustnode1">



<Location /aplicacion>

ProxyPass balancer://cluster/aplicacion stickysession=JSESSIONID

ProxyPassReverse balancer://cluster/aplicacion

Order Deny,Allow

Allow from all

</Location>


Aquí ya hacemos el proxy, simplemente le decimos que las peticiones para /aplicacion lo mande al cluster. Importante definir stickysession para que te mande siempre al mismo nodo.

El /balancer-manager no es mas que para administrar vía web el balanceo....

miércoles, 24 de noviembre de 2010

Exámenes LPIC

Buenas, para aquellos que estén interesados, para marzo del año que viene se realizan los exámenes del LPIC en la ETSII de Sevilla. Aquí tenéis el enlace:

http://www.concursosoftwarelibre.org/1011/certificado-lpi

Nos vemos allí ;)

Manipular pdf's desde la línea de comandos

Si necesitas extraer páginas de un pdf, unir varios pdf en uno, obtener metadatos ... una forma muy fácil y efectiva de hacerlo en con pdftk.

En el siguiente post viene muy bien expliado:

http://danubuntu.wordpress.com/2008/04/05/manipular-archivos-pdf-con-pdftk/

Ejemplo: queremos extraer las páginas 25 a 36 de un archivo PDF

$ pdftk A=documento1.pdf cat A25-36 output documento_nuevo_pag_25_a_36.pdf

Ejemplo: obtener informe con los metadatos de un pdf
$ pdftk documento.pdf dump_data output informe.txt


lunes, 22 de noviembre de 2010

Contar número de documentos en un espacio de Alfresco

Siguiendo la mísma línea que en el script para dar permisos a un espacio copiado en alfresco, podemos recorrer un espacio de forma recursiva para obtener otros datos que nos pueden ser muy útiles. En este caso, obtenemos el número de documentos que contiene el espacio y el peso de este:

//Crea log en el espacio personal de quien se loga.
var logFile = userhome.childByNamePath("recorre.log");
if (logFile == null)
{
logFile = userhome.createFile("recorre.log");
}
logFile.content ="";
var log = "";



//Funcion que cuenta los docuementos y obtiene el peso de un espacio de forma recursiva.
function cuenta(doc)
{
for each (n in doc.children)
{
if (n.isContainer)
{
cuenta(n);
}
else
{
total += 1;
peso += n.size;
}
}
}

//Comienza main.
var total = 0;
var peso = 0;
cuenta(space);
log += "El total de documentos del espacio " + space.name + "es: " + total + "\n";
log += "El tamaño del espacio es: " + space.name + "es: " + peso/1024/1024 + " MB\n";
logFile.content += log;
//FIN

Este script lo debemos ejecutar como una acción sobre el espacio que queramos consultar.

Hacemos la división para obtener el valor en MB.

domingo, 21 de noviembre de 2010

Screen para no perder sesiones...

Ya me ha pasado más de una vez que mientras ejecuto algún trabajo a través de ssh, por algún motivo he perdido la conexión y también lo que estaba haciendo en el servidor sobre el que trabajaba.

Para evitar estas situaciones podemos hacer uso de screen. screen es un manejador de sesiones que nos permite tener en segundo plano la ejecución de un programa. No sólo sirve para trabajar sobre ssh, también lo podemos usar en local.

Su uso es muy sencillo. Una vez conectados, simplemente tenemos que ejecutar:

rafa@rafa-laptop:~$ screen

A partir de ahora todo lo que ejecutemos estará asociado a este "screen".

Si la conexión se cierra, podemos recuperar lo que teníamos en ese screen con:

rafa@rafa-laptop:~$ screen -rx

Y aparecerá la ejecución que teníamos.

screen admite muchas más opciones, como por ejemplo:

  • Si queremos dejar un screen abierto ejecutando algún comando, pulsaremos: ^a d (CTRL+A D).
  • Para abrir una nueva ventana: ^a c (CTRL+A C).
para más info, ya sabéis: man screen

sábado, 20 de noviembre de 2010

Añadir nuevas versiones de java a alternatives

Muchas veces necesitamos trabajar con distintas versiones de java. Podemos tener instaladas todas las versiones que queramos y utilizar en cada momento la que nos convenga.

Para instalar una nueva versión haríamos lo siguiente:
  • Descargas el .bin de la versión de java que queramos, le das permisos de ejecución y lo ejecutas.
  • Una vez aceptadas las condiciones, se habrá creado una carpeta con el nombre de la versión. Mueves la carpeta a /usr/lib/jvm/.
  • Ahora lo añadimos a alternatives:

update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/version_que_sea/bin/java" 1


Para usar esta versión tan sólo tenemos que indicar lo siguiente:

update-alternatives --set java /usr/lib/jvm/version_que_sea/bin/java

Y listo. También podemos ver las distintas versiones que tenemos:

update-alternatives --list java

En mi caso, la salida sería la siguiente:



jueves, 18 de noviembre de 2010

Mantener los permisos al copiar un espacio en Alfresco 3.2r

Buenas, supongo que más de uno se habrá encontrado con este bug de alfresco: http://issues.alfresco.com/jira/browse/ALF-2638

La cosa es que al copiar un espacio, se copia correctamente su contenido, pero no mantiene los permisos que tenga aplicados (lo cual es un verdadero problema cuando se trata de espacios con una estructura compleja y muchos grupos).

Como de momento parece que no hay solución para este bug (si existe, por favor que me lo indiquen ;) ), he confeccionado un js para que una vez se ha hecho la copia de un espacio, se apliquen los permisos. El proceso sería: copiar y pegar el espacio, renombrarlo por "NombreDeEspacioOriginal"_COPIA (es decir, el nombre original con el sufijo _COPIA) y aplicarle una acción para que ejecute el script.

   //Obtiene el path del espacio _COPIA y genera el path del origen.
var ruta_destino = (space.displayPath + "/" + space.name).replace("/Empresa/","");
var ruta_origen = ruta_destino.replace("_COPIA","");
//Crea log en el espacio personal de quien se loga.
var logFile = userhome.childByNamePath("recorre.log");
if (logFile == null)
{
logFile = userhome.createFile("recorre.log");
}
logFile.content ="";
var log = "";
//Funcion que recorre un espacio para copiar sus permisos sobre otro espacio copia.
function recorre(doc)
{
for each (n in doc.children)
{
if (n.isContainer)
{
//Compongo path origen
cadena_origen = n.displayPath + "/" + n.name;
//Compongno path destino
var replace_1 = "/Empresa/" + ruta_origen + "/";
var replace_2 = ruta_destino + "/";
cadena_destino = cadena_origen.replace(replace_1, replace_2);
//Compongo ScriptNode destino
var espacio_fin = companyhome.childByNamePath(cadena_destino);
log += n.name + " es un subespacio de " + n.parent.name + ".\n";
if (n.inheritsPermissions())
{
log += n.name + " hereda permisos." + "\n";
espacio_fin.setInheritsPermissions(true);
}
var cadena = n.getPermissions();
for each (k in cadena)
{
var permisos = k.split(';');
log += "Grupo: " + permisos[1] + "\n";
log += "Permiso: " + permisos[2] + "\n";
espacio_fin.setPermission(permisos[2],permisos[1]);
}
recorre (n);
}
}
}
//Funcion que quita los permisos otorgados nada mas copiar.
function quita_permisos(doc)
{
for each (n in doc.children)
{
if (n.isContainer)
{
if (n.inheritsPermissions())
{
n.setInheritsPermissions(false);
}
var cadena = n.getPermissions();
for each (k in cadena)
{
var permisos = k.split(';');
log += "Grupo: " + permisos[1] + "\n";
log += "Permiso: " + permisos[2] + "\n";
n.removePermission(permisos[2],permisos[1]);
}
quita_permisos (n);
}
}
}
//Comienza main. El espacio sobre el que se invoque debe tener el sufijo "_COPIA"
var pos = ruta_destino.lastIndexOf("_COPIA");
if (pos > 0)
{
//Se obtien los ScriptNode a partir de la ruta de los espacios.
var espacio_origen = companyhome.childByNamePath(ruta_origen);
var espacio_destino = companyhome.childByNamePath(ruta_destino);
//Primero quitamos los permisos del copiado.
quita_permisos(espacio_destino);
//Recorremos el espacio origen para dar los permisos al destino.
recorre(espacio_origen);
//Se aplican los permisos al espacio padre destino.
log += espacio_origen.name + " es el espacio padre. \n";
if (espacio_origen.inheritsPermissions())
{
espacio_destino.setInheritsPermissions(true);
}
var cadena_permisos = espacio_origen.getPermissions();
for each (k in cadena_permisos)
{
var permisos_origen = k.split(';');
log += "Grupo: " + permisos_origen[1] + "\n";
log += "Permiso: " + permisos_origen[2] + "\n";
espacio_destino.setPermission(permisos_origen[2],permisos_origen[1]);
}
}
else
{
log += "El espacio no tiene sufijo _COPIA \n";
}
logFile.content += log;
//FIN

Para quien no conozca la api de alfresco 3.2: http://wiki.alfresco.com/wiki/3.2_JavaScript_API

Lo que hace es recorrer el espacio original recursivamente para obtener los permisos y si tiene o no herencia para aplicarlos sobre el espacio donde se ejecuta el script. Antes se deben quitar los permisos aplicados al copiar y posteriormente hacer lo mismo sobre el espacio padre (ya que no se contempla en la recursión).

Si el espacio no lleva el sufijo _COPIA no hará nada.

También se mantiene un log en el espacio home de quien lo lance.

Espero que os sea útil.

Un saludo.


CORRECCIÓN:
Buenas, mando una corrección a este script. Había un par de cosas que se me pasaron. Una, que sólo activaba la herencia si el original la tenía, pero no la desactivaba en caso de no tenerla (y por defecto la activa). Dos, a la hora de añadir los permisos, si el espacio heredaba, añadía todos los permiso heredados, lo cual no debería hacer (aunque el resultado en la práctica será lo mismo, ya que los estaba heredando). Se observa que si no tiene herencia, los permisos los copia de forma adecuada. Por tanto lo que hago es desactivar temporalmente la herencia en el original para hacer la copia.

Gracias Jose Luis por haberte dado cuenta y por avisarme....

//Obtiene el path del espacio _COPIA y genera el path del origen.

var ruta_destino = (space.displayPath + "/" + space.name).replace("/Empresa/","");

var ruta_origen = ruta_destino.replace("_COPIA","");



//Crea log en el espacio personal de quien se loga.

var logFile = userhome.childByNamePath("recorre.log");

if (logFile == null)

{

logFile = userhome.createFile("recorre.log");

}

logFile.content ="";

var log = "";



//Funcion que recorre un espacio para copiar sus permisos sobre otro espacio copia.

function recorre(doc)

{

for each (n in doc.children)

{

if (n.isContainer)

{

//Compongo path origen

cadena_origen = n.displayPath + "/" + n.name;

//Compongno path destino

var replace_1 = "/Empresa/" + ruta_origen + "/";

var replace_2 = ruta_destino + "/";

cadena_destino = cadena_origen.replace(replace_1, replace_2);

//Compongo ScriptNode destino

var espacio_fin = companyhome.childByNamePath(cadena_destino);



log += n.name + " es un subespacio de " + n.parent.name + ".\n";

if (n.inheritsPermissions())

{

log += n.name + " hereda permisos." + "\n";

var hereda = true;

n.setInheritsPermissions(false);

} else

{

log += n.name + " no hereda permisos." + "\n";

var hereda = false;

}

var cadena = n.getPermissions();

for each (k in cadena)

{

var permisos = k.split(';');

log += "Grupo: " + permisos[1] + "\n";

log += "Permiso: " + permisos[2] + "\n";

espacio_fin.setPermission(permisos[2],permisos[1]);

}

espacio_fin.setInheritsPermissions(hereda);

n.setInheritsPermissions(hereda);

recorre (n);

}

}

}



//Funcion que quita los permisos otorgados nada mas copiar.

function quita_permisos(doc)

{

for each (n in doc.children)

{

if (n.isContainer)

{

if (n.inheritsPermissions())

{

n.setInheritsPermissions(false);

}



var cadena = n.getPermissions();

for each (k in cadena)

{

var permisos = k.split(';');

log += "Grupo: " + permisos[1] + "\n";

log += "Permiso: " + permisos[2] + "\n";

n.removePermission(permisos[2],permisos[1]);

}

quita_permisos (n);

}

}

}



//Comienza main. El espacio sobre el que se invoque debe tener el sufijo "_COPIA"

var pos = ruta_destino.lastIndexOf("_COPIA");

if (pos > 0)

{

//Se obtien los ScriptNode a partir de la ruta de los espacios.

var espacio_origen = companyhome.childByNamePath(ruta_origen);

var espacio_destino = companyhome.childByNamePath(ruta_destino);



//Primero quitamos los permisos del copiado.

quita_permisos(espacio_destino);

//Recorremos el espacio origen para dar los permisos al destino.

recorre(espacio_origen);

//Se aplican los permisos al espacio padre destino.

log += espacio_origen.name + " es el espacio padre. \n";

if (espacio_origen.inheritsPermissions())

{

var hereda = true;

espacio_origen.setInheritsPermissions(false);

} else

{

var hereda = false;

}

var cadena_permisos = espacio_origen.getPermissions();

for each (k in cadena_permisos)

{

var permisos_origen = k.split(';');

log += "Grupo: " + permisos_origen[1] + "\n";

log += "Permiso: " + permisos_origen[2] + "\n";

espacio_destino.setPermission(permisos_origen[2],permisos_origen[1]);

}

espacio_origen.setInheritsPermissions(hereda);

espacio_destino.setInheritsPermissions(hereda);

}

else

{

log += "El espacio no tiene sufijo _COPIA \n";

}



logFile.content += log;

//FIN

Obtener informacion de repositorios a través de los metadatos .git publicados por error

 A raiz de CTF realizado recientemente, me ha parecido interesante publicar este post sobre los errores de seguridad que se encuentran en mu...