Autenticación de usuarios mediante certificados


Suele ser cada vez más normal que se nos requiera a los administradores de sistemas una forma alternativa para acceder a los correos corporativos desde cualquier lugar del mundo, además de usando el cliente de correo. Normalmente esta opción suele ser usar algún tipo de webmail.

Bajo mi punto de vista ésta es sin duda una forma muy cómoda de acceder al correo electrónico, y al mismo tiempo un peligro en potencia. Los usuarios y muchos administradores de sistemas suelen dormir tranquilos cuando instalan este servicio usando https y protegido con un login y un password para cada usuario que tenga cuenta en el servidor. Sin embargo, en mi caso, son numerosos los dolores de barrigua que me produce el pensar que cualquiera desde un ciberbar puede ver los correos de la gente a la que se supone que protejo con el simple hecho de saber la clave del usuario…

Donde actualmente trabajo, existe una gran cantidad de consultores que viajan alrededor de todo el mundo y usan en ocasiones el webmail desde algún ordenador que les proporciona el cliente al que van a prestar la consultoría. Es muy fácil que a un cliente poco avanzado se le ocurra echar un ojo por encima del hombro de mi consultor cuando va a teclear la clave, para luego poder usarla él tranquilamente desde su casa. Un cliente un poco más avanzado podría incluso instalar un keylogger en esa máquina, con lo que el trabajo sería aún más fácil. Entonces… ¿cuál es la solución? La solución pasa por mejorar el sistema de autentificación. Hay que autentificarse no sólo por una clave que sabes, sino que también debes usar un certificado que tienes. Probablemente en tu pendrive, que debes guardar como si fuese tu tarjeta de crédito.

Doy por hecho de que ya tenemos un servidor Apache bajo Linux instalado, por lo que voy a pasar a cómo generar los certificados para los clientes.

En este caso, nosotros mismos seremos la autoridad certificadora (CA) que firmará los certificados del cliente, autoridad que hay que guardar de forma segura y sólo poder acceder a ella los administradores de sistemas. Espero que este mini-manual os sirva de ayuda. Tened en cuenta que tendréis que adaptar los comandos ejecutados para que se ajusten a vuestra estructura de directorio. Esta instalación se ha hecho en una distribución Gentoo, pero sirve para cualquiera.

Paso 1: Configuración Apache y SSL

Ahora vamos a hacer que escuche en el puerto 443 para conexiones seguras. Es decir, para el protocolo https.

Añadimos lo siguiente al fichero /etc/apache2/vhosts/00_default_ssl_vhost.conf:


Listen 443
SSLEngine on
SSLOptions +StrictRequire

SSLProtocol -all +TLSv1 +SSLv3
SSLCipherSuite HIGH:MEDIUM:!aNULL:+SHA1:+MD5:+HIGH:+MEDIUM

SSLMutex file:/var/log/apache2/ssl_mutex

SSLRandomSeed startup file:/dev/urandom 1024
SSLRandomSeed connect file:/dev/urandom 1024

SSLSessionCache shm:/var/log/apache2/ssl_cache_shm
SSLSessionCacheTimeout 600

SSLPassPhraseDialog builtin
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key

SSLVerifyClient none
SSLProxyEngine off

AddType application/x-x509-ca-cert      .crt
AddType application/x-pkcs7-crl         .crl

SetEnvIf User-Agent ".*MSIE.*" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0

NOTA: En el fichero de configuracion del apache, esa linea anterior debe ir sin los \.

Antes de arrancar de nuevo nuestro Apache tendremos que generar los certificados, que estarán firmados por nosotros mismos. Se supone que nos los tendria que dar alguna empresa tipo VeriSign, pero para lo que nosotros queremos, nos bastamos y nos sobramos.

servidor:/etc/apache2/ssl# openssl req -new -x509 -days 30 -keyout /etc/apache2/ssl/server.key -out /etc/apache2/ssl/server.crt -subj ‘/CN=Javi-Test-Certificate’

(Para más información sobre la sintaxis ir a www.openssl.org)

