Migrando a HTTPS con Let’s Encrypt


Let’s Encrypt es la solución gratuita y confiable para obtener un certificado SSL / TLS que nos permite migrar nuestro sitio a HTTPS de manera fácil y rápida.

Let's Encrypt - Free SSL TLS Certificates

Con la creciente tendencia en sitios web en la adopción de protocolos cada vez más confiables, seguros y con encriptación más robusta, ha sido notoria la gran ola de sitios de todos tamaños migrando a HTTPS, además del empuje que Google le da al considerarlo un factor para el posicionamiento en su buscador.

Encrypt all the things

Anteriormente era común ver este tipo de certificados implementados solo en sitios de comercio electrónico o que de alguna manera requieren el manejo de información sensible, por lo que se consideraba esencial contar con las medidas de seguridad y encriptación necesarias para garantizar la integridad y buen manejo de los datos de sus usuarios.

El costo de estos certificados representaba una barrera para que sitios web de carácter informativo, pequeños negocios o blogs personales adoptaran esto como un estándar ya que se consideraba inviable al no tener un beneficio aparente o tangible, además de la carga y costos de infraestructura relacionados. Con las tecnologías actuales se ha demostrado que ya no representa un impacto en el desempeño de nuestro sitio web, además de la reciente liberación pública de Let’s Encrypt para la emisión de certificados de validación de dominio totalmente gratuitos en cuestión de segundos.

Let’s Encrypt is a new free certificate authority, built on a foundation of cooperation and openness, that lets everyone be up and running with basic server certificates for their domains through a simple one-click process.

Mozilla Corporation, Cisco Systems, Inc., Akamai Technologies, Electronic Frontier Foundation, IdenTrust, Inc., and researchers at the University of Michigan are working through the Internet Security Research Group (“ISRG”), a California public benefit corporation, to deliver this much-needed infrastructure.

En este tutorial te mostraré los pasos para obtener un certificado SSL gratuito y usarlo en tu servidor NGINX sobre Ubuntu. Además, explicaré algunos tips para optimizar tu servidor y aprovechar al máximo los beneficios de seguridad que esto te ofrece, así como algunos trucos para la renovación automática de tus certificados.

Si eres usuario Webinoly no es necesario realizar ninguna acción adicional, Let’s Encrypt ya se encuentra instalado en tu servidor y además facilitamos la creación de certificados para tu sitio con un solo comando sudo site domain.com -ssl-on. Puedes visitar la documentación oficial para consultar los detalles sobre la Creacion de Certificados SSL en Webinoly.

Instalar Let’s Encrypt

sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Obtener un certificado

sudo certbot certonly --webroot -w /var/www/example.com/htdocs/ -d example.com -d www.example.com --email user@example.com --agree-tos --staple-ocsp --must-staple

Es recomendable considerar la versión con y sin www de tu dominio al momento de generar el certificado como se indica en el ejemplo anterior, además de tener configurado la redirección del mismo.

Si se realizó de manera exitosa deberías ver el siguiente mensaje:

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/example.com/fullchain.pem. Your cert will expire on 2016-03-15. To obtain a new version of the certificate in the future, simply run Let's Encrypt again.
- Your account credentials have been saved in your Let's Encrypt configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Let's Encrypt so making regular backups of this folder is ideal.
- If 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

Consideraciones:

  • Asegúrate de que los puertos 80 y 443 no están bloqueados en tu firewall.
  • Durante la generación y obtención del certificado se generará la carpeta .well-known en la raíz de la carpeta de tu sitio web (htdocs) donde se guardara de manera temporal un archivo para validar el correcto acceso a tu servidor, por lo que debes asegurarte de que esta carpeta sea accesible de manera pública o no este bloqueado el acceso.
  • Los certificados generados y emitidos por Let’s Encrypt tienen validez por 90 días, después de este periodo debes generar uno nuevo ejecutando el mismo comando o puedes renovarlo. A continuación explicaré una manera práctica para realizar la renovación de manera automática.
  • Para hacer pruebas te recomiendo usar la opción --test-cert para generar certificados de prueba o la opción --dry-run para probar y ejecutar comandos de certbot sin generar ni guardar un certificado.

Además, te recomiendo consultar la Documentación Oficial y conocer la lista completa de comandos para administrar o hacer modificaciones a nuestros certificados. Cabe mencionar que dependiendo la versión y método de instalación de Let’s Encrypt lo pudieramos encontrar bajo el nombre de “certbot”, “certbot-auto” o “letsencrypt-auto”.

Renovación automática del certificado Let’s Encrypt

Los certificados generados y emitidos por Let’s Encrypt tienen validez por 90 días, por lo que es necesario renovarlos de manera constante. En el caso de los paquetes distribuidos en algunas distribuciones de Linux, como es el caso de Ubuntu, diariamente el sistema intentará renovar tus certificados de manera automática.

Si deseas renovar tus certificados de manera manual, solo debemos ejecutar el siguiente comando antes de la fecha de expiración:

sudo certbot renew

Cabe mencionar que este comando checará todos los certificados en el servidor para su posible renovación, por lo que no es necesario hacerlo de manera individual para cada dominio.

De manera redundante para garantizar y sobre todo recibir notificaciones sobre el estado actual de los certificados podemos ejecutar un cronjob de manera periodica.

sudo crontab -e

Y agregamos las siguientes lineas:

MAILTO=webmaster@example.com
30 2 * * 7 certbot renew

Con esto hemos creado un nuevo cronjob que ejecutará el comando todos los domingos a las 2:30am y si el certificado está a menos de 30 días de expirar lo renovará de manera automática y además recibirás un correo notificando la renovación o status del certificado.

Configuración de Let’s Encrypt en servidor Nginx

En la configuración del servidor NGINX añadimos el certificado obtenido en el paso anterior:

server {
   listen 443 ssl http2 default_server;
   listen [::]:443 ssl http2 default_server;
   ssl on;
   ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
   ssl_certificate_key     /etc/letsencrypt/live/example.com/privkey.pem;
}

Es muy recomendable redireccionar todo el tráfico HTTP hacia HTTPS:

server {
   listen 80 default_server;
   listen [::]:80 default_server;
   server_name www.example.com example.com;
   return 301 https://example.com$request_uri;
}

Finalmente, no olvidemos reiniciar NGINX.

sudo service nginx restart

Seguridad y optimización del servidor Nginx

Empezaremos con algunas configuraciones básicas para controlar la cantidad de recursos que SSL consume, así como ocultar la versión de NGINX.

server_tokens off;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;

OCSP Stapling

OCSP Stapling no hace tu servidor más seguro, pero definitivamente mejora los tiempos de respuesta entre el servidor y cliente. Esto funciona haciendo que el servidor al iniciar la comunicación SSL con el cliente envíe información almacenada en cache sobre el certificado y así evitar que el navegador del cliente tenga que realizar la verificación con un tercero.

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;

Con esto se remueve una gran porción de las solicitudes e información intercambiada.

HSTS: HTTP Strict Transport Security

Una de las mejores cosas que puedes hacer para mejorar la seguridad de tu sitio web es agregar HSTS a las cabeceras HTTP enviadas en cada respuesta de tu servidor. Esto le indica a los navegadores que tu sitio solo debe ser accesado con HTTPS, incluso cuando se envíe una solicitud HTTP será el navegador quien de manera automática realice la corrección a HTTPS.

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

HSTS se está convirtiendo cada vez más en un estándar, pero debe ser utilizado con mucha cautela y solo cuando estamos completamente seguros de que nuestro sitio solo utilizara HTTPS. Una vez que la cabecera HSTS se envía al navegador no se puede desactivar hasta que el valor “max-age” definido ha caducado.

Además, podemos dar de alta nuestro dominio en el sitio “HSTS Preload Submission” para ser agregado en las listas de los principales navegadores, así nuestro dominio será precargado como HSTS de manera predeterminada.

SSL Ciphers

Existe una gran cantidad de artículos en la web sobre la óptima configuración de los Ciphers de tu servidor, conforme se descubren nuevas vulnerabilidades estos cambian constantemente, además aquí es donde entra la batalla entre la seguridad y mantener compatibilidad con navegadores obsoletos cuando las estadísticas nos muestran que aún existe una gran base instalada de computadoras con Windows XP y versiones de Internet Explorer poco fiables para la época actual.

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256';

En resumen, debemos tomar en cuenta que a mayor seguridad obtendremos menor compatibilidad, pero lo más importante es no dejar los ciphers que vienen configurados por default. De manera general te recomiendo usar los Ciphers recomendados por Mozilla.

Intercambio de claves “DHE – dhparam”

NGINX usa de manera predeterminada algunos ciphers DHE (Ephemeral Diffie-Hellman) o en nuestra selección como vimos en la sección anterior podemos incluirlos, los cuales conllevan algunas debilidades en el cifrado que pueden ser prevenidas o corregidas fácilmente generando nuestras propias claves.

Desde la terminal ejecutamos el siguiente comando para generar una nueva clave:

sudo openssl dhparam -out /etc/ssl/dhparam.pem 2048

Una vez generada la clave la incluimos en la configuración del servidor:

ssl_dhparam /etc/ssl/dhparam.pem;

HTTP Headers

Algunas cabeceras HTTP recomendadas:

add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

Para más información sobre el uso de estas cabeceras ver el artículo “List of useful HTTP headers”.

