Imagina: ayer tu scraper a través de proxy funcionaba perfectamente, los registros limpios, las métricas en verde. Hoy por la mañana abres el panel y ves una pared de errores: certificate is not yet valid, token expired, signature does not match. El primer pensamiento del ingeniero es predecible: el proxy se rompió, el proveedor hizo algo, hay que cambiar el pool. Pasas horas diagnosticando la red, cambias endpoints, escribes al soporte. Y la causa estuvo todo el tiempo justo delante de tus narices, marcando mal. Es el reloj del sistema.

La desincronización de la hora es una de las fuentes de fallos más subestimadas en infraestructuras que operan a través de proxy. Es traicionera porque se disfraza de problemas de red y de certificados. Ves la palabra certificate en el error y por reflejo vas a revisar TLS, aunque el certificado está perfectamente vivo y válido. Simplemente tu máquina cree que hoy es otro día.

En esta guía desglosaremos el tema de la A a la Z. Sabrás exactamente dónde está embebida la hora en la criptografía y los protocolos, cómo se ven los errores concretos en curl, Python y Node, por qué los relojes se desvían en máquinas virtuales y contenedores, cómo diagnosticar en un minuto y cómo configurar la sincronización para que realmente funcione y no sea solo un adorno instalado. El material fue escrito por ingenieros de Proxeon a partir del análisis de incidentes reales. Aclaramos por separado: no se trata de la emisión de certificados ni de su estructura, solo de la hora como causa de fallos.

Fundamentos: por qué la hora forma parte del protocolo y no es solo un número en pantalla

Empecemos por lo fundamental. Muchos perciben la hora del sistema como una convención puramente humana: saber que son las 14:30 resulta útil. Pero en el mundo de los protocolos de red, la hora es un participante activo en las verificaciones de seguridad. Está integrada en la lógica de validación en varios niveles a la vez.

Cuando dos nodos establecen una conexión segura o intercambian mensajes firmados, necesitan distinguir datos frescos de datos obsoletos. Sin la noción de tiempo es imposible responder preguntas simples: ¿este certificado ya expiró? ¿este token se venció? ¿un atacante está repitiendo una solicitud antigua interceptada? Por eso los protocolos incorporan marcas temporales y ventanas de validez.

Qué es la hora del sistema y de dónde viene

En cualquier sistema operativo hay dos conceptos relacionados. El primero son los relojes de hardware (RTC, real-time clock), un chip con su propia alimentación por batería que sigue marcando incluso con el equipo apagado. El segundo es el reloj del sistema, que el núcleo del SO mantiene en memoria RAM, partiendo del valor del RTC al arrancar y ajustando a medida que opera.

El problema es que el oscilador de cuarzo de cualquier hardware no es perfecto. Se adelanta o se atrasa fracciones de segundo por día. Esto se llama deriva del reloj. En una semana sin corrección se acumulan segundos perceptibles, y en algunos entornos virtuales, minutos enteros. Para combatir la deriva se creó el protocolo de sincronización de hora por red. El demonio de sincronización consulta periódicamente la hora exacta de servidores de referencia y ajusta suavemente el reloj local.

UTC, zonas horarias y por qué importa para el proxy

Un dato clave para principiantes: toda la criptografía de red seria trabaja en UTC, tiempo universal coordinado, sin ataduras a zonas horarias. Certificados, JWT, firmas de solicitudes: todo opera con instantes de tiempo en UTC. La zona horaria es solo cosmética para mostrársela a las personas.

Esto significa que si configuraste mal la zona horaria pero la hora absoluta (en UTC) es correcta, la criptografía no sufrirá. Pero si lo que está mal es la hora absoluta, todo se descuadra. Una confusión habitual: el ingeniero ve una hora local extraña en los registros, se pone a arreglar la zona horaria, y la raíz del problema está en otro lado. Recuerda la distinción: la zona horaria afecta la visualización, la hora absoluta en UTC afecta las verificaciones.

Cómo entra el proxy en este panorama

Cuando trabajas a través de proxy, aparece un nodo adicional en la ruta de la solicitud. Pero es importante entender: el proxy, en la mayoría de los escenarios, no cambia ni sustituye la hora en tus verificaciones criptográficas. El handshake TLS con el servidor destino, la verificación de la vigencia del certificado, la validación del token: todo esto ocurre de tu lado o del lado del servidor final. El proxy solo transmite bytes.

De ahí la paradoja: trabajar a través de proxy no crea el problema de la hora, pero vuelve sus síntomas más confusos. El ingeniero ve la cadena cliente - proxy - servidor y naturalmente sospecha del eslabón intermedio. Y resulta que la culpable es la máquina local, donde el reloj va mal. Lo llamamos el efecto de sospecha desplazada: cuanto más larga es la cadena, más fácil es culpar al medio y no a los extremos.

Inmersión profunda: dónde es crítico exactamente el tiempo

Ahora bajemos más y analicemos los puntos concretos donde la hora incorrecta se convierte en fallo. Son cuatro, y cada uno merece atención aparte.

Verificación de vigencia del certificado en TLS

Cada certificado TLS contiene dos campos: notBefore (no válido antes de) y notAfter (no válido después de). Son los límites de la ventana de validez. Cuando tu cliente establece una conexión segura, recibe el certificado del servidor y verifica: ¿cae la hora actual dentro de esa ventana?

Y aquí está el punto clave: por hora actual se entiende la hora en tu máquina. Si tu reloj va atrasado y muestra una fecha anterior a notBefore, el cliente decidirá que el certificado aún no ha entrado en vigor. Error del tipo certificate is not yet valid. Si el reloj se adelantó más allá de notAfter, el certificado ya expiró para ti, aunque para el resto del mundo esté fresco. Error certificate has expired.

Los certificados de vida corta son especialmente traicioneros. La práctica moderna tiende a certificados de 90 días o menos, y para 2026 la industria discute reducir los plazos a 45 días o incluso menos. Cuanto más corta la ventana de validez, menor el margen de tolerancia frente a relojes desviados. Antes, una desincronización de una hora era casi imperceptible frente a un certificado anual. Ahora, la ventana estrecha significa que incluso un desfase de varias horas cerca del límite de renovación puede tumbar la conexión.

JWT: campos exp, nbf e iat

JSON Web Token es un formato popular de tokens de autorización. Dentro de él viven campos temporales que se verifican en cada uso del token:

  • exp (expiration time): el momento tras el cual el token se considera vencido.
  • nbf (not before): el momento antes del cual el token aún no es válido.
  • iat (issued at): cuándo se emitió el token.

Los tres son timestamps Unix en segundos desde la época, es decir, hora absoluta en UTC. Cuando el servidor recibe el token, compara esos campos con su propio reloj. Cuando tu cliente decide si debe renovar el token, mira exp respecto a su propio reloj.

El escenario de fallo es elegante en su maldad. Supongamos que el reloj de tu cliente se adelantó diez minutos. El servidor emitió un token con vida de cinco minutos. Tu cliente, viendo su reloj adelantado, considera al instante que el token fresco ya está vencido y o bien no lo envía, o bien lanza un ciclo infinito de renovación. La situación inversa: si nbf está desviado respecto a tu reloj, obtendrás token used before issued o token not yet valid.

Firmas de solicitudes con marca temporal

Muchas APIs exigen que cada solicitud esté firmada, y en la firma se incluye una marca temporal. El ejemplo clásico son los esquemas de firma HMAC, donde el cliente arma una cadena con el método, la ruta, el cuerpo y el timestamp actual, y luego la firma con una clave secreta. El servidor repite el cálculo y compara las firmas.

Aquí la hora juega un doble papel. Primero, el timestamp entra en la cadena firmada, así que el servidor debe usar exactamente el mismo timestamp que envió el cliente: lo toma de la cabecera. Segundo, el servidor verifica que ese timestamp no esté demasiado lejos de su propia hora. Normalmente se admite una ventana de varios minutos como protección contra la repetición de solicitudes antiguas.

Si el reloj del cliente se sale de esa ventana, el servidor rechazará la solicitud como demasiado antigua o proveniente del futuro. Errores del tipo request timestamp too skewed, signature expired o el genérico signature does not match. Y precisamente por la hora, muchas veces ves un error de firma y no un error de tiempo: el servidor no siempre admite con honestidad que el problema es el reloj.

Códigos de un solo uso y contraseñas temporales

Una categoría aparte son los códigos de un solo uso basados en tiempo (TOTP), usados en autenticación de dos factores para acceder a paneles de control y consolas de API. Ese código se calcula a partir de un secreto compartido y la hora actual, dividida en intervalos normalmente de 30 segundos. Ambas partes calculan el código de forma independiente y lo comparan.

Si el reloj del cliente está desviado más de uno o dos intervalos, los códigos dejarán de coincidir. Introducen un código recién generado y el sistema dice que es incorrecto. La gente en esa situación culpa a la app generadora o entra en pánico pensando en un hackeo, cuando bastaba con mirar el reloj. La tolerancia aquí es muy estrecha, decenas de segundos, por eso el TOTP funciona tan bien como indicador de desincronización.

Cómo se ve el error en distintos clientes

La teoría es la teoría, pero el ingeniero vive en la terminal leyendo mensajes de error. Analicemos cómo se manifiesta la desincronización en herramientas populares. Esto te ayudará a reconocer el síntoma al instante.

curl

Al trabajar con TLS a través de curl, un reloj desviado produce mensajes característicos. Si la hora va atrasada y el certificado aún no ha entrado en vigor según tus relojes:

curl: (60) SSL certificate problem: certificate is not yet valid