servidor:/etc/apache2/ssl# openssl req -new -x509 -days 30 -keyout /etc/apache2/ssl/server.key -out
/etc/apache2/ssl/server.crt -subj ‘/CN=Organizacion-Test-Certificate’

Generating a 1024 bit RSA private key
..++++++
.......................................++++++
writing new private key to '/etc/apache2/ssl/server.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:

Desde ahora cuando arranquéis Apache os pedirá la clave. En realidad es configurable, pero por defecto os lo pedirá.

Una vez arrancado ya podéis conectaros poniendo desde el mismo ordenador, en un navegador https://localhost

Os saldrán los datos del certificado.

Si es así es que vamos bien.

Ahora vamos a cambiar la configuración, para que cada cliente que se vaya a conectar a nuestro web tenga que tener un certificado instalado en su navegador.

Paso 2: Hacemos que el servidor nos pida un certificado

Para eso, cambiamos configuración en Apache cambiando los siguientes valores:

SSLVerifyClient require
SSLVerifyDepth 1

Ese valor a 1 significa el numero máximo de intermediarios que aceptamos en el certificado. Si lo ponemos a 1 significa que todos los certificados tienen que estar firmados directamente por el CA que indiquemos. En este caso somos nosotros mismos.

Una vez que hagamos esos cambios y volvamos a rearrancar el servidor, veremos que ya no nos podemos conectar, y eso se debe a que no tenemos instalado ningún certificado en nuestro navegador; por lo tanto no tiene éxito la negociación y nos echa.

Tenemos que indicar Apache cuál es la entidad certificadora. En nuestro caso está en /etc/apache2/ssl/server.crt

Para ello, en httpd.conf añadimos:

SSLCACertificateFile /etc/apache2/ssl/server.crt

Reiniciamos Apache para ver que va todo bien.

Paso 3: Generación de certificados para clientes

Generación de certificados para la gente que queramos que vea nuestra web.

La creación de certificados para el cliente es muy similar a la que seguimos para la generación de certificados para el servidor.

Mediante este comando creamos una clave cliente:

servidor:/etc/apache2/ssl#openssl req -new -sha1 -newkey rsa:1024 -nodes -keyout client.key -out request.pem -subj ‘/O=Secure/OU=Organizacion/CN=Javi’

Eso genera dos ficheros, client.key y request.pem (éste debe ser firmado por la CA, en este caso nosotros). La CA se supone que debe de asegurarse que la información es real antes de firmar nada.

Ahora toca firmarla. Te puedes poner a configurar el fichero openssl.cnf, pero yo lo que hice fue copiar el directorio /usr/lib/ssl/misc/demoCA a mi directorio CA, con lo que me quedó la siguiente estructura:

javi@servidor:~$ tree CA
CA
|-- demoCA
|   |-- cacert.pem
|   |-- careq.pem
|   |-- certs
|   |-- crl
|   |-- index.txt
|   |-- index.txt.attr
|   |-- index.txt.old
|   |-- newcerts
|   |   `-- 91213828FA1E8EA9.pem
|   |-- private
|   |   `-- cakey.pem
|   `-- serial
|-- requests
|   `-- request.pem
`-- signed
`-- signed.pem

Una vez ejecutado:

servidor:/etc/apache2/ssl# openssl ca -config /usr/lib/ssl/openssl.cnf -keyfile /etc/apache/ssl/server.key -cert /etc/apache2/ssl/server.crt -policy policy_anything -out /etc/apache2/ssl/CA/signed.pem -infiles /etc/apache2/ssl/CA/requests/request.pem

Tenemos el fichero signed.pem listo para enviar al cliente.

El cliente por tanto, una vez recibido ese fichero, tendrá en un directorio los
siguientes ficheros:

  • client.key
  • request.pem
  • signed.pem

Ahora tiene que guardarlo todo en un certificado con formato PKCS#12 y para eso hace:

openssl pkcs12 -export -clcerts -in signed.pem -inkey client.key -out client.p12

Y ya para finalizar hay que cargar el certificado client.p12 en el navegador. Cada navegador tendrá un procedimiento para hacer esto.

Share
Javier Rodriguez Escrito por:

Sé el primero en comentar

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *