LetsEncrypt

El proyecto Let’s Encrypt nació en 2012 a partir de la idea inicial de dos empleados de Mozilla, Josh Aas y Eric Rescorla a los que posteriormente se unieron Peter Eckersley de la Electronic Frontier Foundation (EFF) y Alex Halderman de la universidad de Michigan, constituyendo en 2013 la corporación sin animo de lucro Internet Security Research Group (ISRG). La verdad es que se trataba de una idea bastante ambiciosa y no poco controvertida, ni más ni menos que conseguir que Internet fuera un lugar más seguro y privado, de manera que nuestra privacidad en Internet sea realmente privada, para lo cual deberían dar capacidad de encriptar toda la Web haciendo universal el uso del protocolo https.

Todos los que administramos algún servidor somos conscientes de que esto no es una cuestión sencilla, hasta ahora si queríamos asegurar nuestros servidores debíamos de «pasar por caja» además de vernos obligados a cumplir con toda la burocracia y periodos que nos imponía la Autoridad Certificadora (CA) de turno para validarnos, lo cual hacia que en muchos casos no fuese factible la idea de obtener un certificado valido.

Hasta el momento disponíamos de pocas alternativas, podíamos generar y emplear nuestros propios certificados autofirmados de forma muy sencilla, lo cual aseguraba que nuestras comunicaciones viajasen cifradas pero sufriendo los incontables problemas que dan este tipo de certificados al no asegurar la identidad, mostrando alertas y obligando a añadir excepciones de seguridad, sin contar con la desconfianza y mala imagen que esto genera de cara a los usuarios finales.

conexión insegura Firefox

Como alternativa se podría decir que teníamos CAcert.org, la cual es una Autoridad de Certificación administrada por la comunidad y que otorga certificados de forma gratuita, en este caso, podemos decir que ganamos en confianza ya que al igual que en el resto de CA comerciales, es necesario pasar por cierta burocracia para obtener el certificado existiendo un grupo de «auditores» que avalan la identidad, pero aún con todo seguimos teniendo el gran problema de que esta autoridad de certificación no es incluida por defecto como una CA valida en la mayoría de sistemas y navegadores, por lo que los usuarios finales debían añadir esta CA a las autoridades de confianza para evitar el mensaje de conexión no verificada. Lo cual de nuevo es un problema ante proyectos dirigidos al publico general.

Por otro lado, creo que es justo indicar que desde hace años la CA comercial StartSSL nos permite obtener certificados validos, pero por supuesto hay truco y claramente para este tipo de certificados impone varias limitaciones:

  • Validos solo para uso personal.
  • Solo se puede registrar un certificado por cuenta.
  • Tan solo se permite un subdominio (normalmente www).
  • El registro es sólo por 1 año (Después deberías pagar).

Pero por suerte el proyecto Let’s Encrypt fue madurando siendo anunciado al publico el 18 de Noviembre de 2014, para evitar los problemas típicos existentes en la adquisición  de un certificado se desarrollo el protocolo Automated Certificate Management Enviroment (ACME), que fue enviado a la IETF para su estandarización el 28 de Enero de 2015 y el cual es la piedra angular del proyecto, ya que gracias a este protocolo se puede automatizar el proceso de validación no siendo necesaria intervención humana. El proyecto fue desarrollándose y tras un tempo de betas privadas (solo se podía acceder bajo invitación), por fin el 3 de Diciembre de 2015 el proyecto entro en fase de beta publica quedando a disposición de cualquier interesado.

Son ya varios los proveedores de hosting que están habilitando estos certificados para que sus clientes los puedan utilizar de forma gratuita y viendo los patrocinadores del proyecto, al que cada vez se unen más «pesos pesados», podemos entrever la seriedad y el alcance del mismo.

Patrocinadores del proyecto Let's Encrypt

Los certificados que podemos obtener mediante Let’s Encrypt son certificados con una validez de 90 días, lo cual no es mayor problema al poder automatizar el proceso de renovación con un simple script y conseguimos «barra verde» ya que estos son firmados por IdenTrust, uno de sus principales patrocinadores y reconocida autoridad certificadora que se encuentra preinstalada por defecto en la mayoría de sistemas y navegadores. No podemos obtener certificados wildcard ni certificados multidominio por lo que deberemos generar un certificado para cada dominio y/o subdominio que necesitemos asegurar, pero como ya hemos indicado, al poder automatizar el proceso no es mayor problema y si lo pensamos detenidamente, tiene su lógica.

Para obtener y/o actualizar los certificados han desarrollado un cliente de código abierto en Python que mediante plugins nos da la opción de escoger entre varios sistemas para poder conseguir nuestro certificado, por ejemplo modificando automáticamente los ficheros de configuración del servidor web Apache o inclusive levantando un servidor web propio. Pero a mi personalmente uno de los métodos que más me ha gustado, es empleando el plugin webroot el cual lo único que necesita es que exista el directorio .well-known accesible desde la raíz de nuestro sitio.

Let's Encrypt - webroot - nginx

A modo de ejemplo voy a mostrar el proceso necesario para conseguir un certificado empleando el servidor web nginx y este método. Lo primero que necesitaremos es obtener la última versión estable del cliente oficial, para ello lo más cómodo es clonar el repositorio git.

Si no lo teníamos ya instalado, instalamos git:

apt-get install git

Clonamos el cliente oficial de Let’s Encrypt en el directorio /opt que es donde se suele colocar el software de terceros:

git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt

Creamos el directorio para servir nuestros archivos de identificación:

mkdir -p /var/www/letsencrypt

Editamos el archivo de configuración de nuestro sitio /etc/nginx/sites-available/example.com y añadimos la directiva location para que example.com/.well-known apunte a /var/www/letsencrypt, una característica importante a tener en cuenta es que si necesitamos certificados para varios dominios/subdominios podemos compartir el mismo directorio /var/www/letsencrypt sin ningún problema:

server{
    listen 80;
    server_name example.com
    [...]
    location /.well-known {
        root /var/www/letsencrypt/;
    }
}

Ahora vamos a crear un archivo de configuración para obtener nuestros certificados, podríamos enviar directamente los parámetros, pero a mi me gusta más esta opción:

mkdir -p /etc/letsencrypt/confcerts

Si necesitamos crear varios certificados para varios subdominios o inclusive dominios distintos basta con que los indiquemos en la variable domains separándolos mediante coma, aunque a mi personalmente me gusta más crear un fichero de configuración para cada uno de los certificados que necesito:

nano /etc/letsencrypt/confcerts/example.com.ini
# Let's Encrypt archivo de configuración

# Usamos el método de identificación webroot
authenticator = webroot

# El siguiente directorio será servido por nginx y es necesario
# para que mediante el plugin webroot Let´s Encrypt pueda validar
# nuestro dominio para crear o actualizar el certificado.
webroot-path = /var/www/letsencrypt

# Se generaran certificados para los dominios que especifiquemos aquí.
# En caso de necesitar varios FQDN se separaran mediante comas sin
# dejar espacio entre ellos.
# domains = example.com,subdomain1.example.com,otherdomain.es
domains = example.com

# Registramos los certificados con la siguiente dirección de e-mail.
# Es muy importante que este sea un e-mail valido de nuestra propiedad,
# ya que será el empleado para contactar ante cualquier problema que
# pudiera surgir con nuestro certificado.
email = tuemail@xxx.com

# Usamos una clave de 4096 bit RSA el lugar de 2048 bit
rsa-key-size = 4096

Ya podemos intentar la generación de nuestros certificados:

/opt/letsencrypt/letsencrypt-auto certonly -c /etc/letsencrypt/confcerts/example.com.ini

Los ficheros correspondientes a nuestros certificados se generan en /etc/letsencrypt/archive/example.com/ y son:

cert1.pem - (certificado firmado)
chain1.pem - (certificado intermedio)
fullchain1.pem - (contiene el certificado firmado y el intermedio concatenados)
privkey1.pem - (es la llave privada del certificado)

Aunque para configurar nuestro servidor no vamos a utilizar estos, sino los enlaces simbólicos a estos que se encuentran en /etc/letsencrypt/live/example.com/:

cert.pem
chain.pem
fullchain.pem
privkey.pem

Esto es porque cuando regeneramos o actualizamos nuestros certificados la utilidad no elimina los archivos anteriores, simplemente genera unos nuevos aumentando la versión (número del final de los archivos) y se actualizan los enlaces simbólicos para que siempre apunten a los archivos correspondientes al último certificado generado.

Configuramos nginx para habilitar el uso de https:

server{
   listen 80;
   listen 443;
   server_name example.com;

   ssl_certificate           /etc/letsencrypt/live/example.com/fullchain.pem;
   ssl_certificate_key       /etc/letsencrypt/live/example.com/privkey.pem;

   ssl on;
   ssl_session_cache  builtin:1000  shared:SSL:10m;
   ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
   ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
   ssl_prefer_server_ciphers on;

   [...]
   
   location /.well-known {
       root /var/www/letsencrypt/;
   }
}

Recargamos la configuración de nginx:

service nginx reload

Y ya podemos disfrutar de una conexión segura desde cualquier navegador:

Barra verde Let's Encrypt

Como ya hemos comentado la duración de estos certificados es tan solo de 3 meses, pero no es necesario que esperemos a que estos caduquen para poder renovarlos, podemos hacerlo en cualquier momento y de una forma que podemos automatizar de manera muy simple. En este caso haremos que se actualicen cada mes mediante un script en el cron del sistema:

nano /etc/cron.monthly/renew-certs
#!/bin/bash

/root/.local/share/letsencrypt/bin/letsencrypt certonly -c /etc/letsencrypt/confcerts/example.com.ini --renew-by-default

service nginx reload

Mediante el parámetro –renew-by-default indicamos que no se muestre ningún dialogo renovando nuestros certificados sin necesidad de ninguna intervención por nuestra parte.

No debemos olvidar dar permiso de ejecución a nuestro script:

chmod +x /etc/cron.monthly/renew-certs

Y eso es todo lo que necesitamos para disponer de nuestros certificados de «barra verde» actualizados el día 1 de cada mes.

De todas formas el cliente oficial es una opción, como ya hemos comentado la gracia del sistema radica en el protocolo ACME, por lo que no han tardado a aparecer otros proyectos no oficiales para obtener certificados de Let’s Encrypt. Así que si no nos convence el cliente oficial podemos buscar una alternativa o si somos más osados, generar la nuestra propia. En estos momentos quizás los proyectos más interesantes sean:

  • acme-tiny, un cliente bastante ligero desarrollado en Python.
  • simp_le, parecido al anterior y desarrollado también en Python.
  • letsencrypt.sh, implementación desarrollada directamente en Bash.
  • acme-client, cliente desarrollado en PHP 7. El autor también tiene el proyecto con la librería para PHP por separado: kelunic/acme
  • lescript, otra librería PHP para poder consumir el protocolo ACME. En este caso tan solo es necesaria una versión de PHP igual o superior a la 4.5.8.
  • gethttpsforfree.com, en este caso se trata de un sitio web que nos permitirá generar nuestros certificados de forma manual. El código fuente del proyecto lo tenemos en: https://github.com/diafygi/gethttpsforfree

Y eso es todo, ya no hay escusas para no generar certificados validos para nuestros servidores y esperemos que el proyecto siga por el buen camino que ha tomado hasta el momento…

Comments

  1. Enrique

    Hola, muy buen artículo. Me queda una duda:
    El certificado generado me va perfecto con un dominio, pero ¿se podría también firmar digitalmente una aplicación software de escritorio? Me refiero que el instalador en Windows no haga saltar la típica pantalla naranja de la UAC «publicador desconocido».
    Gracias.

    1. B-Yo Article Author

      Hola Enrique, muchas gracias.

      No, los certificados generados con Let´s Encrypt son certificados TLS que sirven para los propósitos típicos de este tipo de certificados: servidores Web, servidores de correo electrónico… Ten en cuenta que lo que permiten este tipo de certificados es validar el domino (a parte claro esta de cifrar las comunicaciones). Por lo tanto no tienen sentido en la firma de software.

  2. José Rodríguez

    Hola muy buena ayuda, he estado batallando con esto de la generación de certificados SSL con letsencrypt y me ha dado algunos errores, me gustaría saber si me pueden ayudar

Deja un comentario

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