Si la hora se adelantó y el certificado, según tus parámetros, ya expiró:

curl: (60) SSL certificate problem: certificate has expired

Un detalle útil: el código de error 60 se refiere a problemas de verificación del certificado. Un ingeniero inexperto ve la palabra certificate y va a revisar el certificado mismo con un comando de visualización, comprueba que las fechas de validez están bien y queda perplejo. La clave está en que las fechas del certificado se comparan con tu hora local. Prueba un ejemplo a través de proxy:

curl -x http://user:pass@gateway.proxeon.net:8080 -v https://api.example.com/status

Si en la salida con -v ves líneas sobre la verificación de fechas del certificado y luego un error de validez, lo primero es comparar date -u con la referencia, no sospechar del gateway.

Python (requests y httpx)

En Python, sobre el stack TLS estándar, un reloj desviado lanza una excepción durante el handshake:

requests.exceptions.SSLError: HTTPSConnectionPool(host='api.example.com', port=443): Max retries exceeded (Caused by SSLError(SSLCertVerificationError("certificate verify failed: certificate is not yet valid")))

Fíjate en la cola del mensaje: certificate is not yet valid. Es el mismo síntoma temporal. Al trabajar con JWT el panorama es distinto: no hay errores TLS, pero la librería de validación de tokens lanzará una excepción específica:

jwt.exceptions.ImmatureSignatureError: The token is not yet valid (nbf)

o

jwt.exceptions.ExpiredSignatureError: Signature has expired

Aquí la palabra signature confunde: parece que el problema está en la firma criptográfica. En realidad, expired apunta justamente al campo exp y a tu reloj. Una verificación rápida de la hora directamente desde el código:

import time, datetime; print(datetime.datetime.utcnow(), int(time.time()))

Compara el timestamp Unix obtenido con el de referencia: una discrepancia de más de un par de segundos ya es sospechosa.

Node.js

En Node los errores TLS vienen con códigos. Para la desincronización son característicos:

Error: certificate is not yet valid\ncode: 'CERT_NOT_YET_VALID'

y

Error: certificate has expired\ncode: 'CERT_HAS_EXPIRED'

Los códigos CERT_NOT_YET_VALID y CERT_HAS_EXPIRED son señaladores directos. Si ves el primero con un certificado vivo, tu reloj va atrasado. Si ves el segundo con un certificado claramente fresco, tu reloj va adelantado. Al trabajar con librerías JWT en Node obtendrás errores con nombres como TokenExpiredError y NotBeforeError. Verificación rápida:

node -e "console.log(new Date().toISOString(), Math.floor(Date.now()/1000))"

Tabla resumen de síntomas

Reunamos los patrones en un solo mapa mental:

  • certificate is not yet valid / CERT_NOT_YET_VALID: el reloj va atrasado.
  • certificate has expired / CERT_HAS_EXPIRED con un certificado fresco: el reloj va adelantado.
  • token not yet valid / nbf / ImmatureSignature: el reloj va atrasado respecto al servidor emisor.
  • token expired / ExpiredSignature justo tras recibir el token: el reloj va adelantado.
  • signature does not match / timestamp too skewed: el reloj se salió de la ventana de tolerancia del servidor.
  • Código TOTP incorrecto de forma persistente: el reloj está desviado decenas de segundos o más.

Por qué se desvían los relojes: anatomía de la deriva

Entender la causa es la mitad de la solución. Analicemos por qué en la infraestructura moderna los relojes se desvían más de lo que parece. Especialmente en servidores y nodos de trabajo por donde pasas tráfico de proxy.

Máquinas virtuales y congelación

Una máquina virtual no tiene acceso directo al cuarzo físico. Su noción del tiempo es una abstracción que mantiene el hipervisor. Normalmente todo va bien mientras la VM opera de forma continua. Pero basta con que el hipervisor pause la máquina para que empiecen las sorpresas.

El escenario clásico es la congelación y los snapshots. El hipervisor pausa la VM, por ejemplo para migración o respaldo. Dentro del huésped, el tiempo se detiene. Cuando se descongela la máquina, su reloj del sistema va atrasado exactamente la duración de la pausa. Si fue un minuto, obtuviste un desfase de un minuto al instante, de golpe. Para tokens de vida corta y ventanas estrechas de firma, esto es fatal.

Peor aún es restaurar desde un snapshot antiguo. La máquina revive con la hora del momento en que se tomó el snapshot: pueden ser horas o días en el pasado. TLS empezará de inmediato a rechazar certificados como aún no válidos. Muchas plataformas de nube ofrecen agentes de huésped que ajustan la hora tras la descongelación, pero no siempre están ni funcionan.

Contenedores

Con los contenedores la historia es más sutil. Un contenedor no tiene relojes del sistema propios: usa el núcleo del host y, por tanto, la hora del host. Eso es una buena noticia: si el host está sincronizado, el contenedor ve la hora correcta automáticamente.

La mala noticia está en los matices. Primero, dentro del contenedor normalmente no se puede cambiar la hora del sistema: no tiene los privilegios necesarios, y eso está bien. Segundo, y esto es importante, dentro del contenedor a menudo no existe un demonio de sincronización, y es normal: debe sincronizar el host. El problema surge cuando el host no está sincronizado y tú no lo notas, porque estás acostumbrado a que en el portátil del desarrollador todo esté sincronizado de fábrica.

Ausencia de demonio de sincronización

La causa más banal y más común. En imágenes mínimas de servidores el demonio de sincronización puede no estar instalado o no estar corriendo. La máquina arranca, toma la hora del RTC y luego vive sobre un cuarzo a la deriva sin corrección. Día tras día el desfase se acumula.

Son especialmente peligrosas las imágenes construidas a mano o clonadas. El ingeniero configuró todo en una máquina de referencia, sacó la imagen, la desplegó en cien nodos, y el demonio de sincronización no está activado allí. Cien nodos empiezan a divergir silenciosamente, cada uno por su lado. Mientras el desfase es pequeño, todo funciona. Una semana después, los cuarzos más rápidos se salen de la ventana de tolerancia y obtienes fallos flotantes, no reproducibles, en parte del parque.

Edición manual y RTC pegado

A veces el tiempo lo rompe una persona. Alguien puso la fecha a mano para una prueba y olvidó devolverla. Alguien desactivó la sincronización porque le estorbaba en un experimento concreto. Un problema aparte es la batería agotada del RTC en un servidor físico: tras el reinicio el reloj vuelve a un pasado lejano y, hasta la primera sincronización, TLS no funciona en absoluto.

Doble gestión del tiempo

Un caso sutil del que se olvidan. A veces compiten dos mecanismos por el tiempo: el agente de huésped del hipervisor y el demonio de sincronización dentro del SO. Tiran del reloj en direcciones opuestas y obtienes oscilaciones de hora de un lado a otro. Se manifiesta como fallos intermitentes imposibles de atrapar. La regla es simple: por el tiempo debe responder exactamente un mecanismo.

Diagnóstico en un minuto: llegar al veredicto rápido

Pasemos a la práctica. Tu objetivo es entender en sesenta segundos si la culpa es de la hora. Aquí tienes el framework paso a paso que usamos en Proxeon al analizar incidentes.

Paso uno: mira tu hora en UTC

Lo primero es saber qué piensa tu reloj, precisamente en UTC, para excluir confusiones con la zona horaria:

date -u

Anota el valor. Ahora compáralo con la referencia.

Paso dos: compara con una fuente externa

La forma más confiable es preguntarle la hora a un servidor de tiempo por red y ver el desfase. Si tienes chrony instalado:

chronyc tracking

En la salida busca la línea System time: muestra el desfase del reloj del sistema respecto a la referencia. Un valor como 0.000030 seconds es lo ideal. Si es systemd-timesyncd:

timedatectl show-timesync --all | grep -i offset

Otro truco rápido es una consulta puntual al servidor de tiempo sin cambiar el reloj:

chronyd -Q 'server pool.ntp.org iburst'

Imprimirá la corrección estimada. Si su módulo es grande, ahí tienes la respuesta.

Paso tres: verifica mediante la cabecera HTTP Date

Un truco que ahorra muchísimo tiempo. Casi cualquier servidor web devuelve en la respuesta la cabecera Date con la hora actual en UTC. Compárala con tu reloj directamente a través de tu proxy:

curl -sI -x http://user:pass@gateway.proxeon.net:8080 https://example.com | grep -i ^date

Compárala con date -u. Si la diferencia es de segundos, todo bien. Si es de minutos, ahí está la causa. La belleza del método es que no requiere demonios instalados y funciona incluso dentro de un contenedor pelado donde no hay nada más que curl.

Qué dispersión se considera normal

Referencias prácticas forjadas por la experiencia:

  • Hasta 1 segundo: excelente, no hay nada que hacer. Un sistema sano y sincronizado mantiene fracciones de segundo.
  • 1-5 segundos: aceptable para TLS y la mayoría de JWT, pero ya es zona de atención. Las firmas de solicitudes y el TOTP aún aguantan, pero el margen se agota.
  • 5-30 segundos: alerta. El TOTP empieza a fallar, las ventanas estrechas de firma están en riesgo. La sincronización claramente no funciona como debería.
  • Más de 30 segundos: crítico. Fallan las firmas, los tokens de vida corta y, con desfases grandes, también TLS. Arréglalo de inmediato.
  • Minutos y horas: catástrofe, normalmente consecuencia de congelación, snapshot o batería RTC muerta.

Regla de oro: si el desfase supera los cinco segundos, la hora debe considerarse el primer sospechoso de todos los fallos de TLS, tokens y firmas.

Configuración de la sincronización: que realmente funcione

Diagnosticar es poco: hay que curar y evitar la repetición. Analicemos las dos herramientas principales en Linux y, sobre todo, cómo asegurarte de que la sincronización esté realmente activa y no solo instalada. Esta es la diferencia clave que muchos pasan por alto.

systemd-timesyncd: la variante sencilla

Para la mayoría de máquinas cliente y nodos ligeros, el cliente integrado en systemd es suficiente. Hace una sincronización simple vía el protocolo de tiempo. Activación:

timedatectl set-ntp true

Verificación de que la sincronización va de verdad:

timedatectl status

Busca dos líneas. System clock synchronized: yes significa que el sistema se considera sincronizado. NTP service: active significa que el demonio está funcionando. Ambas deben ser positivas. Si synchronized: no con active, el demonio está corriendo pero aún no logró contactar al servidor o este no está disponible.

Detalles por servidor concreto:

timedatectl show-timesync --all

Aquí se ve a qué servidor se conectó y qué desfase obtuvo. Justamente este comando separa la sincronización real de la decorativa.

chrony: la variante seria

Para servidores donde importa la robustez, especialmente en VMs con riesgo de congelación, chrony es preferible. Sobrelleva los saltos de tiempo con más inteligencia y converge más rápido tras una pausa. Instalación vía gestor de paquetes, luego arranque del servicio. Verificación con el comando principal:

chronyc tracking

Análisis de las líneas clave de la salida:

  • Reference ID: a qué fuente está atado. Si aparece 00000000 o una línea diciendo que la fuente no está seleccionada, no hay sincronización.
  • Stratum: nivel de distancia a los relojes de referencia. Es normal ver un número bajo.
  • System time: el desfase actual del reloj del sistema. Es tu indicador principal.
  • Last offset y RMS offset: correcciones recientes y promediadas, muestran la estabilidad.

Listado de fuentes y su estado:

chronyc sources -v

El asterisco a la izquierda del servidor indica que ese es el elegido como fuente activa. Si ninguna fuente tiene marca de selección, el demonio está instalado pero no sincroniza: la trampa típica.

Cómo distinguir una sincronización instalada de una que funciona

Este es el insight por el que vale la pena leer la sección. El hecho de instalar el paquete y hasta de tener el servicio corriendo no garantiza la sincronización. El servicio puede estar girando sin acceso a servidores de tiempo: por ejemplo, un firewall bloquea los paquetes de salida al puerto necesario, o en un entorno cerrado no hay servidor de tiempo interno.

La verificación real consta de tres preguntas. Primera: ¿hay fuente activa seleccionada? Mira la marca en sources o el Reference ID en tracking. Segunda: ¿cuál es el desfase actual? System time debe estar en fracciones de segundo. Tercera: ¿se actualiza? Ejecuta la verificación dos veces con intervalo y confirma que las cifras están vivas y no congeladas. Si las tres respuestas son positivas, la sincronización funciona de verdad.

Monitoreo del desfase como métrica

El enfoque profesional es no esperar el incidente, sino vigilar el desfase de forma continua. Envía el valor de System time a tu sistema de monitoreo como una métrica más. Configura una advertencia al superar, digamos, dos segundos, y una alerta a los cinco. Así te enterarás del problema antes de que caigan firmas y tokens. El costo de ese monitoreo es cercano a cero y el retorno es enorme: un incidente nocturno evitado lo justifica todo.

Contenedores y relojes: qué se hereda y qué no

La contenedorización merece un análisis aparte porque es donde los ingenieros tienen más ideas equivocadas. Desglosemos qué recibe el contenedor del host y qué no.

Qué se hereda: la hora en sí

Dato clave: el contenedor comparte el núcleo del host y, por tanto, el reloj del sistema. Dentro del contenedor, date -u mostrará exactamente la misma hora absoluta que en el host. El contenedor no tiene un contador de tiempo propio. Esto es fundamental. De ahí se sigue la conclusión principal: para que el contenedor vea la hora correcta, hay que sincronizar el host, no tratar de configurar la sincronización dentro del contenedor.

Qué no se hereda: la zona horaria

La visualización de la hora es otro asunto. La zona horaria se determina por la configuración dentro del contenedor, normalmente el archivo de zona y una variable de entorno. La imagen base suele venir con UTC, y eso, por cierto, es una buena práctica para servidores. Si dentro del contenedor la hora local se ve distinta a la del host, casi siempre es diferencia de zonas horarias, no de hora real. Verifica el absoluto en UTC antes de entrar en pánico.

Por qué no hay que arrancar un demonio de tiempo en el contenedor

Un error extendido entre principiantes es meter un demonio de sincronización dentro del contenedor. Es incorrecto por dos razones. Primera: cambiar la hora del sistema es una operación privilegiada que afecta a todo el núcleo y, por tanto, a todos los contenedores del host y al propio host. Por defecto el contenedor tiene eso prohibido, y está bien. Otorgar ese privilegio solo para sincronizar es abrir un agujero y crear un conflicto.

Segunda: simplemente no es necesario: la hora ya llega del host. La arquitectura correcta es un host sincronizado, muchos contenedores viendo automáticamente la hora correcta. Si tienes un orquestador con múltiples nodos, la sincronización debe garantizarse en cada nodo host, no en cada pod.

La trampa del portátil del desarrollador

Advertimos aparte sobre una situación traicionera. En el portátil del desarrollador todo funciona: los contenedores ven la hora correcta porque el sistema operativo de la estación de trabajo está sincronizado de fábrica. El ingeniero construye la imagen, todo en verde. La imagen viaja al servidor, donde el host no está sincronizado, y allí empiezan los fallos. Lección: prueba el comportamiento con la hora desviada, no solo con la perfecta. Desplaza la hora a propósito en el entorno de pruebas y observa cómo reacciona la aplicación.

Verificación de la hora en un contenedor en ejecución

Un comando rápido para asomarte dentro de un contenedor en marcha y comparar su hora absoluta:

docker exec -it my_container date -u

Si coincide con date -u en el host, todo está bien, busca el problema en otro lado. Si el contenedor muestra de algún modo una hora absoluta distinta, es señal de una configuración no estándar y potencialmente peligrosa que conviene revisar de inmediato.

Errores típicos: qué no hay que hacer

La experiencia del análisis de incidentes se condensa en una lista de tropiezos repetidos. Recorramos esos para que los esquives.

Error uno: culpar al proxy por reflejo

Empezamos con esto y lo repetimos. La palabra certificate o signature en un error al trabajar a través de proxy despierta automáticamente la sospecha hacia la red y el gateway. No cedas. La primera acción ante estos errores es verificar la hora, no cambiar el endpoint. Cuesta diez segundos y descarta la causa oculta más frecuente.

Error dos: arreglar la zona horaria en lugar de la hora

El ingeniero ve una hora local extraña en los registros y cambia la zona horaria. El síntoma en los registros cambia, pero la criptografía sigue fallando, porque la hora absoluta en UTC sigue desviada. Diagnostica siempre con date -u y comparación con la referencia, no con la visualización local.

Error tres: creer que instalar la sincronización es la solución

Instalaron el paquete, vieron que el servicio estaba corriendo, cerraron el ticket. Una semana después vuelven los fallos, porque el servicio no tenía acceso a los servidores de tiempo. Instalar no es sincronizar. Verifica siempre el desfase real y la existencia de una fuente seleccionada.

Error cuatro: corregir el reloj bruscamente en caliente

Un salto brusco del reloj del sistema con un comando de ajuste directo puede romper procesos en ejecución que cuentan con la monotonía del tiempo: expiran timeouts, se rompen sesiones, se disparan acciones incorrectas del planificador. Lo correcto es dejar que el demonio de sincronización ajuste el reloj de forma suave. La corrección brusca solo se justifica ante un desfase enorme y puntual, y aun así, con conciencia.

Error cinco: ignorar la congelación de máquinas virtuales

El equipo no considera que las migraciones, snapshots y pausas generan desfases instantáneos. Para esos entornos hace falta un demonio resistente a los saltos y monitoreo del desfase tras las operaciones de mantenimiento. Si tus fallos correlacionan en el tiempo con respaldos o migraciones, ahí tienes la pista.

Error seis: doble gestión del tiempo

Trabajan simultáneamente el agente de huésped del hipervisor y el demonio interno. El reloj se sacude, los fallos son intermitentes y no se reproducen. Elige un solo mecanismo y desactiva el otro. Esto cura los bugs flotantes más agotadores.

Error siete: ventanas demasiado estrechas sin margen

Si desarrollas una API con firma de solicitudes, no pongas una ventana de tolerancia de treinta segundos sin una razón fundada. Un margen razonable de varios minutos reduce drásticamente la sensibilidad a la desincronización de los clientes sin sacrificar la protección contra repetición. El equilibrio entre rigor y robustez es una decisión de ingeniería, no un dogma.

Herramientas y recursos

Reunamos el arsenal que conviene tener a mano. Todas las herramientas son estándar y legales, para la explotación normal de ingeniería.

Línea de comandos

  • date -u: mirada instantánea a la hora absoluta. El primer comando ante cualquier sospecha.
  • timedatectl: estado de la sincronización y de la zona horaria en sistemas con systemd.
  • chronyc tracking y chronyc sources: diagnóstico profundo de chrony: desfase, fuentes, estabilidad.
  • curl -sI ... | grep -i date: verificación de hora mediante la cabecera HTTP de respuesta, funciona incluso donde no hay demonios. Ideal para contenedores pelados y verificación a través del gateway.

Verificaciones por lenguaje

  • En Python: una línea que imprima utcnow y el timestamp para comparar directamente desde el entorno de ejecución de la aplicación.
  • En Node: una línea con toISOString y Date.now para ver la hora con los ojos de tu propio runtime.
  • Decodificar el JWT sin verificar la firma para ver con tus propios ojos los campos exp, nbf, iat y compararlos con la hora actual. Esto elimina las conjeturas: literalmente ves si el token está vencido según tu reloj o no.

Qué monitorear de forma continua

  • Desfase del reloj del sistema como métrica numérica con umbrales de advertencia y alerta.
  • Estado de existencia de fuente de tiempo seleccionada: indicador booleano de salud de la sincronización.
  • Frecuencia de errores TLS y de tokens desglosada por nodo: un pico en un nodo concreto suele apuntar justamente a su reloj desviado.

Infraestructura Proxeon

Al trabajar a través de los gateways de Proxeon, recomendamos integrar la verificación de hora en el script de arranque de tus nodos de trabajo. Una línea que compare la cabecera Date a través del gateway al iniciar, y atraparás la desincronización antes de la primera solicitud de trabajo. Es barato y reduce drásticamente la proporción de contactos falsos al soporte, donde la raíz resulta ser el reloj del lado del cliente y no el proxy.

Casos y resultados

La teoría cobra vida en historias reales. Presentemos casos generalizados de la práctica: las cifras están redondeadas, los detalles anonimizados, pero los patrones son absolutamente reales.

Caso uno: colapso nocturno del scraper tras el respaldo

El equipo recolectaba datos a través del proxy las 24 horas. Cada noche, alrededor de las tres, empezaba una pared de errores certificate is not yet valid, y para la mañana todo se arreglaba solo. Los ingenieros culparon al pool de proxies durante dos semanas, cambiaron endpoints, escribieron quejas. La respuesta llegó cuando alguien notó la correlación: los fallos empezaban justo durante el respaldo nocturno de las máquinas virtuales.

El hipervisor congelaba la VM minuto y medio o dos para tomar un snapshot consistente. Tras la descongelación, el reloj quedaba atrasado esos minutos, y el agente de huésped no lo ajustaba enseguida. En la ventana entre la descongelación y la corrección, TLS rechazaba certificados frescos como aún no válidos, porque según el reloj atrasado empezaban a regir en el futuro. La solución fue pasar a chrony con convergencia rápida tras el salto y monitorear el desfase justo después de las operaciones de respaldo. Los fallos nocturnos desaparecieron por completo, y el tiempo de diagnóstico de futuros problemas similares se redujo de días a minutos.

Caso dos: cien nodos divergiendo cada uno por su lado

La organización desplegó un parque de cien nodos de trabajo a partir de una misma imagen. La primera semana todo funcionó. Luego empezaron fallos flotantes de firmas de solicitudes en nodos aleatorios: request timestamp too skewed. No reproducibles: reinicias la tarea y puede pasar en otro nodo.

La causa: en la imagen no se había activado la sincronización de hora. Cien nodos derivaban cada uno según su cuarzo. Los más rápidos, en una semana, se salieron de la ventana de tolerancia de la firma. Una verificación masiva con chronyc tracking en todo el parque mostró desfases desde fracciones de segundo hasta quince segundos. Tras activar y verificar el funcionamiento real de la sincronización en todos los nodos, además de añadir la métrica de desfase al monitoreo, los fallos cesaron. Conclusión del equipo: en despliegues masivos hay que verificar el hecho de la sincronización, no el de la instalación.

Caso tres: el desarrollador al que nadie entendía

Un ingeniero se quejaba de que en su máquina local no le pasaba la autorización por TOTP en el panel de control, aunque a todos los demás sí. Introduce el código correcto, el sistema lo rechaza. Se sospechaba un problema con su cuenta.

Resultó que una semana antes había desplazado manualmente la hora del sistema en su estación de trabajo para probar otra aplicación y se olvidó de devolverla, y además había desactivado la sincronización. El reloj se desvió casi un minuto. El TOTP, con ventana de treinta segundos, dejó de coincidir. Activar la sincronización automática lo arregló al instante. Moraleja: la tolerancia estrecha del TOTP es un detector incorporado de desincronización. Si los códigos no coinciden, mira el reloj primero.

Caso cuatro: el contenedor con zona horaria ajena

En los registros de la aplicación en contenedor, la hora iba con un desfase de tres horas respecto al host. Los ingenieros concluyeron que el reloj del contenedor estaba desviado y pasaron un día intentando configurar la sincronización dentro de él, casi otorgándole privilegios de más.

La verificación con date -u dentro y fuera mostró la misma hora absoluta. El desfase era puramente de visualización: la imagen base tenía una zona horaria y el host otra. La criptografía, mientras tanto, funcionaba impecablemente, porque en UTC todo coincidía. En realidad no había problema alguno, solo una confusión cosmética en los registros. La lección costó un día de trabajo: distingue siempre la hora absoluta de su visualización.

