Implementación de Certificados Gratuitos Let's Encrypt en Cisco ASA para Accesos VPN

Esta semana se conoció la noticia que el servicio Let's Encrypt alcanzó el millón de certificados emitidos. Esta CA es gratuita, open-source y en ella ya confían la mayoría de los navegadores.

¿ Pero para qué otros servicios podemos utilizar estos certificados ?

Veamos un 'tweak' de como utilizar Let's Encrypt para generar un certificado que vamos a aplicar en nuestro firewall, que en este caso será un Cisco ASA, a través del que los usuarios de nuestra red y otros externos, se pueden conectar por medio de VPN, a los recursos de la empresa. Y esperemos que pronto ya se integren de manera automatica...

Si las PC que se conectan a la VPN, estasen toda administradas por un servidor de dominio, sería suficiente con utilizar un certificado firmado por nuestra CA interna en la que confien todos los equipos. Pero esto no siempre se da en la práctica, por ejemplo podría darse un escenario en que se conecten por VPN clientes o proveedores con pcs particulares, que tengan accesos específicos a algún servicio de nuestra red, y no está mal que utilicemos una CA pública para garantizar identidad en el dominio. Esto, siempre y cuando, utilicemos un nombre de dominio para el acceso y no únicamente la dirección IP, lo que es generalmente más cómodo y fácil de recordar.

En este ejemplo, el dominio será https://vpn.tuempresa.com y la IP a la que está asociada: 200.200.200.200.
O sea, 200.200.200.200 es la IP que tiene la outside del firewall Cisco ASA, que está asociada al crypto map de VPN.

Let's Encrypt utiliza un mecanismo de chequeo de propiedad de dominio basado en la validación de un código númerico que se debe ubicar en un path específico del dominio en cuestión, mediante acceso web, que se genera al momento de solicitar el certificado.

Entonces, lo que vamos a hacer es, para generar el certificado de nuestro firewall, primero asociar el dominio que uitizamos para VPN a algún webserver que controlemos, para poder poner el código que Let's Encrypt verificará, luego lo volveremos a mover a la IP original que tiene la outside del firewall y configuraremos el certificado generado en el Firewall.

Instalar Let's Encrypt, es tán sencillo como clonar el repositorio de GIT y ejecutar un script que hace todo el proceso de instalación de dependencias. Yo recomiendo instalarlo en un servidor dedicado, y no en el mismo webserver, ya que como la instalación es automática no controlamos específicamente los paquetes que instala. Mejor levantar una virtual dedicada a este servicio.

Entonces son 3 pasos:

sudo yum install git
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto

Luego de tener Let's Encrypt en nuestro servidor instalado, lo que vamos a hacer es generar un certificado manual para el dominio http://vpn.tuemperesa.com

./letsencrypt-auto certonly -a manual -d vpn.tuempresa.com

El script hace primero un chequeo de actualizaciones, luego solicita permisos de root si no fué ejecutado con ese usuario.
Te va a avisar que la IP pública de tu servidor va a ser logueada, tendrás que contestar que sí.

Luego de contestar que sí, el script te informará algo como lo siguiente:

Make sure your web server displays the following content at
http://vpn.tuempresa.com/.well-known/acme-challenge/c5bkVUVXuIzOgLapaA-kj3GWqKjHZ-b0SZ7OjGHmMuo before continuing:

c5bkVUVXuIzOgLapaA-kj3GWqKjHZ-b0SZ7OjGHmMuo.cqHxOq3UKUGrsDtGPpZFGuuWasVwY7gI4R5hDsYJrZg

If you don't have HTTP server configured, you can run the following
command on the target server (as root):

mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
cd /tmp/letsencrypt/public_html
printf "%s" c5bkVUVXuIzOgLapaA-kj3GWqKjHZ-b0SZ7OjGHmMuo.cqHxOq3UKUGrsDtGPpZFGuuWasVwY7gI4R5hDsYJrZg > .well-known/acme-challenge/c5bkVUVXuIzOgLapaA-kj3GWqKjHZ-b0SZ7OjGHmMuo

# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()" 

Básicamente, lo que está informándote es lo que va a chequear, desde internet, en el dominio que querés certificar.
Por lo tanto, hay que meter en el path /.well-known/acme-challenge/ el archivo c5bkVUVXuIzOgLapaA-kj3GWqKjHZ-b0SZ7OjGHmMuo que contiene c5bkVUVXuIzOgLapaA-kj3GWqKjHZ-b0SZ7OjGHmMuo.cqHxOq3UKUGrsDtGPpZFGuuWasVwY7gI4R5hDsYJrZg

Nos dá el script para generar ese archivo en /tmp/ , que es:

mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
cd /tmp/letsencrypt/public_html
printf "%s" c5bkVUVXuIzOgLapaA-kj3GWqKjHZ-b0SZ7OjGHmMuo.cqHxOq3UKUGrsDtGPpZFGuuWasVwY7gI4R5hDsYJrZg > .well-known/acme-challenge/c5bkVUVXuIzOgLapaA-kj3GWqKjHZ-b0SZ7OjGHmMuo

Ejecutenlo en el servidor web y luego muevan el directorio /tmp/letsencrypt/public_html/.well-known con su contenido al path que asociaron a vpn.tuempresa.com, de esta manera, Let's Encrypt podrá chequear que el dominio te pertenece.

Si todo resultó bien, luego de indicarles que continuen, recibirán un mensaje de que fué correctamente verificado, y el path donde se dejó el certificado con toda la cadena: /etc/letsencrypt/live/vpn.tuempresa.com/

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/vpn.tuempresa.com/fullchain.pem. Your cert
   will expire on 2016-06-15. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - If you like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

En esa carpeta van a encontrar:

cert.pem – contiene el certificado firmado
chain.pem – certificado “intermedio”
fullchain.pem – contiene ambos cert.pem y chain.pem, para los servicios que soporten este formato
privkey.pem – la llave privada del certificado

Lo primero que debemos hacer antes de instalar el certificado en el Firewall, es generar un certificado más en formato pkcs12, que es un formato que contiene la privada y la pública en un mismo file. Lo haremos mediante openssl, con el siguiente comando:

openssl pkcs12 -export -inkey privkey.pem -in cert.pem -name "vpn.tuempresa.com.ar" -out cert.p12

Se pedirá una clave y confirmarla, si todo fué bien, entonces ahora tendrán un archivo más cert.p12

La instalación en el firewall:

Los procedimientos más comunes para establecer comunicación segura mediante certififcados en los firewalls son o generar un CSR (Certificate Sign Request) a partir de la private key del equipo y firmarla por una CA pública, o generar un self signed certificate. Pero en este caso, el procedimiento será un poco diferente ya que incorporaremos al equipo la private key y el certificado firmado...

MEDIANTE ASDM:

  1. Crear la CA:

Configuration - Device Management - Ceritifcate Management - CA Certificate - Add
Le ponemos el nombre: CA-LETSENCRYPT
Seleccionamos la opción la opción "Paste certificate in PEM format:"
Pegamos el contenido del certificado intermedio, que es chain.pem
Install certificate.

  1. Importar el cert y privkey en formato pkcs12:
    Configuration - Device Management - Ceritifcate Management - Identity Certificate - Add
    Le ponemos el nombre: SRV-LETSENCRYPT
    Seleccionamos la opción la opción "Import the identity certificate from a file (PKCS12 format with Certificate(s)+Private Key)"
    En "Decryption Passphrase:" ponemos la password que seteamos al armar el pkcs12 con OpenSSL.
    Y Seleccionamos el file cert.p12
    Add Certificate

  2. Asociar el Certificado a la Outside Del Firewall:
    Por último debemos asociar el certificado o trustpoint que creamos en el punto 2, a la interface que responde VPN. En nuestro caso la outside.
    Configuration - Device Management - Advanced - SSL Settings
    En la sección "SNI (Server Name Indication)", seteamos vpn.tuempresa.com y le asociamos el trustpoint SRV-LETSENCRYPT
    En la sección "Certificates" nos paramos en la interface correspondinete, le damos Edit, y también seteamos el certificado SRV-LETSENCRYPT en Primary.

MEDIANTE CLI

Para poder hacer este procedimiento mediante CLI, primero vamos a tener que ejecutar un comando más con OpenSSL, que nos va a decodificar el pkcs12 a base64, el comando es:

openssl base64 -in cert1.p12 -out base64-cert1.p12
  1. Crear la CA:

    crypto ca trustpoint CA-LETSENCRYPT
    enrollment terminal
    crl configure

    crypto ca authenticate CA-LETSENCRYPT

    • Copiar el Contenido de chain.pem
      quit
  2. Importar el cert y privkey en formato pkcs12:

    crypto ca trustpoint SRV-LETSENCRYPT
    crl configure
    exit

    crypto ca import SRV-LETSENCRYPT pkcs12

    • Copiar el Contenido de base64-cert1.p12
      quit
  3. Asociar el Certificado a la Outside Del Firewall:

    ssl trust-point SRV-LETSENCRYPT outside
    ssl trust-point SRV-LETSENCRYPT domain vpn.tuempresa.com

Con esta configuración debería ser suficiente.

Pueden probarlo a través de un browser entrando a https://vpn.tuempresa.com y conectando por VPN con el cliente correspondiente.

Saludos Colegas !

@Gabriel Soltz

Read more