miércoles, 27 de febrero de 2008

STUNNEL

INTRODUCCION


Stunnel es un programa muy útil que nos permite utilizar conexiones SSL con clientes y/o servidores que no soportan este protocolo. Algunos ejemplos de uso son:

Utilizar el modo de conexión SSL entre un cliente que tenga esa opción y un servidor POP o IMAP que no.
Utilizar el modo de conexión SSL entre un Servidor que tenga esa opción y un cliente POP o IMAP que no.
Encriptar cualquier conexión TCP entre dos ordenadores, permitiendo opcionalmente el control de acceso al servidor desde determinados clientes.

SINTESIS

Stunnel debe ejecutarse en el extremo de la conexión donde se quiera tener la funcionalidad SSL que de otra forma no se tiene. Así, en el primero de los ejemplos anteriores, habría que ejecutarlo en el servidor POP/IMAP. En el caso de IMAP la orden sería:

stunnel -d 993 -r 143

La opción -d indica en qué puerto debe escuchar. En este caso, puesto que hemos supuesto que el cliente soporta IMAP sobre SSL, el puerto debe ser 993, que es el asignado para ello (IMAPS). La opción -r indica a qué host y puerto debe redirigir la conexión (ésta última ya no es SSL). Si no se indica host se conecta a sí mismo. En este ejemplo es el puerto habitual de IMAP.

Otra forma de hacerlo es:

stunnel -d 993 -l /usr/sbin/imapd – imapd

En este caso no redirige la conexión al puerto estandar de IMAP, sino que el mismo stunnel se encarga de lanzar el servidor, asumiendo así el mismo papel que inetd. En este caso el programa servidor debe soportar ese modo de ejecución (via inetd, no abriendo la conexión por sí mismo). Tras el doble guión se pone lo mismo que en el fichero inetd.conf tras el nombre del ejecutable.

Si el extremo de la conexión donde no tenemos un software SSL es el cliente, también podemos usar SSL. En este caso hay que ejecutar, en la máquina cliente:

stunnel -c -d 1999 -r sslserver:puerto-s

Y configuramos el cliente para que se conecte a locahost al puerto 1999.

Lo importante a recordar a es que:
En modo servidor (cuando no se usa la opción -c), la conexión entrante (por el puerto dado en -d) es SSL, y la que genera stunnel (dada por -r) no lo es.
En modo cliente ocurre justo lo contrario.

Podemos también encriptar cualquier conexión en la que ni cliente ni servidor sean SSL. Por ejemplo, para encriptar la conexión IMAP entre un lector de correo de PC y un servidor:
En el cliente:
stunnel -c -d 143 -r servidor_imap:1999

Habrá que configurar el programa de correo para indicarle que el servidor IMAP es el propio PC (una de las cosas buenas de stunnel es que tiene una versión casi totalmente funcional para PC).
En el servidor:
stunnel -d 1999 -r localhost:143

Aquí también hemos cogido un puerto aleatorio (1999) para la conexión encriptada. Este último caso es lo mismo que se puede conseguir con SSH de la forma:
ssh -L 143:servidor_imap:143 servidor_imap

La ventaja de stunnel es que no hay que tener una cuenta de la máquina remota. Debe ser el administrador de la misma (o nosotros si tenemos allí cuenta) quien arranque el servidor stunnel. No hay que indicarle a SSH un puerto aleatorio porque todo el tráfico encriptado va por la conexión que se establece con el servidor.

CERTIFICADOS
Cuando stunnel funciona en modo servidor, debe presentar un certificado al cliente, como todo servidor SSL. La distribución de stunnel trae uno, pero es conveniente generar uno propio, usando OpenSSL por ejemplo. La clave privada debe residir en un fichero no encriptado para que el programa pueda acceder a ella sin tener que pedir clave. Lo mismo cabe decir si se van a usar certificados en modo cliente, para su autentificación. Esto es un problema importante de seguridad, sobre todo en el caso de un PC, donde cualquier con acceso al mismo podrá acceder a la clave privada. Estaría bien que el programa soportara tenerla encriptada y contemplara formas de acceder a la misma al arrancar, como hace mod_ssl (como pedir la frase de paso al usuario, obtenerla mediante un programa o variables de entorno, etc.).

La autentificación de cliente puede imponerse ejecutando el servidor con la opción -v, cuyo argumento indica el nivel de autentificación exigido. Los valores que puede tomar son:
El cliente puede presentar o no un certificado. Si lo hace, comprobar que es válido.
El cliente debe presentar un certificado, que es verficado por el servidor. Si no es válido no acepta la conexión.
El cliente debe presentar un certificado, el cual debe ser figurar en una lista de certificados válidos almacenados en el servidor.

Un certificado se considera válido cuando va firmado por un CA cuyo certificado conozca el servidor (por tanto no aceptará certificados de cliente auto-firmados).

Estos pueden residir uno en cada fichero o todos en el mismo. En el primer caso, los nombres de los certificados deben tener nombres del tipo XXXXXXXX.0 (generados con openssl x509 -hash), y el nombre del directorio se le pasa a stunnel con la opción -a. Para el segundo caso (todos en el mismo fichero), se usa la opción -A.

Estas opciones nos pueden servir para implementar un control de acceso, para lo cual también se puede utilizar el control de TCP Wrappers, si stunnel se compiló con soporte para ello.


FORMAS DE FUNCIONAMIENTO
Ya hemos visto que stunnel puede actuar como cliente o como servidor. Estos roles se refieren a conexiones SSL, porque el cliente también puede ser servidor de conexiones no-SSL (opción -d), y el servidor puede ser cliente (opción -r).

En el caso del cliente, hay tres fuentes de las que puede obtener la conexión a enviar por el canal SSL:
Opción -d (modo daemon)
Por inetd. Un ejemplo de entrada en inetd.conf es:
servicio stream tcp nowait root /usr/local/sbin/stunnel \
stunnel -c -r host:puerto-s
En este caso no es necesario usar la opción -d porque obviamente la conexión se la da abierta inetd. Esta forma tiene el inconveniente de la lentitud por el arranque del programa en cada conexión.
Mediante un programa externo (con -l). En este caso son la entrada/salida estandar del programa lo que se envía por la conexión SSL:
stunnel -c -r server:puerto-s -l /.../programa


Lo que sí es obligatorio en el caso del cliente es la opción -r, para indicar a qué servidor y puerto SSL hay que conectarse.

En el caso del servidor, puede obtener la conexión SSL de dos fuentes:
Opción -d (modo daemon).
Por inetd, como en el caso anterior.
servicio-s stream tcp nowait root /usr/local/sbin/stunnel \
stunnel -r host:1999

El servidor puede conectarse a un destino de dos formas:
Opción -r
A un programa externo:
stunnel -d puerto-s -l /.../programa
En este caso se conecta con las entrada/salida estandar del programa.

La opción -L es semejante a -l, pero en este caso se abre un pseudo-tty para ejecutar el programa y es el descriptor esclavo del mismo el que se conecta. Esto se usa para encriptar conexiones PPP. En resumen:

Origen Destino
Cliente (-c)
-d, -l, -L, inetd -r
Servidor -d, inetd -r, -l, -L

Si ejecutamos stunnel en el modo inetd, tenemos problemas en sistemas operativos, como Solaris, que no permiten pasar a un programa arrancado de esta forma más de 5 argumentos, por lo que si hay que usar la opción -p o -R (para indicar el fichero de datos aleatorios, si es necesario), puede que tengamos que compilar el programa con esos datos por defecto, de forma que no haya que pasárselos como argumentos.

APRENDIENDO A INICIAR STUNNEL
Es posible usar Stunnel para proporcionar una conexión segura entre bases de datos locales y remotas. Si usted tiene una base de datos en una máquina distinta a la que ubica el cliente psql, es posible proporcionar una conexión segura entre psql y la base de datos. Si su base de datos está ubicada en la misma máquina que el cliente psql, puede proporcionar una igualmente segura conexión entre los dos programas locales.

Debería haber un archivo llamado stunnel en su directorio Stunnel; este es el ejecutable del programa. Las instrucciones incluídas asumen que usted está usando el ejecutable desde este directorio, pero puede copiarlo a /usr/local/sbin, o a otra ruta de su elección. También, puede crear enlaces a este archivo en sus scripts de arranque para que sea automáticamente inicializado cuando el sistema arranque.

Si usa Stunnel con inetd, no necesitará llamarlo desde un script de arranque.

La ejecución de Stunnel en modo demonio es realmente simple, ya esté conectando a una base de datos local o remota. Para usar Stunnel para conectar a una base de datos local, debe iniciarlo como cliente y como servidor (dos procesos diferentes del mismo programa, cada uno corriendo en un puerto distinto). Luego instruirá a psql para que se conecte al número de puerto que el cliente stunnel está usando.

Una vez que psql ha conectado con el cliente, cualquier dato será encriptado y entonces enviado al servidor Stunnel donde es desencriptado y enviado al servidor PostgreSQL. Al cliente debe serle indicado sobre qué puerto correr, además del puerto en el cual está corriendo el proceso servidor.

El uso más común de Stunnel es para enviar datos desde un cliente local a un servidor remoto. La forma de hacer esto es iniciar el proceso cliente Stunnel localmente, bien llamándolo con un script de arranque (tal como /etc/rc.d/rc.local) o bien llamándolo directamente desde el directorio de instalación. Luego debe iniciar el proceso Stunnel remotamente en la máquina donde PostgreSQL está corriendo. Como con el cliente, usted puede querer iniciar el servidor automáticamente durante el arranque del sistema.

Tanto las ejecuciones del cliente como del servidor STunnel en un escenario de ejemplo se demuestran en los ejemplos siguientes.


EJEMPLOS

Ejemplo 1
Veamos un ejemplo completo de cómo conseguir una comunicación segura con control de acceso al puerto 25 (SMTP) de un servidor desde un PC, suponiendo que en ninguna de las máquinas tenemos software SSL, y que hemos seguido el procedimiento de la página antes mencionada para crear los certificados de servidor y de clientes:
Llevarse el fichero client.pem al PC, al directorio donde tengamos el stunnel.exe.
Ejecutar en el servidor:
stunnel -d 1999 -r 25 -p $CADIR/certs/server.pem \
-v 3 -A $CADIR/cacert.pem -a $CADIR/certs
Ejecutar en el cliente:
stunnel -c -d 25 -r servidor:1999 -p client.pem
Configurar el cliente de correo de forma que el servidor SMTP es el propio PC.

Si en el servidor queremos aceptar cualquier cliente cuyo certificado haya sido firmado por nuestra CA, la orden a ejecutar en el servidor sería:

stunnel -d 1999 -r 25 -p $CADIR/certs/server.pem \
-v 2 -A $CADIR/cacert.pem


Ejemplo 2
Ejecutar en el servidor:
[user@remote ~]$ # Este comando innicia el servidor en la máquina remota.
[user@remote ~]$ stunnel -P/tmp/ -p ~/stunnel.pem -d 9000 -r localhost:5432
Ejecutar en el cliente:
[user@local ~]$ # Este comando inicia el cliente en la máquina local.
[user@local ~]$ stunnel -P/tmp/ -c -d 5432 -r 192.168.1.2:9000

El comando de máquina remota (el primero) le dice al servidor que use /stunnel.pem como certificado para la encriptación, y que abra un proceso Stunnel como demonio. El parámetro -d 9000 provoca que el demonio escuche datos encriptados en el puerto 9000. El parámetro -r localhost:5432 le dice al proceso demonio que cuando reciba datos encriptados en su puerto de escucha (9000, en este caso), debería desencriptarlos y enviarlos a localhost en el puerto 5432 (el cual es el puerto de PostgreSQL, significando que los datos desencriptados serán enviados al servidor de bases de datos en la máquina local).

El segundo comando abre una instancia de Stunnel en la máquina cliente, en modo cliente (como dicta el flag -c), que escucha por el puerto 5432. El parámetro -r 192.168.1.2:9000 le indica al proceso que la computadora servidora está localizada en 192.168.1.2, y que está a la escucha por el puerto 9000 para paquetes encriptados.

Ambos modos requieren el flag -P /tmp/ para proporcionar una ruta temporal para el archivo PID, el cual es el archivo que almacena el ID de sistema del proceso Stunnel. No necesita especificar el nombre del archivo PID, sólo con la ruta ya es suficiente (el nombre de archivo será por defecto algo parecido a stunnel.localhost.9000.pid), aunque podría especificarlo si lo desea.

Una vez que cada uno de estos procesos Stunnel están corriendo en sus respectivas máquinas, el cliente psql puede ser apuntado al puerto 5432 en la máquina cliente. Los paquetes enviados a este puerto serán encriptados de forma transparente, enviados al puerto 9000 en la máquina servidora, desencriptados y enviados a PostgreSQL en el puerto 5432. Esto es similar al túnel SSH discutido en la sección denominada ``SSH/OpenSSH'', pero con una notable distinción: el proceso cliente Stunnel puede ser creado sin ningún tipo de autenticación en el servidor remoto.

Esta encriptación ocurre de forma completamente separada de los procedimientos normales de autentificación de PostgreSQL; en cuanto le concierne al proceso en segundo plano postmaster, los datos son enviados a través de él en texto plano, porque estos son desencriptados antes de ser reenviados al postmaster. El uso de Stunnel en conjunción con la autenticación mediante contraseña puede ser el ideal, ya que éste usa una política de restricción basada en contraseñas, y también encripta dichas contraseñas sobre la conexión de red.

Adicionalmente, como ya mencionamos, usted tiene la opción de ejecutar los dos procesos Stunnel localmente para encriptar paquetes entre dos puertos TCP/IP locales. La iniciación de ambos procesos cliente y servidor sobre la misma máquina se demuestra en el siguiente ejemplo. Usando Stunnel localmente.

[user@local ~]$ stunnel -P/tmp/ -p ~/stunnel-3.15/stunnel.pem -d 9000 -r 5432
[user@local ~]$ stunnel -P/tmp/ -c -d 5433 -r localhost:9000

El primer uso de stunnel abre el proceso servidor, y le dice al mismo que use /stunnel-3.15/stunnel.pem como archivo de certificado. También instruye al demonio para que escuche conexiones por el puerto 9000, y que envíe los datos desencriptados desde ese puerto al puerto 5432. El ejemplo usa el puerto 5432 porque el servidor PostgreSQL está corriendo con ese puerto.

El segundo uso de stunnel abre el proceso cliente Stunnel en el puerto 5433 (escogido arbitrariamente para enlazar al puerto PostgreSQL, en éste caso). Ese demonio es instruído para encriptar los datos entrantes, y para reenviarlos al proceso servidor a la escucha en la máquina localhost por el puerto 9000.

LIMITACIONES
Stunnel tiene dos opciones a la hora de decidir cómo correr en su sistema: usando inetd, o ejecutando el binario Stunnel como demonio. Esta última es la forma preferida, ya que usar inetd puede crear limitaciones en el software debido a varias cuestiones relacionadas con SSL. Estas limitaciones incluyen:
Stunnel debe ser inicializado para cada conexión por inetd
No es posible ninguna caché de sesión
inetd requiere forking (lo cual causa sobrecarga en el procesador)

VULNERABILIDADES
Las versiones previas a la 3.11 de Stunnel contienen diversas vulnerabilidades que hacen que su uso resulte inseguro. Stunnel es una herramienta que permite hacer un "forwarding" de puertos TCP/IP entre dos máquinas que lo estén ejecutando, utilizando tecnología SSL para asegurar la autenticidad, la integridad y la confidencialidad de las transmisiones. Las versiones previas a la 3.11 contienen tres vulnerabilidades:
El generador de números pseudoaleatorios contiene errores que hacen que sus valores sean predecibles, comprometiendo la calidad criptográfica de la sesión y de las claves generadas con esta herramienta.
El programa genera un fichero "pid" (donde se almacena el PID del proceso) de forma insegura, siendo vulnerable a ataques a través de enlaces simbólicos.
El uso de la función "syslog()" es incorrecto, siendo vulnerable a ataques de formato.
Se recomienda a todos los usuarios de Stunnel que actualicen a la versión 3.11 o superior cuanto antes.

CONCLUSIONES.

Con stunnel se pueden entubar (por decirlo de alguna forma) conexiones TCP de y hacia puertos arbitrarios entre un servidor y un cliente. Se puede redirigir un puerto local a uno remoto en donde está corriendo el demonio stunnel el cual a su vez redirige ese puerto a uno estándar donde está escuchando algún servicio. Me explico: Quería que las conexiones POP3 viajasen de forma segura entre el cliente y el servidor.

Diseñado para ofrecer la seguridad SSL a servidores (demonios) o clientes que no han sido programados con soporte SSL.
Se puede utilizar desde inetd o xinetd.
El uso más frecuente es para cifrar servicios como POP, IMAP, SMTP, LDAP, etc.
Junto con PPP se puede crear fácilmente una Red Privada Virtual RPV (VPN).
Se puede configurar para validar a los clientes mediante certificados.


REFERENCIAS.

http://www.sobl.org/traducciones/practical-postgres
Aplicación en bases de datos
http://www.stunnel.org/faq/
Pagina principal de Stunnel
http://www.uni-freiburg.de/rz/pc/software/stunnel/
Stunnel 3.4a packaged in a Windows Install Wizard

http://www.exim.org/pipermail/exim-users/Week-of-Mon-19991011/014751.html
Using Stunnel with Exim

http://www.onsight.com/faq/stunnel/
The original Stunnel Web FAQ (retired)

http://stunnel.mirt.net/
The official stunnel home page

http://www.rickk.com/sslwrap/
programa semejante a stunnel
http://www.ssh.com
Conectividad SSH
http://www.openssh.com
Conectividad SSH Libre
http://www.openssl.org
Conectividad SSH Libre

No hay comentarios: