Fatal de memoria recurrente en Joomla (antiguo.feadulta.com) — Registry.php, disparado por bots #168

Open
opened 2026-07-08 22:20:12 +00:00 by rafa · 1 comment
Owner

Sintoma

/php_errors.log registra un PHP Fatal recurrente en antiguo.feadulta.com (Joomla legacy post-cutover), 15-47 veces/dia:

[08-Jul-2026 19:01:16 Europe/Madrid] PHP Fatal error:  Allowed memory size of 805306368 bytes exhausted (tried to allocate 20480 bytes) in /usr/home/feadulta.com/web/antiguo/libraries/vendor/joomla/registry/src/Registry.php on line 814

Investigacion (agente Opus, 2026-07-08)

  • No lo causo el cutover. Contando fatales en logs historicos comprimidos (/errors/*.bz2), el mismo error ya ocurria 15-47 veces/dia desde primeros de junio (ej. 30-jun: 47, 6-jul: 46). El 8-jul (dia del mv a /web/antiguo/) tuvo 17, por debajo de la media.
  • No es un cron: Joomla 3.10 (EOL) no tiene task scheduler, no hay crontab en la jaula. El limite del fatal es 768M (config web PHP-FPM); CLI usa 128M -> confirma que es trafico HTTP, no un proceso batch.
  • Disparador real: trafico de bots/crawlers contra el sitio legacy. errors.log esta saturado de bloqueos ModSecurity "DDoS Attack (discovery)" desde rangos de IP de Cloudflare. El patron de horas (pares separados ~20s, luego huecos irregulares) es tipico de bot, no de proceso periodico.
  • Factor agravante: cache de Joomla estaba DESACTIVADA (caching='0' en configuration.php). Cada request bots incluida reconstruia toda la pagina desde cero, aumentando la presion de memoria en el binding recursivo de Registry.php:814 (bindData(), recursion sobre arrays/objetos anidados al cargar config/params). Codigo Joomla core (vendor), no custom de feadulta.

Acciones

  1. [HECHO 2026-07-08] Activada cache de Joomla (caching='0' -> '1', conservative caching, cache_handler=file ya estaba OK). Backup del configuration.php original en /entrada/configuration.php.bak-20260708-precaching en el servidor. Verificado: sitio responde 200 con contenido real tras el cambio, cache generando ficheros en /web/antiguo/cache/* (mod_menu, com_k2_extended, com_content, etc.), sin errores nuevos en el log tras el cambio. Esto reduce la frecuencia pero no elimina la causa raiz (no arregla la recursion en si).
  2. [PENDIENTE - Inma] Reducir exposicion del legacy a bots via Cloudflare. antiguo.feadulta.com es un sitio en retirada (solo sirve de fallback tras el cutover a WordPress) y no tiene por que estar expuesto a rastreo agresivo. Pedimos a Inma que revise en el dashboard de Cloudflare:
    • Bot Fight Mode / Super Bot Fight Mode para antiguo.feadulta.com (challenge o bloqueo a bots no verificados).
    • Regla especifica de rate-limiting o WAF para ese hostname si el BFM basico no basta.
    • Opcional: robots.txt con Disallow: / para antiguo.feadulta.com (evita que crawlers "legitimos" tipo Googlebot sigan indexando el legacy).
  3. [NO SE HARA] Subir memory_limit por encima de 768M. 768M ya es 6x el limite CLI (128M); si un request llega ahi es un runaway (recursion), no una pagina grande legitima. Subirlo solo retrasaria el OOM y arriesgaria RAM del servidor bajo trafico bots concurrente.

Nota

Si se quiere localizar la URL exacta que dispara el fatal (para bloquearla puntualmente en vez de bots en general), haria falta el access log de antiguo.feadulta.com (no accesible desde la jaula SSH, pedir a cdmon) o analytics de Cloudflare en los timestamps de los fatales.

## Sintoma `/php_errors.log` registra un PHP Fatal recurrente en `antiguo.feadulta.com` (Joomla legacy post-cutover), 15-47 veces/dia: ``` [08-Jul-2026 19:01:16 Europe/Madrid] PHP Fatal error: Allowed memory size of 805306368 bytes exhausted (tried to allocate 20480 bytes) in /usr/home/feadulta.com/web/antiguo/libraries/vendor/joomla/registry/src/Registry.php on line 814 ``` ## Investigacion (agente Opus, 2026-07-08) - **No lo causo el cutover.** Contando fatales en logs historicos comprimidos (`/errors/*.bz2`), el mismo error ya ocurria 15-47 veces/dia desde primeros de junio (ej. 30-jun: 47, 6-jul: 46). El 8-jul (dia del `mv` a `/web/antiguo/`) tuvo 17, por debajo de la media. - **No es un cron:** Joomla 3.10 (EOL) no tiene task scheduler, no hay crontab en la jaula. El limite del fatal es 768M (config web PHP-FPM); CLI usa 128M -> confirma que es trafico HTTP, no un proceso batch. - **Disparador real: trafico de bots/crawlers** contra el sitio legacy. `errors.log` esta saturado de bloqueos ModSecurity "DDoS Attack (discovery)" desde rangos de IP de Cloudflare. El patron de horas (pares separados ~20s, luego huecos irregulares) es tipico de bot, no de proceso periodico. - **Factor agravante: cache de Joomla estaba DESACTIVADA** (`caching='0'` en `configuration.php`). Cada request bots incluida reconstruia toda la pagina desde cero, aumentando la presion de memoria en el binding recursivo de `Registry.php:814` (`bindData()`, recursion sobre arrays/objetos anidados al cargar config/params). Codigo Joomla core (vendor), no custom de feadulta. ## Acciones 1. **[HECHO 2026-07-08] Activada cache de Joomla** (`caching='0'` -> `'1'`, conservative caching, `cache_handler=file` ya estaba OK). Backup del `configuration.php` original en `/entrada/configuration.php.bak-20260708-precaching` en el servidor. Verificado: sitio responde 200 con contenido real tras el cambio, cache generando ficheros en `/web/antiguo/cache/*` (mod_menu, com_k2_extended, com_content, etc.), sin errores nuevos en el log tras el cambio. Esto reduce la frecuencia pero no elimina la causa raiz (no arregla la recursion en si). 2. **[PENDIENTE - Inma] Reducir exposicion del legacy a bots via Cloudflare.** `antiguo.feadulta.com` es un sitio en retirada (solo sirve de fallback tras el cutover a WordPress) y no tiene por que estar expuesto a rastreo agresivo. Pedimos a Inma que revise en el dashboard de Cloudflare: - Bot Fight Mode / Super Bot Fight Mode para `antiguo.feadulta.com` (challenge o bloqueo a bots no verificados). - Regla especifica de rate-limiting o WAF para ese hostname si el BFM basico no basta. - Opcional: `robots.txt` con `Disallow: /` para `antiguo.feadulta.com` (evita que crawlers "legitimos" tipo Googlebot sigan indexando el legacy). 3. **[NO SE HARA] Subir memory_limit por encima de 768M.** 768M ya es 6x el limite CLI (128M); si un request llega ahi es un runaway (recursion), no una pagina grande legitima. Subirlo solo retrasaria el OOM y arriesgaria RAM del servidor bajo trafico bots concurrente. ## Nota Si se quiere localizar la URL exacta que dispara el fatal (para bloquearla puntualmente en vez de bots en general), haria falta el access log de `antiguo.feadulta.com` (no accesible desde la jaula SSH, pedir a cdmon) o analytics de Cloudflare en los timestamps de los fatales.
inma was assigned by rafa 2026-07-08 22:20:19 +00:00
Collaborator

Punto 2 (reducir exposición del legacy a bots vía Cloudflare) — HECHO y verificado

Tope del plan free: Cloudflare solo permite 5 custom rules y ya estaban las 5, así que no pudimos crear una regla nueva. Lo resolvimos editando una existente.

Hallazgo: la regla "Permitir bing" (Skip) en realidad permite muchos rastreadores en TODAS partes, incluido antiguo: bing, Google, duck, yahoo, ecosia, archive, Slurp, ahrefs, semrush, Collaborator, openai (+ rutas wp-cron.php/admin-ajax.php). Por el orden de reglas (Skip corta la cadena antes de llegar a "bloquear bots 1/2"), esos crawlers estaban entrando al Joomla viejo sin freno → era una fuente clara del fatal del #168.

Cambio aplicado: a esa regla le añadimos al final and (not http.host eq "antiguo.feadulta.com") (envolviendo el OR original entre paréntesis). Así, en antiguo esos rastreadores ya no se permiten → caen en "bloquear bots 1" (cf.client.bot) y se bloquean. En www todo sigue igual (SEO intacto).

Verificado desde fuera:

Googlebot Bingbot Navegador
antiguo.feadulta.com/es/ 403 403 200 (pasa)
www.feadulta.com/… 200 (pasa) 200 (pasa)

Complementa tu activación de la caché de Joomla. Los grandes buscadores dejan de rastrear el archivo.

Notas / cabos:

  • Cubre los rastreadores verificados (los del volumen). Alguno no-verificado (p.ej. ahrefs/semrush si no son cf.client.bot) podría colarse aún; si quieres rematarlo, un robots.txt con Disallow: / o cabecera noindex solo en antiguo (lado servidor) lo cerraría del todo — pero con esto la presión ya baja mucho.
  • Recordatorio del límite de 5 reglas custom del plan free, por si en el futuro hace falta más margen.

Por nuestra parte, cerrado. 🎯

## Punto 2 (reducir exposición del legacy a bots vía Cloudflare) — HECHO y verificado **Tope del plan free:** Cloudflare solo permite **5 custom rules** y ya estaban las 5, así que **no pudimos crear una regla nueva**. Lo resolvimos **editando una existente**. **Hallazgo:** la regla "Permitir bing" (Skip) en realidad permite **muchos rastreadores en TODAS partes, incluido `antiguo`**: `bing, Google, duck, yahoo, ecosia, archive, Slurp, ahrefs, semrush, Collaborator, openai` (+ rutas `wp-cron.php`/`admin-ajax.php`). Por el orden de reglas (Skip corta la cadena antes de llegar a "bloquear bots 1/2"), **esos crawlers estaban entrando al Joomla viejo sin freno** → era una fuente clara del fatal del #168. **Cambio aplicado:** a esa regla le añadimos al final `and (not http.host eq "antiguo.feadulta.com")` (envolviendo el OR original entre paréntesis). Así, en `antiguo` esos rastreadores **ya no se permiten** → caen en "bloquear bots 1" (`cf.client.bot`) y se bloquean. En `www` todo sigue igual (SEO intacto). **Verificado desde fuera:** | | Googlebot | Bingbot | Navegador | |---|---|---|---| | `antiguo.feadulta.com/es/` | **403** ✅ | **403** ✅ | 200 (pasa) ✅ | | `www.feadulta.com/…` | 200 (pasa) ✅ | 200 (pasa) ✅ | — | Complementa tu activación de la caché de Joomla. Los grandes buscadores dejan de rastrear el archivo. **Notas / cabos:** - Cubre los rastreadores verificados (los del volumen). Alguno no-verificado (p.ej. ahrefs/semrush si no son `cf.client.bot`) podría colarse aún; si quieres rematarlo, un **`robots.txt` con `Disallow: /` o cabecera `noindex` solo en `antiguo`** (lado servidor) lo cerraría del todo — pero con esto la presión ya baja mucho. - Recordatorio del límite de 5 reglas custom del plan free, por si en el futuro hace falta más margen. Por nuestra parte, **cerrado.** 🎯
Sign in to join this conversation.
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rafa/feadulta#168