De igual manera te recomiendo leer sobre el Referrer Policy Header y su impacto en tu estrategia SEO, ambos artículos muy interesantes para complementar tu implementación de certificados SSL. Ademas, un tema un poco más avanzado en seguridad sería la implementación de HPKP (HTTP Public Key Pinning).

Let’s Encrypt en WordPress Multisite

El siguiente ejemplo utiliza un mismo certificado Let’s Encrypt para diferentes sitios web, en este caso una instalación de WordPress Multisite con Domain Mapping.

Para generar el certificado utilizamos el mismo comando donde solo agregamos los dominios de los sub sitios con el parámetro “-d”, donde “example.com” sería el sitio principal y “subsite.com” y “another.com” serían los dominios mapeados.

sudo certbot certonly --webroot -w /var/www/example.com/htdocs/ -d example.com -d www.example.com -d subsite.com -d www.subsite.com -d another.com -d www.another.com --email user@example.com --agree-to --staple-ocsp --must-staples

La configuración del servidor NGINX quedaría de la siguiente manera:

server {
listen 80;
listen [::]:80;
server_name example.com www.example.com subsite.com www.subsite.com another.com www.another.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com subsite.com www.subsite.com another.com www.another.com;
ssl on;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT';
ssl_dhparam /etc/ssl/dhparam.pem;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
access_log /var/log/nginx/example.com.access.log rt_cache;
error_log /var/log/nginx/example.com.error.log;
root /var/www/example.com/htdocs;
index index.php index.html index.htm;
# WordPress nginx config rules
include common/php.conf;
include common/wpsubdir.conf;
include common/wpcommon.conf;
include common/locations.conf;
# Custom nginx.conf
include /var/www/example.com/conf/nginx/*.conf;
}
view rawnginx.confhosted with ❤ by GitHub

Otra manera de abordar la implementación de un certificado en una instalación WordPress Multisite con Domain Mapping, es mediante la creación de diferentes secciones server o Virtual Hosts en Nginx para cada dominio (alias); siempre apuntando el root hacia el sitio principal root /var/www/example.com/htdocs;, de esta manera podemos tener certificados individuales por cada dominio mapeado.

Conclusiones

Tu sitio web ahora funciona sobre HTTPS y puedes probar el nivel de seguridad y compatibilidad con el Test de Qualys SSL Labs.

Si deseas aprender más sobre como implementar SSL / TLS la documentación de Mozilla es un buen punto de inicio.

Ahora todos tus links internos deben empezar a usar HTTPS, paginas, imágenes, CSS, JS deben ser llamados con HTTPS, notarás que algunas páginas no se muestran de manera correcta debido a que algunos navegadores ahora bloquean el contenido que consideran inseguro, por lo que debes asegurarte de corregir y actualizar todos los enlaces necesarios, una herramienta que nos puede ayudar a detectar estos elementos es SSL Check de JitBit.

Límites de Let’s Encrypt. Si bien es probable que durante la implementación hagamos algunas pruebas, debemos asegurarnos de no generar demasiados certificados para el mismo dominio o IP durante este periodo, ya que Let’s Encrypt tiene límites en cuanto al número de certificados diarios que puede emitir para un mismo dominio o IP, esto con el único fin de garantizar la calidad del servicio.

Siempre habrá una lucha entre la seguridad y la compatibilidad con tecnologías un poco más antiguas, por lo que es importante considerar el impacto en la audiencia de nuestro sitio web que pueden tener los cambios en la configuración del servidor.

No todos los certificados son iguales, existen diferentes tipos de certificados para distintas necesidades. Let’s Encrypt solo emite certificados de Validación de Dominio y son gratuitos, pero también existen certificados de Validación Extendida que requieren validar una dirección postal de nuestro negocio por lo que su proceso de emisión es mas complejo y tienen un costo, su uso suele ser más idóneo en actividades de comercio electrónico o donde la validación de la existencia física de la marca o sitio web sea necesaria o aporte valor y confianza al usuario.


5 respuestas a “Migrando a HTTPS con Let’s Encrypt”

  1. Enhorabuena por el post. Me queda una duda, ¿sabes si podría utilizarse para firmar digitalmente una aplicación de escritorio? Por cierto mía y descargable desde mi mismo dominio. Gracias.

    • Hola Enrique.
      Muchas gracias por tu interés en este artículo. No tengo experiencia en el desarrollo de aplicaciones de escritorio, por lo que no podría responder a tu pregunta, pero dudo mucho que Let’s Encrypt pueda usarse para este proposito.
      De cualquier manera te invito a que si encontraras la manera de hacerlo, nos lo compartieras.
      Saludos.

Responder a caramiame Cancelar respuesta

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