¿Has bajado el sitio? Lo que un certificado SSL caducado me enseñó sobre HTTPS
Tengo una jornada de 08:30 horas hasta las 17:30 horas, a eso de las 16:45 hrs me llega un mensaje por interno de un trabajador en otra…
¿Has bajado el sitio? Lo que un certificado SSL caducado me enseñó sobre HTTPS
Tengo una jornada de 08:30 horas hasta las 17:30 horas, a eso de las 16:45 hrs me llega un mensaje por interno de un trabajador en otra región “Oye! ¿has bajado el sitio?” y comencé a sentir los síntomas de un preinfarto.
Inmediatamente ingresé al sitio web de la organización y me encuentro con un mensaje en pantalla que no quería ver nunca, “Su navegación no es segura”, esto solo significaba una cosa, el certificado SSL del sitio web había caducado, o bien se había corrompido por alguna acción indeseada.
Comencé una búsqueda incesante. Abrí la configuración de nginx y encontré las rutas de los certificados, había archivos .old junto a los archivos .pem correctos, modificados hacía no más de cinco minutos. El administrador los había renovado.”
Uno está pendiente de la arquitectura del sistema, de los bugs del desarrollo, que no quedes sin recursos de memoria o CPU y francamente, esto era esos “pendientes” que uno tiene en la vida de desarrollador de que va a aprender sobre esta temática, pero que nunca llegaba ese momento, y la verdad es que me llegó duro, no tenía idea que era lo que había ocurrido, más allá de lo superficial que uno pueda entender.
¿Qué es HTTP y por qué existe HTTPS?
Para entender lo que me pasó ese día, es necesario entender como funciona la web, quizás hay muchos sitios que te muestran como los datos se transmiten desde un servidor hasta tu navegador en la casa, son técnicos (aunque necesario) y a veces no se comprenden muy bien, la idea es que voy a intentar explicarlo de la forma mas sencilla y didáctica posible.
HTTP: Hyper Text Transfer Protocol
Este protocolo permite la transferencia de datos entre dos hosts, mayoritariamente es utilizado para transacciones que tienen que ver con mostrar páginas web en HTML (Hyper Text Markup Language), pero también es utilizado para cuando utilizas API (Application Programming Interface) para obtener datos desde una base de datos o comunicacion entre servicios, por convención se utiliza el puerto 80, aunque puede ser modificado facilmente cuando configuras el servidor que utilizas para servir este tipo de protocolo (Apache, Tomcat, Nginx, etc).
La mayor desventaja que tiene HTTP, es que es un protocolo que solo transporta información en texto plano, sin ningún tipo de seguridad en caso de que seas víctima de un ataque MITM (man in the middle).
Es aquí donde comenzamos con la historia de HTTPS, que corresponde al mismo protocolo del que ya hemos hablado, añadiéndole una capa de seguridad encriptando la información que traslada y cambiando el puerto de comunicación al 443.
Entonces, que significa la “s” en https y donde entra en juego SSL?
Vamos con lo simple primero, la “S” solo significa secure, es decir, se le agrega la capa de seguridad al protocolo HTTP para que la información que es entregada por ese medio viaje encriptada y segura de ataques de hombre en el medio, quienes pudieran interceptar la información que viaja y mal utilizarla de alguna forma, como por ejemplo, hacerse pasar por usuarios validados en el sistema.
Pero la “S” no es que se pueda llegar y configurar en un archivo de texto en el servidor web que se esté utilizando, esto se obtiene a través de la emisión de un certificado de confianza, que indica que la conexión establecida entre un host y el servidor es válida y dando fe de que se está conectando a la url que el usuario a colocado en la barra de navegación del explorador de internet que este utilizando.
¿Cómo se obtiene ese certificado?
Aqui es donde entramos en un terreno más árido, pero no incomprensible. Para que exista una conexión segura entre un host y un servidor web, previamente el administrador del sistema debió configurar el dominio FQDN dentro del servidor, ya sea en Apache, Nginx, Caddy, etc. Depende de la herramienta que ha utilizado en este efecto es como se produce la obtención del certificado. En este artículo vamos a ver cómo se aplica en Nginx, el servidor web más usado en internet con cerca del 38% del mercado, y en Caddy, una alternativa moderna que aunque tiene menor adopción masiva, está ganando terreno rápidamente en proyectos nuevos gracias a su gestión automática de certificados.
Pero antes de que obtengamos el certificado, es importante responder las siguientes preguntas:
¿ Que es un certificado ?
Un certificado es un documento digital que contiene tres elementos: la identidad del sitio (el FQDN para el que fue emitido), la clave pública del servidor, y la firma digital de la CA que lo emitió. La clave privada es un archivo separado que vive en el servidor y nunca se comparte con nadie.
¿ Quien lo emite ?
El certificado es emitido por una CA (Certificate Authority) o Autoridad Certificadora, quien mediante un procedimiento con el servidor verifica que el solicitante controla el dominio FQDN indicado. Una vez verificado, emite un certificado firmado con la clave privada de la CA, que contiene la clave pública del servidor, el dominio para el que fue emitido, y una fecha de expiración. Cuando un browser recibe este certificado, verifica la firma de la CA localmente, sin realizar consultas a terceros, usando la lista de CAs de confianza que viene preinstalada en el sistema operativo o en el propio navegador, dependiendo del browser que se utilice.
El almacén de CAs puede estar en el sistema operativo, como ocurre en Windows con Chrome y Edge, o en macOS con Safari y Chrome, o puede ser interno al propio browser, como hace Firefox en todos los sistemas operativos, manteniendo su propia lista independiente.
¿ Cómo se obtiene ?
Antes de que mostremos código o comandos de instalación es importante conocer el flujo en la obtención del certificado, este proceso consta, genéricamente, de los siguientes pasos:
1- El servidor genera su propio par de claves (privada y pública).
2- Le pides a una CA un certificado para tu FQDN.
3- La CA verifica que el servidor controla el dominio mediante ACME challenge.
4- La CA emite el certificado que contiene:
- El FQDN. - La clave pública del par de claves del servidor.
- La firma de la CA.
5- El certificado obtenido se instala en el servidor.

Algo que se comentó en los pasos es el ACME challenge y este consiste en que la CA le solicita al servidor que coloque un archivo en la ruta http://misitio.cl/.well-known/acme-challenge/TOKEN_ALEATORIO, y la CA, en caso de poder ingresar al sitio requerido, procede a firmar el certificado ya que se garantiza el dominio del FQDN.
¿ Cómo se configura ?
Hasta que por fin llegamos al momento que nos gusta a todos, meter las manos en la consola y es aquí donde se explicarán dos grandes contrastes, el enfoque manual y flexible de Nginx, con la simplicidad y automatización de Caddy, dos grandes herramientas, una con mayor cuota de uso que la otra, pero que no por eso podemos ignorar el hecho de que podemos ver el mismo problema, con una solución totalmente diferente una de otra.
NGINX
Con Nginx primero debemos instalar un cliente ACME en el servidor, en este caso hablamos de certbot, que es el mas conocido y utilizado:
# Instalar certbot
sudo apt install certbot python3-certbot-nginx
Posteriormente le damos la instrucción a Certbot que solicite el certificado para el sitio
# 2. Obtener e instalar el certificado
sudo certbot --nginx -d misitio.cl
Es importante que sepas, que cuando instalaste certbot, el sistema automáticamente configuró un timer como servicio en el sistema, lo cual puedes comprobar de esta manera:
# 3. Verificar renovación automática
sudo systemctl status certbot.timer
Finalmente, para verificar que todo ha sido instalado correctamente, puedes verificar el archivo de configuración de Nginx que debiera mostrar lo siguiente:
server {
listen 443 ssl;
server_name misitio.cl;
ssl_certificate /etc/letsencrypt/live/misitio.cl/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/misitio.cl/privkey.pem;
location / {
proxy_pass http://localhost:3000;
}
}
CADDY
Caddy es un servidor web open source escrito en Go, creado por Matt Holt y lanzado en 2015 mientras estudiaba en la universidad. Su motivación era simple: hacer que HTTPS fuera automático y sin fricción. Fue el primer servidor web en implementar HTTPS automático usando Let’s Encrypt, algo que Nginx y Apache todavía no hacen nativamente. En 2020 lanzó Caddy 2, una reescritura completa con arquitectura más flexible.
Para instalarlo, configurarlo y ponerlo en marcha, te lo explico acá:
# Instalar dependencias
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
# Agregar el repositorio oficial de Caddy
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
| sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
| sudo tee /etc/apt/sources.list.d/caddy-stable.list
# Instalar Caddy
sudo apt update && sudo apt install caddy -y
Para verificar que Caddy esté corriendo correctamente:
sudo systemctl status caddy
Ahora, ya que tenemos instalado y funcionando Caddy, podemos editar el archivo de configuración y habilitar nuestro sitio:
# Abrimos el archivo de configuración
sudo nano /etc/caddy/Caddyfile
Habilitamos nuestro sitio con esta simple directiva:
misitio.cl {
reverse_proxy localhost:3000
}
Salimos y guardamos la configuración modificada y recargamos el archivo de configuración
sudo systemctl reload caddy
Y con esto obtenemos todo este flujo de trabajo:
→ Genera el par de claves
→ Hace el ACME challenge con Let's Encrypt
→ Obtiene el certificado
→ Lo instala
→ Redirige HTTP → HTTPS automáticamente
→ Renueva el certificado 30 días antes de que expire
¿Cómo evitar que te pase lo mismo?
Volviendo al inicio de esta historia, el certificado caducó a las 16:45 y nadie lo supo hasta que un usuario en otra región lo reportó. El problema no fue técnico, fue de proceso: sin monitoreo y sin automatización, dependes de que alguien recuerde renovar a tiempo.
Si usas Caddy, ya tienes el problema resuelto, renueva automáticamente 30 días antes de que expire. Si usas Nginx con certbot, el timer que se instala automáticamente también lo cubre. Pero si tu situación es como la mía, un certificado emitido por una CA privada institucional, renovado manualmente por un administrador de sistemas, necesitas al menos una alerta temprana.
La herramienta más simple para esto es UptimeRobot (uptimerobot.com), que en su plan gratuito monitorea el vencimiento de tu certificado y te manda un email con anticipación. No requiere acceso al servidor, es externa, y toma cinco minutos configurar.
Si tienes acceso SSH al servidor, también puedes verificar cuántos días le quedan a tu certificado con este comando:
echo Q | openssl s_client -connect misitio.cl:443 2>/dev/null \
| openssl x509 -noout -dates
El campo notAfter te muestra la fecha exacta de expiración.
La lección que me dejó ese día no fue técnica, fue de criterio. Un certificado caducado no es un fallo del sistema, es un fallo del proceso. Y los fallos de proceso se resuelven con automatización o con monitoreo. Idealmente con ambos.
¿Qué viene después?
Existe un tercer escenario que no cubrimos en este artículo: las CA privadas, utilizadas en redes internas donde los dominios no son accesibles desde internet público — como los sistemas de intranet institucionales con PKI propia. Lo abordaremos en detalle en un próximo artículo.
메타데이터
- post_id
- 383e8aa91d2a
- slug
- has-bajado-el-sitio-lo-que-un-certificado-ssl-caducado-me-enseñó-sobre-https-383e8aa91d2a
- url
- https://medium.com/@enzo.ramirezs/has-bajado-el-sitio-lo-que-un-certificado-ssl-caducado-me-ense%C3%B1%C3%B3-sobre-https-383e8aa91d2a
- canonical_url
- https://medium.com/@enzo.ramirezs/has-bajado-el-sitio-lo-que-un-certificado-ssl-caducado-me-ense%C3%B1%C3%B3-sobre-https-383e8aa91d2a
- author_url
- https://medium.com/@enzo.ramirezs
- status
- ok
- fetched_at
- 2026-06-21 07:44:09