FAQ: respuestas profundas a preguntas frecuentes

¿Puede el proxy desviarme la hora o sustituirla en TLS?

En escenarios estándar de trabajo a través de gateway, no. El proxy transmite bytes entre tú y el servidor destino. La verificación de la vigencia del certificado, de los campos exp y nbf, y de la ventana de firma ocurre de tu lado o del lado del servidor final, apoyándose en sus propios relojes. Por eso, ante errores que parecen temporales, hay que sospechar primero del reloj local del nodo de trabajo, no del gateway. El proxy solo alarga la cadena y psicológicamente desplaza la sospecha hacia el medio.

¿Con qué precisión debe ir la hora para que todo funcione?

Para TLS el margen suele ser amplio: las ventanas de validez de los certificados se miden en días, y hasta un desfase de un minuto pasa desapercibido la mayoría de las veces, salvo justo en el límite de renovación. Para JWT todo depende de la vida del token: con tokens cortos, hasta los segundos importan. Para firmas de solicitudes la ventana típica es de minutos, pero conviene mantener el desfase dentro del segundo. El TOTP es el más exigente: decenas de segundos. Recomendación universal: mantén el desfase dentro de un segundo y quedarás protegido de todos los mecanismos mencionados a la vez.

¿Por qué el certificado muestra fechas válidas pero el cliente dice que aún no es válido?

Porque el cliente compara las fechas del certificado no con la verdad absoluta, sino con tu reloj local. Si tu reloj va atrasado y muestra un momento anterior al campo notBefore, para el cliente el certificado aún no ha llegado. Las fechas del propio certificado están perfectas. La respuesta siempre está en comparar tu date -u con la referencia. Es la causa más frecuente del desconcierto de los ingenieros.

¿Hay que instalar un demonio de sincronización dentro del contenedor?

No. El contenedor usa el reloj del núcleo del host, así que hay que sincronizar el host. Instalar un demonio dentro del contenedor es inútil y exige privilegios peligrosos para cambiar la hora del sistema, afectando a todo el host. El modelo correcto es un host sincronizado y muchos contenedores viendo automáticamente la hora correcta. En el orquestador, la sincronización se garantiza en cada nodo host.

¿Cómo distinguir un problema de hora de un problema real de proxy o de red?

Empieza verificando la hora: son diez segundos. Compara date -u con la referencia y con la cabecera HTTP Date a través de tu gateway. Si el desfase es pequeño y los errores TLS y de tokens persisten, pasa al diagnóstico de red. Si el desfase es grande, encontraste la causa. Señal clave de problemas temporales: los errores contienen las palabras not yet valid, expired, skewed, signature con certificados claramente vivos y tokens frescos.

¿Qué hacer justo después de una descongelación o migración de una VM?

Asegúrate de que el demonio de sincronización ajuste el reloj rápido. Para entornos con congelaciones es preferible chrony, que sobrelleva bien los saltos. Verifica chronyc tracking y confirma que System time volvió a fracciones de segundo. Buena práctica: forzar la verificación del desfase tras las operaciones de mantenimiento y no lanzar solicitudes firmadas críticas hasta que el reloj converja.

¿Afecta una zona horaria incorrecta al funcionamiento de TLS y los tokens?

No, siempre que la hora absoluta en UTC sea correcta. Toda la criptografía opera en UTC, y la zona horaria es solo visualización para las personas. Una zona horaria incorrecta te confundirá en los registros, pero no tumbarás TLS, JWT ni la firma. Por eso hay que diagnosticar en UTC y no con la hora local. La confusión entre zona horaria y hora absoluta es una trampa clásica.

¿Cómo integrar la verificación de hora en el flujo de trabajo a través de proxy?

Añade al script de arranque del nodo una línea de verificación: solicita la cabecera Date a través de tu gateway Proxeon y compárala con tu date -u local. Si la discrepancia supera el umbral, detén el arranque y levanta una alerta. Además, envía el desfase del reloj del sistema al monitoreo como métrica permanente con umbrales. Estas dos medidas atrapan la inmensa mayoría de los incidentes temporales antes de que se conviertan en fallos de TLS y tokens.

¿Por qué obtengo

Sobre el autor

Andrey Kokh

Andrey Kokh

Leading Expert and Business Consultant

Experiencia laboral: Leading expert with 12 years of experience. Consults Forbes-listed companies, author of 3 books. Teaches at HSE and SKOLKOVO. His methodologies are used by hundreds of companies across Russia. RBC and Forbes expert on strategic development and digital transformation.
Formación académica: Higher School of Economics. Faculty of Economics, Master's Program
Especialización:
Strategic Consulting Digital Transformation Change Management Business Strategy Innovation Management Organizational Development Lean Management Agile Transformation

Comparte el artículo: