Fecha de caducidad: 6/4/2021
El 6 de abril de 2021 caducó de manera inesperada un certificado TLS comodín que teníamos. Es vergonzoso cuando caduca un certificado, pero sentimos que era importante compartir nuestra historia aquí con la esperanza de que otros también puedan aprovechar nuestros aprendizajes y mejorar sus sistemas. Si tú o tu organización están utilizando el monitoreo de certificados, este puede ser un buen recordatorio para verificar si hay brechas en esos sistemas.
El certificado que caducó se usaba en muchos servicios internos de Epic; de hecho, en demasiados. A pesar de nuestros mejores esfuerzos para monitorear la caducidad de nuestros certificados, no cubrimos completamente todas las áreas donde se estaban utilizando certificados. Luego de la caducidad y renovación del certificado, se desarrollaron una serie de eventos inesperados que extendieron el corte. Tenemos más detalles sobre ellos en esta publicación.
Ciertos componentes centrales, como nuestros sistemas de identidad y autenticación, se vieron afectados, y estos servicios afectan a muchos otros servicios de todo nuestro ecosistema. Se observaron o se informaron los siguientes impactos:
- Los inicios de sesión de las cuentas de Epic fallaron desde cualquier producto que utiliza esta forma de autenticación, incluidos Fortnite, Rocket League, Houseparty, Epic Online Services o la Epic Games Store
- Desconexiones de juegos o servicios en vivo en todas las plataformas
- Falló la compra de artículos en el iniciador de Epic Games
- Comportamiento inesperado en el iniciador de Epic Games, desde contenido que no se cargaba hasta el modo sin conexión que no funcionaba
- Los sitios web de productos y marketing de Epic Games no estaban disponibles o estaban deteriorados, incluidos los sitios de Unreal Engine
- Múltiples problemas de herramientas internas que afectan la capacidad de los empleados de Epic para resolver o administrar problemas
Esta publicación tiene como objetivo brindarte información detallada sobre lo que ocurrió, lo que aprendimos y los pasos que vamos a tomar en el futuro.
¿Qué ocurrió?
Ocurrieron tres graves series de eventos:
- Un certificado caducado provocó un corte en una gran parte de las llamadas internas de servicio a servicio back end y en las herramientas de administración interna
- Incrementos inesperados e importantes de tráfico hacia el iniciador de Epic Games, servicio interrumpido del iniciador de Epic Games y de funciones de distribución de contenido
- Se desplegó una versión incorrecta del sitio web de la Epic Games Store que mostraba artefactos y recursos no válidos como parte del escalado automático, deteriorando la experiencia de la Epic Games Store
1) Certificado caduco
El 6 de abril a las 12:00 UTC, un certificado TLS caducó. Este certificado se usaba para una gran cantidad de comunicaciones exclusivamente internas en la plataforma back end de Epic. Usamos cifrado TLS entre nuestros servicios back end para llamadas API entre servicios y herramientas de administración interna. Este certificado es para una zona DNS interna que no está orientada al público.
A las 12:00 UTC, el tráfico se detuvo del todo entre los sistemas back end. Seis minutos más tarde, a las 12:06 UTC, se informó el incidente y comenzó nuestro tratamiento del incidente. Si bien tuvimos muchas alarmas, también alentamos a cualquier persona de la empresa a informar cualquier problema de impacto general que vieran. Cada incidente es clasificado por nuestro equipo de Live Ops (operaciones en vivo) las 24 horas, los 7 días de la semana, y ellos inician nuestro proceso de gestión de incidentes. Cuando llegó el primer informe interno, nuestras herramientas y procesos de gestión de incidentes abrieron automáticamente un canal de Slack y las partes relevantes fueron invitadas o llamadas al incidente.
A las 12:12 UTC, confirmamos la caducidad de un certificado, que creíamos que probablemente era la fuente de los problemas, y comenzamos el proceso de renovación. A las 12:37 UTC, el certificado se volvió a emitir y el certificado actualizado comenzó a implementarse en nuestros servicios back end. En el transcurso de los siguientes 5 a 15 minutos, los balanceadores de carga comenzaron a implementar automáticamente el nuevo certificado en los puntos finales internos y nuestras llamadas HTTPS de servicio a servicio se recuperaron junto con nuestras interfaces de administración.
El equipo de Live Ops (operaciones en vivo) que se encargó de determinar las prioridades durante este incidente también estaba manejando el incidente en esta etapa, comunicándose con los empleados e involucrando a las personas adecuadas, y a las 12:38 UTC se activó una llamada de Zoom para coordinar a las personas que habían estado colaborando en Slack. Si bien Slack es una buena herramienta de comunicación, en situaciones urgentes nada supera la comunicación en vivo en tiempo real a través de voz o video. Las actualizaciones sobre el incidente se enviaban regularmente a las partes interesadas internas a través de nuestras herramientas y procesos para mantener a todos al tanto de lo que estaba sucediendo. En este momento, había más de 25 personas directamente involucradas y trabajando en este problema con muchas más observando: sectores como los de asistencia al jugador, comunidad, ingeniería y producción a lo largo de muchos de nuestros diferentes productos y equipos.
Un gráfico de los recuentos de solicitudes por minuto a un solo microservicio, con una caída en el corte del certificado y un aumento en el momento de su recuperación total.
Factores que contribuyeron
Las zonas DNS para esta comunicación interna de servicio a servicio no eran monitoreadas activamente por nuestros servicios de monitoreo de certificados, lo cual fue un descuido de nuestra parte. Nuestros servicios de monitoreo de certificados obtienen claves de espacios de nombres DNS completos, no de puntos finales o certificados individuales, y faltaba la configuración para esta zona interna. Desde entonces, hemos trasladado esta zona a nuestra nueva solución de monitoreo que aborda esta brecha. Antes de este incidente, también habíamos comenzado un proyecto para habilitar y configurar AWS Config de manera global sobre nuestras muchas cuentas. Con esta configuración a nivel global, podemos agregar fácilmente una regla de AWS Config que activa una alarma de defensa en profundidad ante la caducidad de certificados.
Las renovaciones automáticas no estaban habilitadas para este certificado interno y el trabajo necesario para lograrlo no se había priorizado cuando se identificó a principios de este año. Contamos con los sistemas y servicios adecuados para facilitar la renovación automática, pero la migración para usar estas funciones no se había completado antes de este incidente. Con nuestros sistemas de monitoreo existentes, creíamos que estábamos más protegidos de lo que realmente estábamos frente a los peligros de la caducidad de los certificados. Trabajaremos para trasladar este certificado y otros a renovaciones automáticas. Mientras tanto, hemos completado una auditoría manual de todos nuestros certificados.
El certificado comodín de servicio a servicio utilizado estaba instalado en cientos de servicios de producción diferentes y, debido a esto, el impacto fue muy amplio. Usamos el AWS ACM (AWS Certificate Manager) para administrar este certificado, lo que nos permitió renovarlo y aplicarlo rápidamente en cientos de servicios de producción en pocos minutos. El problema de la caducidad no tuvo nada que ver con el AWS ACM en sí, sino con nuestra administración de nuestro propio certificado. Trabajaremos para separar el radio de impacto de nuestros certificados y parte de esto implicará actualizar nuestros procesos para el uso de certificados con el AWS ACM.
2) Aumento significativo del tráfico en el servicio del iniciador de Epic Games
A pesar de que la mayoría de nuestros servicios se recuperaron inmediatamente luego de la renovación del certificado, nuestros servicios del iniciador de Epic Games seguían sin estar disponibles.
A las 12:46 UTC, luego de haberse emitido el certificado, hubo un aumento en la tasa de solicitudes que saturó el servicio del iniciador de Epic Games, un servicio back end clave que brinda soporte al cliente del iniciador de Epic Games. Este aumento en la tasa de solicitudes surgió a partir de una inesperada lógica de reintentos de los clientes, que solo se da cuando hay fallas. A pesar de haber mejorado la resiliencia del iniciador de Epic Games durante años, este caso de aumento en las solicitudes fue inesperado. Nuestros servidores alcanzaron sus límites de seguimiento de conexiones y se cayeron paquetes en toda la flota, lo que hizo que la recuperación fuera más desafiante a pesar de que nuestra flota de aplicación back end se incrementó un 250 %. Los servicios del iniciador de Epic Games pasaron por una falla en cascada y un corte completo. Para recuperarlos, era necesario limitar el tráfico hacia el back end y luego agregar tráfico progresivamente de nuevo al sistema mientras, de manera simultánea, se aumentaban nuestros límites de seguimiento de conexiones.
Una gran cantidad de clientes del iniciador de Epic Games estaban generando decenas de millones de conexiones al servicio back end del iniciador de Epic Games, y los componentes de sus sistemas se fueron deteriorando debido a esta carga. Necesitábamos drenar el tráfico hacia el back end para que pudiera recuperarse. Si bien normalmente tenemos disponible una capacidad de explosión para este servicio, no permitía que el servicio se encargara siquiera de la carga 28 veces mayor que observamos al comienzo del corte.
Un gráfico del conteo de solicitudes por minuto a nuestro balanceador de carga back end del iniciador de Epic Games. Inicialmente, el tráfico se multiplicó por 28, y la explosión final a las 15:12 UTC fue 40 veces mayor a la tasa normal.
A pesar de que nuestro conteo de solicitudes era 28 veces mayor al normal, la gran cantidad de conexiones al servicio back end del iniciador de Epic Games sobrepasó el espacio del seguimiento de conexiones disponible, lo que hizo que se perdieran paquetes y finalmente se deteriorara la conexión de los nodos del back end. Nuestra carga de conexiones del back end era 3200 veces mayor que nuestra tasa normal. El aumento en las conexiones TCP era significativamente más alto que la cantidad de solicitudes.
Un gráfico de conteos de nuevas conexiones por minuto a nuestro balanceador de carga del back end del iniciador de Epic Games con una cantidad de conexiones 3200 veces mayor que el pico normal.
Factores que contribuyeron
El certificado TLS que caducó creó un corte que inició un comportamiento inesperado en nuestro cliente del iniciador. Nuestra investigación mostró que nuestro cliente usó la lógica linear de reintento en vez de implementar el retroceso exponencial que esperábamos. Otro error inesperado también causó que el patrón de solicitudes de millones de clientes del iniciador de Epic Games siguiera reintentando continua e interminablemente hasta recibir una respuesta satisfactoria. Estos dos errores en la base de instalaciones de nuestro cliente crearon un involuntario e imprevisto patrón de llamadas. Efectivamente, recibimos un ataque distribuido de denegación de servicio por parte de nuestros propios clientes, pero estamos trabajando urgentemente para arreglar estos errores con una actualización del iniciador de Epic Games.
Un factor interesante que contribuyó a esta parte del incidente fue la duración del corte inicial. Mientras más duraba el corte, eran más altas las probabilidades de que más clientes usaran la defectuosa lógica de reintento y llamaran continuamente a nuestro back end. Si el corte hubiera durado menos, podríamos no haber acumulado tantos clientes que hicieran continuamente reintentos de llamadas que sobrecargaran al sistema; solo un corte de esta duración habría generado este caso. Resolveremos este tema a través de nuestros cambios en el patrón de llamadas.
No se entendió del todo nuestra alarma para el seguimiento de conexiones. Esta alarma se disparó durante el incidente del servicio del iniciador de Epic Games, y a pesar de que muchos equipos saben lo que significa esta alarma, su descripción y notificación no fueron del todo claras y no se supo que esta condición haría que se perdieran paquetes de cualquier conexión que hicieran estos servidores, incluida la conexión con un clúster Redis interno. Ese fue un momento estresante para el equipo, que investigaba qué podría estar sucediendo mientras se deterioraba la conexión con el clúster Redis. Se creía que esto fue causado en parte por nuestros mecanismos de almacenamiento de caché. Luego se comprobó que fue a causa de la pérdida de paquetes, debido a que la tabla de seguimiento de conexiones estaba llena, con cientos de miles de conexiones en uso. Más tarde, durante este incidente, aumentamos nuestros límites de seguimiento de conexiones a más de un millón por nodo, pero los aumentos en el seguimiento de conexiones en nuestra infraestructura no son instantáneos y se tardó un tiempo. Trabajaremos para actualizar nuestra alarma y que sea más clara, ya que esto causará graves problemas de red hasta que se resuelva.
Los aumentos hicieron que los nuevos nodos alcanzaran instantáneamente los límites de seguimiento de conexiones. Ya que nuestra flota estaba sobrecargada con conexiones, lo que causaba grandes pérdidas de paquetes, necesitábamos reducir el tráfico total a la flota y aumentar lentamente el tráfico permitido. Al principio, intentamos usar el AWS WAF (firewall de aplicaciones web) para limitarnos a un subconjunto de tráfico entrante, pero nuestra configuración no limitaba el tráfico suficiente. Esto no era un problema con el AWS WAF, sino con nuestro conjunto de reglas específicas. Por razones de tiempo, luego usamos nuestros objetivos medidos del balanceador de carga de AWS para mover algo de tráfico, lo cual, junto con el aumento de nuestros límites de seguimiento de conexiones, resultó ser exitoso. Usar el WAF en esta situación demoró nuestra recuperación de los servicios del iniciador de Epic Games, pero no fue culpa de AWS. Desarrollaremos un proceso estándar para cargar con urgencia el tráfico perdido en situaciones críticas como esta mediante el AWS WAF, objetivos medidos del balanceador de carga u otras tecnologías de AWS.
3) Recursos no válidos en el sitio web de la Epic Games Store
A las 15:12 UTC, con nuestro certificado renovado y nuestro servicio del iniciador de Epic Games recuperado, procedimos a desbloquear a todos los clientes que llamaban a la Epic Games Store. A causa de la duración del corte, había significativamente más clientes que lo normal que solicitaban contenido de la Epic Games Store, y obviamente esto comenzó a aumentar. Empezamos a evaluar todos los tipos de impacto restantes cerca de las 15:30 UTC.
Al principio, todo se veía normal, pero empezamos a recibir informes internos de problemas de diseño y errores en la Store, que pudimos confirmar y reproducir. Luego de analizar los detalles, nos dimos cuenta de que el cliente de la web (mediante el cual los usuarios que navegan en epicgames.com interactúan con la Store) estaba intentando traer una ID de recurso única que no estaba presente en nuestra CDN. Revisamos las versiones de nuestro contenedor a lo largo de la flota y todas eran iguales, pero, si eso fuese cierto, ¿cómo podía ser que la misma versión de aplicación estuviera devolviendo valores de recursos estáticos diferentes?
Algo andaba mal aquí. Este fue un periodo muy confuso del incidente y, al final, muchas de las señales disponibles (como las versiones implementadas) resultaron ser falsas. Pudimos correlacionar la escalada del back end de la Epic Games Store con un aumento en los errores 403 en nuestra CDN, lo que nos llevó a investigar las instancias nuevas de manera más detallada. Al transferir el contenido localmente sobre las nuevas instancias, descubrimos que el contenido que recibíamos no era válido. Pudimos rastrearlo hasta descubrir que un contenedor desencadenaba de forma inesperada un nuevo flujo de trabajo de CI/CD. Esto sucedió el día anterior y, más allá de esto, no estaba relacionado con nada de lo que nos habíamos encontrado hasta ese momento durante este incidente. Estos resultados seguían siendo sorprendentes, pero, una vez que ya habíamos descubierto esto, pudimos volver a una versión anterior del contenedor rápidamente, eliminar las instancias no válidas y restaurar el tráfico.
Este problema se pudo haber presentado durante cualquier aumento de tráfico considerable que haya ocurrido durante este periodo, pero, como normalmente mantenemos suficiente espacio libre en nuestros equipos, este problema no apareció hasta que tuvo lugar el gran aumento de tráfico en la Epic Games Store que produjo el iniciador de Epic Games.
Factores que contribuyeron
La interrupción del certificado causó problemas con el iniciador de Epic Games que, una vez solucionados, crearon un aluvión de solicitudes a la Epic Games Store, lo que posteriormente produjo una escalada en los sistemas de la Epic Games Store. Esto es de esperar y bien recibido.
Nuestras señales y datos sobre el estado de las versiones a través de la flota de nuestra aplicación nos llevaron a creer erróneamente que la implementación de nuestra flota era uniforme. Hemos cambiado el esquema de nuestras versiones para contribuir a que estos diagnósticos falsos no ocurran en el futuro.
Un cambio reciente en la cadena de CI/CD para la Epic Games Store tenía una configuración defectuosa que actualizaba el artefacto de la aplicación de manera inesperada. Pudimos corregir esto con una modificación a nuestra cadena de CI/CD y revertir los cambios inesperados. El cambio en nuestro esquema de versiones nos protegerá si esto volviera a suceder.
Cronología
- 12:00 UTC - Expiración del certificado interno
- 12:06 UTC - Informe del incidente y comienzo de la gestión de incidentes
- 12:15 UTC - Preparación del primer mensaje para los clientes
- 12:21 UTC - Múltiples equipos confirmaron varias fallas de servicio importantes
- 12:25 UTC - Comienzo de confirmación del proceso de renovación del certificado
- 12:37 UTC - Confirmación de que el certificado puede ser renovado
- 12:46 UTC - Recuperación confirmada de algunos servicios
- 12:54 UTC - Identificación del seguimiento de conexiones como un problema para el servicio del iniciador de Epic Games
- 13:41 UTC - Reinicio de nodos del servicio del iniciador de Epic Games
- 15:05 UTC - Aumento de los límites de seguimiento de conexiones para el servicio del iniciador de Epic Games
- 15:12 UTC - Primeras señales de recuperación para el servicio del iniciador de Epic Games
- 15:34 UTC - Escalada en los servicios web de la Epic Games Store
- 15:59 UTC - Primeros informes de recursos faltantes en la Epic Games Store
- 16:57 UTC - Descubrimiento de un problema con versiones no coincidentes del servicio web de la Epic Games Store
- 17:22 UTC - Corrección de la versión del servicio web de la Epic Games Store
- 17:35 UTC - Recuperación completa
¿Qué sucede a continuación?
En las secciones anteriores, analizamos las situaciones que llevaron a las sorpresas y, finalmente, a la interrupción del servicio el 6 de abril. Mencionamos nuestros próximos pasos junto con nuestros factores contribuyentes, pero también los recapitularemos aquí.
No existe una única causa de origen para estos problemas. Innumerables factores, tanto tecnológicos como organizativos, contribuyeron a los acontecimientos que ocurrieron. El alcance y la duración de la interrupción nos ayudaron a descubrir no solo errores explícitos en nuestros sistemas, que nos encargaremos de corregir, sino también supuestos previamente no cuestionados en algunos de nuestros procesos internos, especialmente aquellos que rigen la administración de certificados.
Si bien actuamos de inmediato para cubrir esta zona con nuestro nuevo sistema de monitoreo de certificados y auditamos todos los certificados conocidos existentes, analizaremos más a fondo cualquier brecha adicional en nuestro monitoreo de certificados y agregaremos métodos para prevenir problemas, como incluir monitoreo de AWS Config de todos los certificados basados en el AWS ACM. También trabajaremos para reducir el radio de impacto de todos los certificados.
Vamos a observar más detenidamente los patrones de llamadas de los clientes del iniciador de Epic Games y corregir urgentemente algunos de los errores que hemos identificado como parte de esto, así como mejorar nuestra capacidad para reaccionar ante situaciones de tráfico significativamente mayor. Con el aumento permanente de nuestras tablas de seguimiento de conexiones para esta flota, deberíamos poder manejar una cantidad similar de carga sin una pérdida importante de paquetes. Si tienes flotas a gran escala, este puede ser un buen recordatorio para verificar los límites y alarmas de la tabla de seguimiento de conexiones si utilizas esta funcionalidad netfilter. Además, estamos contentos de servir como un buen recordatorio para verificar la lógica de reintento en tus clientes y, especialmente, cómo podrían comportarse en conjunto después de una interrupción prolongada.
Para la Epic Games Store, hemos implementado una solución que debería evitar la modificación de un objeto de aplicación en vivo, y como parte de esto, descubrimos un error en nuestra generación de recursos y lo solucionamos.
Esperamos que este informe de incidentes te otorgue más detalles sobre lo que sucedió el 6 de abril. Esperamos que estos detalles transmitan nuestros aprendizajes y mejoras y ayuden a otros a evitar problemas similares.
¡Únete!
Esta publicación fue escrita por nuestro equipo de ingeniería para la fiabilidad con gran ayuda de muchos otros estupendos equipos de ingeniería aquí en Epic.
¿Te interesa este tipo de problemas? ¿Te apasionan los videojuegos y los servicios de videojuegos? Epic siempre está buscando grandes talentos y estamos contratando a nivel mundial en todos los tipos de habilidades. Si quieres ver nuestras vacantes, visita el centro de empleos de Epic Games.
¿Te ayudó esta publicación o te pareció interesante? Cuéntanos en [email protected].