Ya hace mucho tiempo que la Web se ha vuelto "segura", con la lista de sitios que utilizan HTTPS creciendo cada día y alcanzando un porcentaje muy alto del total.
Además de los sitios y aplicaciones que están en producción y utilizan HTTPS, el uso de conexiones seguras se está volviendo imprescindible también a la hora de desarrollar. El principal motivo es que cada día más APIs de HTML5 requieren el uso de HTTPS para poder funcionar. Por ejemplo, la API de geolocalización, la de notificaciones o la de service workers entre otras muchas. Debido a ello, si necesitamos desarrollar aplicaciones con ciertas características, no nos queda más remedio que utilizar también HTTPS en nuestros equipos de desarrollo para poder probar y afinar el código.
Hace poco os contaba cómo podías solucionar en parte esta necesidad gracias a una interesantísima herramienta llamada ngrok que lo que hace es exponer hacia Internet cualquier sitio web local, de modo que lo pruebas en tu máquina pero saliendo a Internet y volviendo a entrar en ella desde un dominio externo.
ngrok es una utilidad genial y con muchas aplicaciones, pero ¿no sería mejor para desarrollar poder probar directamente contra localhost
con HTTPS y sin necesidad de una vuelta tan grande? Es más, ¿no sería incluso mejor si pudiésemos desarrollar usando en local el mismo dominio que tendrá la aplicación final (o incluso uno inventado) con conexiones seguras incluidas?
Te voy a contar cómo puedes montar un entorno con estas características de manera sencilla en cualquier sistema operativo de escritorio (Windows, Mac y Linux).
El problema con los certificados HTTPS auto-firmados para localhost
Crear un certificado HTTPS para usar con el "dominio" localhost
es bastante sencillo de conseguir en la mayor parte de los servidores web que se usan en producción. Por ejemplo en nginx o en Apache en Linux o Mac gracias a OpenSSL y también en Windows con Internet Information Server.
Estos certificados en realidad no son válidos ya que no están firmados por una entidad certificadora de confianza (se auto-firman por la propia máquina local), y cuando nos conectamos a un sitio web local que los utilice, pasa esto:
Nos sale una advertencia del navegador y tenemos que desplegar una zona oculta y seguir adelante. Esto en Chrome. En Firefox es incluso más complicado. Una vez que lo aceptamos ya no vuelve a salir mientras no cerremos el navegador, pero tenemos el recordatorio constante en la barra de tareas de que el certificado no es válido:
Sería mucho mejor tener un certificado verdaderamente válido para localhost
. No solo eso, como decía antes, sería genial poder usar directamente el dominio real de la aplicación en local, y dotarlo de un certificado HTTPS válido también.
Vamos a ver cómo lograrlo gracias a una pequeña utilidad.
Crea tu propia entidad certificadora "virtual" con un solo comando
mkcert es una pequeña utilidad creada por el "crack" programador italiano Filippo Valsorda. Filippo ha trabajado en Cloudflare en programación relacionada con la criptografía, y actualmente está en Google en Nueva York en el equipo del lenguaje Go y en proyectos de seguridad y criptografía.
En junio de 2018 creó la utilidad llamada mkcert, que es gratuita y Open Source. mkcert permite crear certificados digitales para cualquier dominio, incluido localhost
, que son siempre válidos para usar en la máquina local.
Lo consigue usando un truco interesante: en lugar de generar certificados auto-firmados como los que hemos visto, crea una autoridad certificadora "virtual" local, que se añade a las entidades raíz de confianza del sistema. Los certificados que genera van firmados por esta autoridad local, y como el sistema confía en ellos, tu navegador los ve como un certificado normal y corriente y muestra el iconito del candado de confianza. Fuera de tu máquina no valdrán para nada, pero en local son certificados de tanta confianza como cualquier otro. Justo lo que queremos para poder desarrollar en local sin problema.
¡Estupendo, vamos a probarlo!
Instalando la entidad certificadora "virtual" con mkcert
El uso de mkcert no podría ser más sencillo. Lo único que hay que hacer es descargar el ejecutable apropiado para tu sistema operativo desde la zona de "releases" del proyecto en Github. Por ejemplo, en mi caso la versión para Windows:
Este ejecutable es ya el programa. No tiene dependencias ni necesita instalación. Es descargar y usar, lo cual es muy de agradecer. Eso sí, por sencillez de uso yo le cambio el nombre por defecto (que tiene la plataforma y la versión) y le dejo simplemente mkcert.exe
. Cópialo a una carpeta donde lo tengas a mano para cuando lo necesites.
Para utilizarlo debes abrir una línea de comandos en Windows, o un terminal si estás en Mac o Linux. Ni siquiera necesitas elevar los privilegios para usarlo.
OJO: en Windows la protección de seguridad Smart Screen, al no identificar el programa, saca un aviso de que puede ser peligroso utilizarlo. Lo puedes ejecutar igual pulsando sobre el enlace y luego sobre la opción de continuar de todos modos:
Si lo pasas por VirusTotal refrendará que es un programa inocuo:
Lo primero que debes hacer es instalar la entidad certificadora "virtual" que se usará para gestionar los certificados. Esto solo tienes que hacerlo una vez, luego ya no vuelve a ser necesario. Para ello escribe:
mkcert -install
Y el sistema te mostrará un aviso de seguridad indicándote de que se va a instalar un certificado raíz de confianza para tu entidad certificadora. Aceptas y listo.
En Windows puedes comprobar que el certificado raíz está instalado haciendo lo siguiente:
- Busca la utilidad
mmc.exe
(la Microsoft Management Console) y ejecútala (necesitarás privilegios de administrador).
- Añade el complemento de certificados para el usuario actual desde el menú
Archivo
tal y como se muestra en esta animación:
3- Si ahora vas al nodo Trusted Root Certificate Authorities
y ves los certificados, verás uno cuyo nombre empieza por "mkcert", que es el de la autoridad raíz virtual. Si haces doble-clic sobre él para examinarlo verás que su utilidad es la de firmar certificados:
¡Genial, todo correcto! Ahora vamos a generar un certificado, que es lo que necesitamos.
Generando certificados con mkcert
Hacerlo es muy sencillo: basta con ejecutar mkcert seguido del nombre o nombres de dominio para los que queremos generar certificados. Por ejemplo, para un certificado válido para localhost
:
mkcert localhost
Esto genera por defecto un certificado digital y un archivo de clave privada en formato PEM, muy común y que contiene la información en formato de texto codificada como Base64.
Este tipo de certificados son los más comunes en servidores en Mac o Linux y será lo que necesitas si estás en estos sistemas o si usas Apache o nginx. Sin embargo, para Windows deberías generar el certificado en formato PKCS 12, que guarda la información protegida con una contraseña. Para ello solo tienes que usar el parámetro -pkcs12
, así:
Esto generará el certificado digital en un único archivo con extensión .p12
que ya contiene tanto el certificado como la clave privada para encriptación.
Del mismo modo que lo haces para localhost
, también puedes generar certificados para cualquier otro dominio, de modo que luego puedas simular que tu servidor local es dicho dominio, y así desarrollar, incluso, usando el dominio final que tendrá la web o la aplicación:
mkcert www.dominio.com otrodominio.es localhost
Como ves, se pueden especificar varios dominios en el mismo comando y se generará un único certificado para todos ellos.
Con esto conseguiremos disponer de certificados HTTPS que nos valen exactamente igual que certificados reales, solo que será nuestra máquina la única que los de por válidos.
Gracias a ellos podremos desarrollar en local del mismo modo que si estuviésemos trabajando contra el servidor real, lo cual es una gran ventaja.
Nota importante: aunque los certificados funcionan sin problema con los navegadores basados en Blink/Webkit como Chrome, Opera o Safari, Firefox no usa el registro de certificados del sistema, sino uno propio. Por lo tanto en Firefox no te funcionará de entrada. Para solucionarlo solo tienes que importar el certificado raíz de mkcert a Firefox. Puedes hacerlo con la utilidad de línea de comandos de Firefox, certutil, o más fácilmente a mano (ya que solo hay que hacerlo una vez) yendo a las opciones de seguridad de este navegador y en "Ver certificados" pestaña autoridades, importarlo allí desde tu carpeta de ajustes de aplicaciones para el usuario actual, como se ve en esta pequeña animación:
Ahora lo único que nos faltaría es incorporarlos a la lista de los certificados de la máquina y asignarlos a un sitio web. Esto dependerá de tu sistema operativo y del servidor web que utilices.
En mi próximo post te explicaré cómo puedes usar estos certificados con Internet Information Server Express (IIS Express) en Windows, que no es una cosa muy directa que digamos.
Si te interesa, en este vídeo te explico cómo usar mkcert en combinación con Visual Studio Code y Live Server para montar sin dificultad un servidor de desarrollo local en tu equipo fácil de usar:
¡Espero que este post te haya resultado útil!