martes, 26 de mayo de 2009

Nuevo animalito - HTC MAGIC

Weno hace un par de horas me han traído mi nuevo teléfono, y es que la operadora ha tenido a bien ofrecerme el terminal que me interesaba.

Ahora solo falta ir dándole vueltas para ver que se le puede sacar al "bicho".

A ver si cumple con lo que se espera de el. ;)










......... De momento pinta bien la cosa ;))




De más está comentar que ahora estoy como un "xiquillete" con juguete nuevo ;)

lunes, 18 de mayo de 2009

SSL - "Sin" y "Con" certificado. Renegociando la conexión

Hace ya un par de meses, por requisitos de una aplcación, me vi en la tesitura de configurar
apache para poder ofrecer una parte de los contenidos de una web por ssl sin certificado
de cliente y el resto mediante ssl pero con certificado de cliente.

Al final todo quedo en nada ya que la primera parte del contenido se acabo ofreciendo
sin ssl, pero como suele ocurrir en estos casos, el trabajo ya estaba hecho ;) así que ahí
van los resultados.

El problema con el que me encrontre es que la directiva "SSLVerifyClient" encargada de
solicitar el certificado al cliente, es aplicable y cito textualmente de la página de
apache a... ("server config, virtual host, directory, .htaccess")

Esto evidentemente te lleva a pensar en una solución por ejemplo, de este tipo:


VirtualHost..........
.....
"<"locationmatch sitio="">
SSLVerifyClient none
"<"/locationmatch>

"<"locationmatch sitio="">
SSLVerifyClient require
"<"/locationmatch>
......




Donde para el patron "/sitio/" solicitamos el certificado del cliente y para el resto no.

Hay que decir, que probamos "mil" conbinaciones más, que no vienen al caso con valores
optional para la directiva SSLVerifyClient.

El proble es que si bien esta directiva es aplicable, lo que no indican es que la
renegociación de certificados no funciona correctamente en mod_ssl. Me explico.......

En el saludo inicial de la conexión, ya sea porque esta definido a nivel del servidor o a
nivel del VirtualHost, apache solicita o no el certificado, pero luego es incapaz de
renegociar esa conexión, para cambiar y usar o dejar de usar este certificado.
Con lo que una vez solicitado o no, esto ya no varia para la conexión.

(He leido referencias a un bug de mod_ssl, aunque no se si es cierto o si simplemente
no esta contemplado en la implementación)

Por este motivo y tras abrir el pertinente caso de soporte (Donde tanto yo como los distintos
técnicos de soporte de los niveles por donde paso la incidencia), decidimos que la
opción viable en este caso era forzar el establecimiento de una conexión nueva en cada caso.

(Es decir dos VH distintos con dos puertos distintos;))

Esto se tradujo en algo de este tipo:

#En este primer VH cuando encontramos el patron para el que no queremos solicitar certificado
#saltamos directamente al destino.
#Cuando encontramos el patron para el que si queremos solicitar certificado, reescrivimos la url
#para saltar al segundo VH



"<"virtualhost xx.xx.xx.xx:443>
DocumentRoot /../sitio1
ServerName sitio1.es
DirectoryIndex index.html index.htm index.php
Options None
AllowCONNECT 443 444

"<"ifmodule>
RewriteEngine On
RewriteRule ^/$ /paso1/ [R,NE]
"<"/ifmodule>

"<"directory>
Order deny,allow
Allow from all
"<"/directory>

ProxyRequests Off
ProxyVia On
ProxyPreserveHost On

SSLVerifyDepth 10
ProxyPass /paso1/ https://maquina_destino:443/paso1/
ProxyPassReverse /paso1/ https://maquina_destino:443/paso1/

RewriteRule /paso2/ https://sitio2.es:444/paso2/

SSLEngine on
SSLVerifyClient none
SSLProxyEngine on

......

"<"/virtualhost>


#########################################

#En el segundo VH cuando encontramos el patron que nos indica que queremos certificado de cliente
#que es el que nos ha traido a este VH, saltamos al destino.

"<"virtualhost 444>
DocumentRoot /../sitio2
ServerName sitio2.es
ErrorLog logs/sitio2_ssl-error-log
TransferLog logs/sitio2_ssl_access_log
LogLevel warn
DirectoryIndex index.html index.htm index.php
Options None
AllowCONNECT 443 444

"<"ifmodule>
RewriteEngine On
RewriteRule ^/$ /sitio2/ [R,NE]
"<"/ifmodule>

"<"directory>
Order deny,allow
Allow from all
"<"/directory>

ProxyRequests Off
ProxyVia On
ProxyPreserveHost On

SSLVerifyDepth 10
ProxyPass /sitio2/ https://maquina_destino:443/sitio2/
ProxyPassReverse /sitio2/ https://maquina_destino:443/sitio2/

SSLEngine on
SSLVerifyClient require
SSLProxyEngine on

.....

"<"/virtualhost>



Al final tras todas las pruebas realizadas, decidimos que esta era la opción más adecuada para
solucionar el problema.
No se si será la opción más "limpia" pero se ajustaba perfectamente al problema que queria
resolver. ;)

lunes, 20 de abril de 2009

Centralizando Tareas - Cron

He estado dándole vueltas a la idea de centralizar las tareas programadas, ya que el número de máquinas aumenta de manera casi exponencial y al final esto se hace imposible de administrar.

He probado varias, aplicaciones para este propósito y la conclusión final es que me aportan más trabajo que beneficio, ya que todas ellas gestionan mas cosas de las que necesito y su puesta en marcha y curva de aprendizaje es demasiado costosa.

Por este motivo me he decidido a centralizarlo del modo mas simple, pero que se ajusta a mis propósitos.
Desde el propio cron con conexiones SSH, de este modo, puedo administrar o ver en que máquina se ejecuta que, y por quien, de un simple vistazo a su cron.

La idea es la siguiente, una máquina, hará la función de "maestro" y las demás serán "esclavas" de esta, de este modo solo habrá que revisar y actualizar el cron de la máquina "maestro", ya que esta lanzará mediante ssh con claves publicas /privadas, los scripts que se ejecutaran en las demas máquinas.

1.- Garantizar el acceso mediante ssh.
Hay que garantizar el acceso por ssh de la máquina maestro a las demás, para cada usuario. Esto esta explicado en un post anterior. Aquí

2.- Editar el cron de la máquina "maestro"

El cron queda de la manera siguiente:

###Maquina Pruebas 1


#user1


31 14 * * * /usr/bin/ssh user1@192.168.1.143 '/etc/local/script_pru1'


#Root


35 14 * * * /usr/bin/ssh root@192.168.1.143 '/etc/local/script_pru2'



Desglosamos mediante comentarios, la máquina "esclavo" afectada y para que usuario (Simplemente a nivel organizativo).
Tras esto editamos la linea de cron propiamente dicha, en la que definimos los patrones de tiempo que correspondan, y lanzamos el cliente ssh de nuestra máquina "maestro" con usuario y host destino ("esclavo"), y con ('') definimos el script remoto que vamos a ejecutar.




Desventaja - 1

Es evidente pensar que depender de una única máquina para gestionar las tareas programadas es un inconveniente, ya que tenemos un cuello de botella, en cuanto a alta disponivilidad se refiere.

Solución.

Una posible solución es esta:
Montando un cluster RH, podemos definir un servicio adicional "cron", el cual al bascular entre nodos, migre el demonio "crond" y ejecute un script que monte un directorio en almacenamiento compartido en /var/spool/cron, de este modo tendremos dos maquinas operativas para servir de gestor de crons. El orden seria , primero el montaje del directorio y luego levantar el servicio crond. Este proceso se puede realizar siguiendo el siguiente post. Aquí

Desventaja - 2

Otro problema es el coste de trabajo, que supone habilitar el acceso por ssh de la máquina "maestro" a las demas "esclavos"
Este problema no es "solucionable" pero el beneficio obtenido de centralizar los procesos es evidente ya que el tiempo invertido será recuperado con creces al aumentar la simplicidad de administración

miércoles, 8 de abril de 2009

REXEC sobre Centos4

Bueno aunque se que esto no es lo más recomendable por motivos evidentes de seguridad, en ocasiones nos encontramos con la necesidad de montar servicios "R" por especificaciones de fabricantes.
Aquí intento comentar un modo de hacerlo e intentar que sea un poco más seguro.

Instalacion de "rexecd"

Rexec forma parte de los servicios ofrecidos a través de "rsh-server"
yum install rsh-server.i386

Editar el fichero de configuración de Rexec

vi /etc/xinetd.d/rexec

En el cambiamos la opción de disable a "no", para habilitar el servicio bajo xinetd

# default: off

# description:

# Rexecd is the server for the rexec program. The server provides remote

# execution facilities with authentication based on user names and

# passwords.

service exec

{

socket_type = stream

wait = no

user = root

log_on_success += USERID

log_on_failure += USERID

server = /usr/sbin/in.rexecd

disable = "no"

}



una vez hecho esto, para permitir el uso a root debemos modificar el fichero
/etc/securetty

Y añadir al final la aplicación que queremos permitir en este caso, rexec

......

......

......

rexec


Tras esto rebotamos el servicio de xinetd y listo, el rexec con todos sus "problemas de seguridad" está operativo.

Para intentar securizar el servicio dentro de lo posible, podríamos entre otras cosas, implementar algo bajo iptables como lo que sigue.

#!/bin/bash

#

#Borramos todas las reglas existentes, comenzamos en un estado limpio

#

iptables -F

#

# Politicas por defecto INPUT, FORWARD y OUTPUT

#

iptables -P INPUT ACCEPT

iptables -P FORWARD ACCEPT

iptables -P OUTPUT ACCEPT

#

#Permitimos rexec desde la maquina autorizada

iptables -A INPUT -p tcp -s x.x.x.x/24 --dport 512 -i eth0 -j ACCEPT

#

#Denegamos el resto de accesos rexec para todas las maquinas

#

iptables -A INPUT -p tcp --dport 512 -i eth0 -j DROP

#

#Salvamos las politicas

#

/sbin/service iptables save

#

#Listamos las reglas cargadas

#

iptables -L -v



Solo me queda recomendar encarecidamente no usar este tipo de servicios a menos que no sea estrictamente necesario.

sábado, 4 de abril de 2009

HTTP - URL's "escapadas" - Alternativas

Este post es una nota mental para no olvidar algunas de las alternativas que he encontrado para evitar el problema de las URL's escapadas en Apache.
Este problema se produce cuando la URL recibida contiene caracteres especiales, que son interpretados y cambiados por su código ASCII, al realizar un "RewriteRule" la lista la podemos consultar por ejemplo en:


http://www.w3schools.com/TAGS/ref_urlencode.asp

Alternativa1
La primera alternativa para este problema, nos la proporciona el mismo "mod_rewrite", y es su flag [NE], el cual evita que estos caracteres sean "escapados"

Ejem.

RewriteRule /ejemplo/(.*) http://www.XXX.es/ejemplo2/$1 [NE]

En este ejemplo cualquier cosa que tenga un patrón de URL que comience por "/ejemplo" será traducido a "http://www.XXX.es/ejemplo2", pasando la ultima parte de la URL contenida en (.*) a la variable "$1"

El problema que presenta esta solución es que este flag está disponible desde la versión 1.3.20 de Apache y en maquinas muy antiguas esto es un inconveniente.

Alternativa2
La segunda alternativa, también es propia de "mod_rewrite", solo que está disponible desde mediados de la versión 1.2 y para todas las versiones 1.3.X y 2.X
La directiva "RewriteMap", es la que nos proporciona esta solución. Esta directiva tiene cuatro funciones internas, las cuales nos permiten saltar entre mayúsculas y minúsculas y escapes o unescapes, las URL's

Ejem.

RewriteMap fescape int:escape RewriteMap funescape int:unescape RewriteRule /ejemplo/(.*) http://www.XXX/ejemplo2/${escape:{unescape:$1}} [R]

ó

RewriteRule /ejemplo/(.*) http://www.XXX/ejemplo2/${unescape:$1} [R]

En este ejemplo, definimos las funciones "fescape" y "funescape" como funciones internas de escape y unescape, de "RewriteMap". Posteriormente, aplicamos estas funciones a nuestra variable "$1", dentro del "RewriteRule". Se pueden aplicar en el orden que se necesite, como se ve en las dos lineas de RewriteRule anteriores.

El problema de esta solución, es que según Apache, estas funciones son aplicadas a la URI, nunca a la sentencia de Query String, posterior a un "?"

Ejem. http://www.XXX.es/XXX?="QueryString"
Nota: Las comillas de este ejemplo no se verían afectadas.


Alternativa3
La siguiente alternativa, pasa por crear un pequeño script que nos genere la URL correcta, sin que esta sea "escapada"
Para este propósito basta con una directiva que apunte a nuestro script:

ScriptAlias /ejemplo /path/script_url

En nuestro script usaremos las variables:

PATH_INFO: Contiene la URI que recibe Apache antes de ser escapada QUERY_STRING: Contiene la Query String que recibe Apache antes de ser escapada

En perl:
my $url = "http://www.XXX.es"$ENV{PATH_INFO}."?".$ENV{QUERY_STRING};

Tras esto construimos una página mediante prints, con un meta que contenga como url la que hemos construido. Este Post es simplemente para ver que existen distintas formas para este proceso, y que cada una de ellas tienes sus diferencias, es cuestión de elegir ;)