Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
NcStatusCheck — Monitorización centralizada para múltiples instancias de Nextcloud | Kitploit
Herramientas/GitLabGitLab/jp.louvel/ncstatuscheck
Análisis de VulnerabilidadesAuditoría de ConfiguraciónSeguridad en la Nube
GitLabjp.louvel/ncstatuscheck

NcStatusCheck

Monitorización centralizada para múltiples instancias de Nextcloud

Ver Repositorio
21hace 15 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

NcStatusCheck

Monitorización centralizada para múltiples instancias de Nextcloud

NcStatusCheck es una herramienta de monitorización que permite rastrear el estado de múltiples servidores Nextcloud desde una única interfaz web. Analiza las versiones de Nextcloud y PHP y proporciona recomendaciones de actualización.

Interfaz de NcStatusCheck Interfaz de NcStatusCheck - 2

🎯 Características

Monitorización

  • Vigilancia automatizada de múltiples instancias de Nextcloud
  • Tres modos de recolección de datos por servidor: Básico (solo versión NC), Extendido (datos completos mediante API serverinfo) y Push (datos enviados por la instancia remota)
  • Análisis de versiones de Nextcloud y PHP
  • Detección del servidor web (nginx, Apache) y protocolos HTTP
  • Seguimiento de actividad/inactividad (mini uptime): accesibilidad actual + último cambio de estado, mostrado como una insignia roja «offline» solo cuando está caído. Un diario de transiciones acotado también alimenta un % de disponibilidad a 30 días y una lista de incidentes recientes en la página de detalle
  • Alerta de caducidad del certificado SSL: leída de la sonda HTTPS existente (sin solicitud extra), insignia cuando el certificado caduca pronto (< 15d / < 7d)
  • Auditoría de aplicaciones instaladas: cruza occ app:list con la tienda de aplicaciones de Nextcloud para marcar aplicaciones a revisar — bloqueantes (bloquean actualización, incompatibles, aplicaciones de prueba en producción) más señales informativas de madurez/turbulencia (publicadas recientemente, pre-1.0, compilación alpha/beta/rc, ráfaga de lanzamientos, versión recién lanzada)
  • Bloques de vigilancia globales: un bloque «Apps a vigilar» (📦) y su gemelo «Contenedores a vigilar» (🐳) agregan cada aplicación/imagen Docker marcada en todas las instancias en una sola entrada, con filtros por tipo por grupo y una ventana emergente que lista las instancias afectadas y sus versiones
  • Alertas proactivas (webhook y/o correo): se disparan ante un cambio de estado confirmado (inactivo, mantenimiento, recuperado) para que sea notificado sin necesidad de abrir el panel — Slack / Mattermost / Google Chat / Discord / JSON en bruto (ALERT_WEBHOOK_URL), y/o un correo resumen por lote (ALERT_EMAIL_TO) enviado mediante envío SMTP directo a su servidor de correo (PHPMailer incluido; recurre al MTA local cuando no hay un relay SMTP configurado). También cubre señales lentas (ALERT_CHECKS): caducidad de certificado SSL (escalonada), versión vulnerable/obsoleta de Nextcloud, sonda Push estancada, informe de auditoría crítico, hallazgo de aplicación bloqueante — una alerta por cada nueva condición, sin spam de recordatorios
  • Retardo de gracia de actualización: una instancia solo se marca como desactualizada unos días después de que se publique un parche (nc_update_grace_days), para evitar perseguir un lanzamiento con errores del mismo día
  • Columna de estado usando el principio «silencio = todo bien»: solo muestra insignias (⚠️ advertencias, 📦 aplicaciones, 🔄 Docker, 🔒 SSL, 🔴 inactivo, 🚧 mantenimiento) cuando hay algo que reportar
  • Sistema de caché para datos de servidor y versiones oficiales

Página de detalle

  • Vista completa de la configuración de cada servidor Nextcloud (PHP, OPcache, Redis, base de datos…) para servidores Extendidos/Push
  • Página de detalle básica para servidores sin sonda: muestra versión, servidor web, protocolo HTTP y una sugerencia de actualización
  • % de disponibilidad a 30 días y lista de incidentes recientes (inicio, fin, duración, motivo), calculados a partir del diario acotado de transiciones actividad/inactividad — etiqueta honesta «medido durante N días» mientras el diario sea más reciente que la ventana
  • Reglas de advertencia de configuración con indicadores ⚠️, cada una reconocible (motivo + caducidad opcional)
  • Sección de informe de auditoría del servidor cuando la instancia envía su informe mensual nc-audit.sh
  • Accesible haciendo clic en cualquier nombre de servidor o indicador de estado

Interfaz

  • Panel centralizado con resumen de estado (tarjetas de resumen que muestran recuentos de inactivos / certificados próximos a caducar / aplicaciones a revisar solo cuando no son cero)
  • Filtros avanzados por estado de Nextcloud, estado de PHP, estado general, imagen Docker en ejecución y búsqueda de texto
  • Versiones oficiales obtenidas automáticamente de fuentes de Nextcloud
  • Calendario de publicaciones con fechas de versiones próximas
  • Interfaz en FR / EN / DE (selector de idioma en la esquina superior derecha)

Administración

  • Interfaz de administración para configurar reglas de versiones
  • Tabla resumen de modos de sonda en la parte superior: explica de un vistazo los tres métodos de recolección (Básico, Extendido, Push)
  • Gestión de servidores mediante interfaz web con diseño de tarjetas: dos zonas de sonda distintas (serverinfo / push), tokens enmascarados con revelado, eliminación en línea
  • Botón «Configurar sondas» por servidor para alternar zonas de token, estado guardado en localStorage
  • Búsqueda en tiempo real de servidores con coincidencia insensible a acentos
  • Generador de script Push: genera un script bash cron listo para usar (chmod 700) para la instancia Nextcloud remota, actualizado automáticamente al cambiar las opciones
  • Botón «Activar Push» en el panel: envía una solicitud push a todos los servidores push configurados (visible solo cuando existe al menos un servidor push, enfriamiento de 5 minutos)
  • Configuración flexible de umbrales de seguridad por rama de Nextcloud

🏗️ Arquitectura```

ncstatuscheck/ ├── Frontend │ ├── index.php # Main entry point │ ├── template.html # HTML template (dashboard) │ ├── admin.html # Administration interface │ ├── detail.php # Server detail page │ ├── audit.php # Server-audit script distribution page (nc-audit.sh) │ ├── troubleshooting.php # Probe troubleshooting guide │ ├── app.js / admin.js / detail.js / audit.js / troubleshooting.js │ └── style*.css # One stylesheet per page family ├── APIs (HTTP) │ ├── api.php # Main monitoring API │ ├── detail-api.php # Detail page API (serverinfo + warnings + acks + availability) │ ├── push-api.php # Push reception + trigger + audit-report reception │ ├── ack-api.php # Warning acknowledge / unmute │ ├── admin-api.php # Version configuration routing │ ├── servers-admin-api.php # Server list management │ ├── nextcloud-versions-api.php # Official version scraping │ ├── nextcloud-apps-api.php # App store catalog (slim cache) for the apps audit │ ├── php-versions-api.php # PHP branch support data │ └── apps-warnings-api.php # Manual app warnings (known-bug list) CRUD ├── Shared modules (lib/) │ ├── auth.php # Auth + CSRF + URL redaction (defense in depth) │ ├── csrf-client.js # Auto-inject X-CSRF-Token in fetch() │ ├── nextcloud-client.php # Centralized HTTP client → remote Nextclouds │ ├── servers-store.php # Single source of truth for servers.json │ ├── uptime-state.php # Up/down state machine + transition journal + availability │ ├── alerts.php # Proactive alert dispatch: webhook + email digest │ ├── alerts-checks.php # Slow-signal alerts (SSL/version/push/audit/apps) + dedup state │ ├── smtp-mailer.php # SMTP transport adapter over vendored PHPMailer │ ├── phpmailer/ # Vendored PHPMailer (3 files + LICENSE, pinned in VERSION) │ ├── apps-warnings-manager.php # Manual app warnings storage │ ├── ui-common.js # NcUI: notify / confirm / prompt + shared app-audit messages │ ├── url-guard.php # Anti-SSRF (loopback, RFC1918, link-local…) │ ├── json-cache.php # Locked JSON read/write helpers │ └── version-config-manager.php # Version rules CRUD ├── Business logic │ ├── version-rules.php # NC / PHP status analysis engine │ ├── warnings-rules.php # Configuration warning engine │ ├── apps-rules.php # Installed-apps audit engine (store catalog cross-check) │ ├── cron-update.php # Full collection script, CLI only (twice a day) │ └── cron-ping.php # Lightweight up/down probe, CLI only (every 5 min) ├── Tools (never web-served — blocked by nginx/.htaccess) │ ├── tools/nc-audit.sh # Standalone server audit script (root, read-only) │ └── tools/ncstatuscheck-push-core.sh # Generic Push probe core (fleet-shared) ├── Tests │ └── tests/run.php # Plain-PHP test suite (no framework): php tests/run.php ├── Configuration │ ├── config.php # Central configuration (git-ignored) │ └── servers.json # Server list with tokens (git-ignored) └── Cache ├── servers_data.json # All server data ├── serverinfo_.json # Raw per-server cache (Extended) ├── push_.json # Last push payload per server ├── ack_.json # Acknowledged warnings per server ├── audit_.json # Last nc-audit.sh report per server ├── version-config.json # Version configuration ├── uptime_state.json # Up/down state per server (mini uptime) ├── uptime_history.json # Bounded up/down transition journal (availability % + incidents) ├── alerts_state.json # "Already alerted" memory of the check alerts ├── nextcloud_versions.json # Official NC versions ├── nextcloud_apps.json # App store slim catalog (apps audit) ├── apps-warnings.json # Manual app warnings (admin-curated) ├── .csrf_secret # CSRF HMAC secret (binary, 0600) └── *.log # Activity logs

deploy/ansible/ # Fleet deployment of the Push core (Ansible / scp) deploy/docker/ # Container packaging of the monitor itself

root@kitploit:~
## 🔌 Modos de recopilación

Los modos no son mutuamente excluyentes: un servidor puede ser Extendido y Push simultáneamente.

| Modo | Insignia | Fuente | Datos recopilados |
|------|----------|--------|-------------------|
| **Básico** | *(ninguna)* | `/status.php` + cabeceras HTTP | Versión de Nextcloud (PHP/servidor web si están expuestos) |
| **Extendido** | `⚡ Extended` (púrpura → naranja en error/desactualizado) | `/ocs/v2.php/apps/serverinfo/api/v1/info` con `NC-Token` | Versión de NC, PHP, servidor web, OPcache, Redis, BD, usuarios activos… |
| **Push** | `📡 Push` (azul → naranja en error/desactualizado) | POST a `push-api.php` | Datos enviados por la instancia NC remota mediante script cron |

El **token NC de serverinfo** está disponible en **Configuración de Nextcloud → Administración → Sistema**.

El **token Push** se genera desde la interfaz de administración; el administrador proporciona un script cron bash listo para usar (`chmod 700`) para desplegar en la instancia monitoreada.

Los datos del modo Extendido son proporcionados por la aplicación [nextcloud/serverinfo](https://github.com/nextcloud/serverinfo), que debe estar instalada y habilitada en la instancia monitoreada.

**Comportamiento de respaldo**: si la API Extendida no es accesible (error de conexión, token inválido, aplicación no instalada), NcStatusCheck vuelve automáticamente a `/status.php` para recuperar al menos la versión de Nextcloud.

**Umbral de obsolescencia Push**: un servidor Push se considera desactualizado si no se han recibido datos dentro de `auto_push_interval + 30 minutos`. El intervalo Push predeterminado es de 12 horas.

### Columnas de la tabla del panel principal

El panel principal muestra 5 columnas: **Servidor** | **Versión de NC** | **PHP** | **Sondas** | **Salud**

La columna **Sondas** muestra los modos de recopilación activos para cada servidor:
- Insignia `⚡ Extended` (púrpura, se vuelve naranja en error de conexión o datos desactualizados)
- Insignia `📡 Push` (azul, se vuelve naranja cuando no se reciben datos dentro del umbral)
- Ambas insignias pueden aparecer simultáneamente si ambos modos están activos
- Sin insignia = solo modo Básico

### Columna Salud

La columna Salud solo muestra algo cuando hay algo sobre lo que actuar:

| Indicador | Insignia | Significado |
|-----------|----------|-------------|
| Desconectado | `🔴 Offline` | Instancia inalcanzable (falló la sonda HTTP), con "offline por X" |
| Advertencias activas | `⚠️ N` | N problemas de configuración |
| Auditoría de aplicaciones | `📦 N` | N aplicaciones instaladas a revisar (bloquean actualización/incompatibles) |
| Caducidad SSL | `🔒 N d` | El certificado caduca pronto — naranja `< 15d`, rojo `< 7d` o caducado |
| Actualizaciones Docker | `🔄 M` | M actualizaciones de contenedores disponibles |
| Todo bien | *(vacío)* | Nada que informar |
| Sin datos | `?` | Modo Básico sin datos Push |

#### Arriba/abajo y caducidad SSL

NcStatusCheck mantiene un estado arriba/abajo **mínimo** por servidor (solo estado actual + fecha del último cambio — sin series temporales, ni página de historial). "Arriba" significa que la sonda HTTPS saliente alcanzó la instancia; una insignia roja **Offline** aparece solo cuando está abajo. Durante esa misma sonda HTTPS, se lee la **caducidad del certificado SSL** de forma gratuita (`CURLOPT_CERTINFO`) y se muestra cuando se acerca. Ambos son visibles en detalle en la página de detalles. *Nota: estas comprobaciones salientes no se aplican a instancias solo Push con las que el monitor nunca se contacta.*

#### Auditoría de aplicaciones (`📦`)

Cuando un servidor Push informa sus aplicaciones instaladas (`occ app:list`, script Push v3+), NcStatusCheck las contrasta con el catálogo de la tienda de aplicaciones de Nextcloud y marca las aplicaciones que vale la pena revisar. **Solo señalización** — la herramienta nunca deshabilita nada; muestra candidatos (no puede saber si una aplicación se usa realmente). Solo se utilizan señales **fácticas y binarias**. La insignia `📦 N` cuenta hallazgos bloqueantes (sin versión compatible para la versión actual de NC, sin versión para NC N+1 → bloquea la actualización, o una aplicación de prueba/desarrollo dejada habilitada en producción). Los hallazgos informativos (aplicación desactualizada en la instancia, abandonada upstream, incompatible con PHP) se muestran solo en la página de detalles. Los hallazgos pueden silenciarse mediante el mismo mecanismo de reconocimiento que las advertencias.

### `servers.json` formato```json
[
  {"url": "https://cloud.example.com"},
  {"url": "https://cloud2.example.com", "serverinfo_token": "abc123def456"},
  {"url": "https://cloud3.example.com", "serverinfo_token": "...", "push_token": "xyz789"}
]

🚀 Instalación

Requisitos previos

  • PHP 8.1+ con extensiones cURL y JSON — ese es el nivel mínimo de sintaxis contra el que se ejecutan las pruebas CI, no una recomendación de implementación: tanto 8.1 como 8.2 ya han pasado su fecha de finalización del soporte de seguridad, use una versión con soporte actual (8.3+ al momento de escribir esto) para cualquier cosa expuesta a Internet
  • Servidor web nginx o Apache con HTTPS
  • Acceso de red a los servidores Nextcloud para monitorear

Configuración del servidor web (nginx)```nginx

server { server_name monitoring.your-domain.com; root /var/www/ncstatuscheck; index index.php;

root@kitploit:~
# HTTP Basic Authentication
auth_basic "Monitoring Access";
auth_basic_user_file /etc/nginx/.htpasswd;

# Protect sensitive files/dirs (tests/run.php has no CLI-only guard — it must
# never be reachable over HTTP; same blocklist as deploy/docker/nginx.conf)
location ~ ^/(cache/|\.git|deploy/|tools/|tests/) {
    deny all;
    return 404;
}

# .txt covers servers.txt (legacy server list — real monitored URLs)
location ~* \.(log|json|txt)$ {
    deny all;
    return 404;
}

# Security headers for static HTML pages (admin.html, template.html).
# PHP pages (index.php, detail.php) send the same headers themselves
# via send_security_headers() in lib/auth.php.
location ~* \.html$ {
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options DENY always;
    add_header Referrer-Policy no-referrer always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'" always;
    try_files $uri =404;
}

# Standard PHP configuration (adjust the socket to your PHP version —
# use a security-supported one: 8.2 has been EOL since December 2025)
location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.4-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

location / {
    try_files $uri $uri/ =404;
}

}

root@kitploit:~
> **Apache**: el repositorio incluye archivos `.htaccess` que reflejan las reglas `deny`
> anteriores (raíz: bloquea `*.log`/`*.json`/`*.txt` y `.git`; `cache/`, `tools/`,
> `deploy/`, `tests/`: `Require all denied`). Solo funcionan si el vhost establece
> `AllowOverride FileInfo AuthConfig` (o `All`) — el valor predeterminado de Debian para
> `/var/www` es `AllowOverride None`, en cuyo caso replica las reglas directamente en el
> vhost. La autenticación básica HTTP aún debe configurarse en el vhost de cualquier manera.

### Despliegue

1. **Clonar el repositorio**```bash
git clone https://gitlab.com/jp.louvel/ncstatuscheck.git
cd ncstatuscheck
  1. Configuración Crea tu archivo de configuración desde la plantilla:```bash cp config-example.php config.php
root@kitploit:~
Edite `config.php` y ajuste las rutas y URL a su entorno:```php
define('MONITOR_PATH', '/var/www/ncstatuscheck');
define('MONITOR_URL', 'https://monitoring.your-domain.com'); // your public URL
define('CACHE_DIR', MONITOR_PATH . '/cache');
  1. Añadir servidores

Los servidores se administran directamente desde la interfaz de administración (botón ⚙️ Admin). También puedes crear servers.json manualmente:```json [ {"url": "https://cloud.example.com"}, {"url": "https://nextcloud.mycompany.org", "serverinfo_token": "your_token_here"} ]

root@kitploit:~
> **Migración desde `servers.txt`**: si existe un archivo `servers.txt`, se convierte automáticamente a `servers.json` en el primer acceso. Luego puedes eliminar `servers.txt`.

4. **Establecer permisos**

nginx/PHP-FPM se ejecutan como su propio usuario (`www-data` en Debian/Ubuntu, `nginx`/`apache` en la familia RHEL — ajusta a continuación) — si clonaste como tu propio usuario de inicio de sesión, ese usuario casi con certeza no será `www-data` ni estará en su grupo, por lo que `chmod` solo deja al servidor web **sin acceso alguno**, ni siquiera de lectura (cada solicitud 403/404s):```bash
chown -R www-data:www-data /var/www/ncstatuscheck   # adjust the user:group to your distro

chmod 750 /var/www/ncstatuscheck
chmod 750 cache img

chmod 640 *.php *.html *.js *.css *.md
chmod 600 config.php servers.json servers.txt   # secrets / serverinfo & push tokens
chmod 660 cache/*.json cache/*.log

Si servers.json aún no existe (estás dejando que la interfaz de administración lo cree en lugar del paso manual anterior), el chmod 600 de arriba simplemente no tiene nada sobre lo que actuar — eso está bien: ServersStore::save() cambia los permisos del archivo a 0600 por sí mismo en cada escritura, por lo que un servers.json (re)creado a través de la interfaz de administración nunca permanece legible para el grupo/mundo con tokens de información del servidor/push dentro.

  1. Autenticación HTTP```bash htpasswd -c /etc/nginx/.htpasswd admin
root@kitploit:~
6. **Tareas programadas (opcional)**

Dos crons complementarios — instala ambos **en la misma llamada `crontab -`**:
`crontab -` instala un crontab completamente nuevo desde stdin, no agrega, por lo que ejecutarlo dos veces (una por línea) deja solo el *segundo* trabajo — el primero desaparece silenciosamente, sin error. Esto también conserva cualquier cosa ya existente en tu crontab (piping `crontab -l` primero) en lugar de borrarlo:```bash
(crontab -l 2>/dev/null; cat <<'EOF'
# Full collection (NC/PHP versions, serverinfo, app-store catalog) — twice a day
0 6,18 * * * cd /var/www/ncstatuscheck && php cron-update.php
# Lightweight reachability probe (status.php only -> up/down state) — every 5 min
*/5 * * * * cd /var/www/ncstatuscheck && php cron-ping.php
EOF
) | crontab -

Si se vuelve a ejecutar, se añadirán duplicados si estas líneas ya están presentes; compruebe primero con crontab -l si no está seguro.

cron-ping.php es intencionadamente mínimo: solo comprueba el status.php de cada instancia y actualiza el estado activo/inactivo (cache/uptime_state.json), por lo que puede ejecutarse con frecuencia sin carga. Una instancia solo se marca como inactiva después de UPTIME_FAIL_THRESHOLD sondas fallidas consecutivas (por defecto 2 → ~10 min con una cadencia de 5 min); la recuperación a activa es inmediata. El cron-update.php completo permanece sin cambios para todo lo demás.

Docker (alternativa a instalación directa)

En lugar de los pasos 1–6 anteriores, NcStatusCheck también puede ejecutarse como un pequeño docker compose stack (PHP-FPM + nginx + un contenedor cron) — el repositorio se monta por bind tal cual, sin paso de compilación ni Composer, por lo que refleja exactamente la estructura de instalación directa, solo que contenerizada. Sirve solo HTTP simple (puerto 8080 por defecto) — coloque su propio proxy inverso de terminación TLS al frente.

La configuración completa — los detalles de permisos (uid 82, pre-creación de servers.json), autenticación HTTP Basic, cron, actualizaciones y copias de seguridad — se encuentra íntegramente en deploy/docker/README.md. Empiece por allí; esta sección es intencionadamente solo una referencia, para evitar mantener dos copias de los mismos pasos sincronizadas.

📋 Uso

Interfaz principal

  • Vaya a https://monitoring.su-dominio.com
  • Vea el panel con el estado de todos sus servidores
  • Use filtros para reducir por estado o búsqueda
  • Consulte las versiones oficiales y el calendario de lanzamientos

Administración

  • Abra la interfaz de administración mediante el botón "⚙️ Admin"
  • Una tabla resumen de modos de sonda en la parte superior de la página explica las diferencias entre los métodos de recolección Básico, Extendido y Push
  • Gestión de servidores: cada servidor se muestra como una tarjeta con dos zonas de sonda plegables:
    • Zona Serverinfo: configure el token de lectura (NC → NcStatusCheck pull)
    • Zona Push: genere un token push y descargue el script cron listo para usar para la instancia remota
  • Configuración de Nextcloud: establezca versiones seguras mínimas por rama (efectos hover en las filas)
  • Configuración de PHP: establezca estados recomendados/soportados por versión

Página de detalle

Accesible haciendo clic en cualquier nombre de servidor o su indicador de Salud.

Para servidores Básicos (sin sonda Extendida ni Push), se muestra una página simplificada con los datos disponibles (versión NC, servidor web, protocolo HTTP) con un aviso y una sugerencia para activar una sonda.

Para servidores Extendidos / Push, la página de detalle completa muestra secciones separadas:

API

NcStatusCheck expone varios endpoints REST:

API principal (api.php)

  • GET ?action=get_data — Obtener datos (caché o actualización)
  • POST ?action=refresh_data — Forzar actualización de todos los servidores

API Push (push-api.php)

  • POST con cabecera push_token — Recibir datos push de una instancia NC remota
  • POST ?action=request_push_all — Solicitar un push inmediato de todos los servidores push configurados (establece una bandera de activación consumida por el script cron remoto)

El script cron generado por la interfaz de administración se divide en dos partes: un núcleo genérico /usr/local/bin/ncstatuscheck-push.sh — idéntico en cada servidor (toda la lógica) — controlado por una pequeña configuración por instancia /etc/ncstatuscheck/<slug>.conf (SERVER_URL, SLUG, OCC_CMD, DOCKER_ENABLED, SKOPEO_ENABLED). Se invoca como ncstatuscheck-push.sh /etc/ncstatuscheck/<slug>.conf [--test]. El núcleo se niega a leer una configuración escribible por grupo/mundo (anti-inyección de código).

Es multi-destino (fan-out): los datos se recogen una vez y se envían a cada monitor listado en /etc/ncstatuscheck/targets-<slug>.conf (una línea url|push_token[|http_user|http_pass] por monitor). Cada administrador de monitor emite un comando idempotente para registrarse.

Múltiples instancias de Nextcloud en un mismo host: las rutas por instancia se sufijan con un derivado de la URL monitorizada (ej. → ): , , , , estado . Solo el núcleo se comparte, por lo que las instancias co-ubicadas nunca colisionan.

API de detalle (detail-api.php)

  • GET ?server=<url> — Datos completos de serverinfo + advertencias calculadas para un servidor Extendido/Push

APIs de administración

  • admin-api.php — Configuración de versiones
  • servers-admin-api.php — Gestión de servidores (get_servers, add_server, remove_server, update_server_token, generate_push_token, remove_push_token)
  • nextcloud-versions-api.php — Versiones oficiales

🩺 Auditoría de servidor (nc-audit.sh)

Un subsistema independiente de la monitorización: un script bash solo lectura independiente (tools/nc-audit.sh) ejecutado como root en un servidor Nextcloud para una auditoría única / mensual de la sintonización web + PHP + base de datos, contrastada con la capacidad física de la máquina (RAM, CPU, tipo de disco). Orientado a una oferta de supervisión gestionada: el cliente lo instala, el monitor solo recibe informes — sin necesidad de acceso a la máquina/red. El script solo lee la configuración (no hace cambios), imprime un informe en color y escribe una copia en /tmp.

Qué comprueba: capacidad del servidor (RAM/CPU/SSD-HDD, swappiness, detección de servidor compartido) · Nextcloud (versiones, cron, caché, Redis en tiempo de ejecución, tipo de BD, registros) · PHP/PHP-FPM (SAPI de servicio real, OPcache en tiempo de ejecución, memoria multi-pool) · Apache (memoria de trabajador consciente de MPM) · Nginx · PostgreSQL · MariaDB · higiene de seguridad (fail2ban o CrowdSec + bouncer + blocklist comunitaria; actualizaciones pendientes / reinicio / servicios con librerías obsoletas) · conciliación de presupuesto de RAM (InnoDB + FPM + Apache vs RAM real) · análisis profundo con herramientas opcionales si ya están presentes (mysqltuner, pt-variable-advisor, apache2buddy, sar/iostat).```bash

Download (the page distributes it; the repo raw URL is public)

curl -fsSL https://gitlab.com/jp.louvel/ncstatuscheck/-/raw/master/tools/nc-audit.sh -o /usr/local/bin/nc-audit.sh chmod 700 /usr/local/bin/nc-audit.sh

sudo nc-audit.sh # auto-detect, dedicated server sudo nc-audit.sh /var/www/nextcloud # explicit path (or NC_PATH=…) sudo NC_RAM_BUDGET_PCT=50 nc-audit.sh # shared host: size to 50% of RAM

root@kitploit:~
**Hosts de múltiples instancias** (varios Nextclouds + una base de datos compartida). `NC_RAM_BUDGET_PCT`
es entonces el **total** del presupuesto de la pila; `NC_PHP_SHARE_PCT`% del mismo (por defecto 60, el resto
cubre DB + web + SO — reduzca en servidores con mucha carga de DB) es la participación de PHP, dividida entre
los pools de FPM por **peso** (una importancia relativa — no un porcentaje, no MB) para dar un
objetivo `pm.max_children` por pool:```
target = PHP_share × (weight / Σ weights) / ~50 MB per process

El objetivo es un techo que el presupuesto permite, no un valor que debas establecer (solo eleva un grupo que realmente sature). Los pesos son tu decisión — la herramienta nunca los adivina.```bash

Weights you provide (a human judgment — the tool never guesses them):

sudo NC_RAM_BUDGET_PCT=70 NC_INSTANCES="poolA:4,poolB:2,poolC:1" nc-audit.sh

Interactive helper (terminal only): lists the pools, asks a weight for each,

prints the targets + a reusable NC_INSTANCES line:

sudo NC_RAM_BUDGET_PCT=70 nc-audit.sh --tune-fpm

root@kitploit:~
**Informe de retroceso** (opcional, reutiliza la infraestructura Push): `nc-audit.sh --push
/etc/ncstatuscheck/<slug>.conf` ejecuta la auditoría y envía POST del informe al(los)
monitor(es), que lo almacenan y lo muestran en la página de detalle del servidor (sección "🩺 Auditoría del servidor"). Típicamente un cron mensual. La página web (admin, beta) en
`audit.php` distribuye el script (descarga + inline + one-liner de GitLab) y muestra su
versión.

> **Las herramientas de análisis profundo nunca son instaladas** por el script — solo se ejecutan si
> ya están presentes (sin `curl | bash`, sin autoinstalación), cada una limitada por `timeout`.

## 🔧 Configuración avanzada

### Personalización de reglas de versión

Las reglas de evaluación son configurables a través de la interfaz de administración:

**Estados de Nextcloud:**
- `dev` — Versión de desarrollo
- `stable` — Versión estable actual
- `oldstable` — Versión estable anterior compatible
- `deprecated` — Versión obsoleta

**Estados de PHP:**
- `recommended` — Versión recomendada
- `supported` — Versión compatible
- `deprecated` — Versión obsoleta

### Variables de configuración

Edite `config.php` para adaptar la configuración:```php
// Environment: 'dev' or 'prod'
define('ENV', 'prod');

// Paths and URLs
define('MONITOR_PATH', '/var/www/ncstatuscheck');
define('MONITOR_URL', 'https://monitoring.your-domain.com');

// Main server cache duration
define('CACHE_MAX_AGE', 86400); // 24 hours

// Official Nextcloud versions cache duration
define('VERSIONS_CACHE_AGE', 86400);

// Consecutive failed probes before a server is marked "down" (min 1)
define('UPTIME_FAIL_THRESHOLD', 2);

// Proactive alerts — webhook on a confirmed up/down state change.
// Empty URL = disabled. Format: 'slack' (default, also Mattermost/Google Chat),
// 'discord', or 'raw' (structured JSON). The URL usually carries a secret, so it
// is never logged in full — see config-example.php for details.
define('ALERT_WEBHOOK_URL', '');
define('ALERT_WEBHOOK_FORMAT', 'slack');

// Check alerts on top of up/down (cron-update cadence, 2×/day): SSL expiry
// tiers, vulnerable (below min_secure) or deprecated Nextcloud version, stale
// Push data, critical audit report, blocking apps-audit finding. Edge-triggered with a persisted state
// (cache/alerts_state.json): one alert per NEW condition, no reminders, re-arms
// when resolved (renewed cert, fixed/acked app…). First run arms silently.
define('ALERT_CHECKS', 'ssl,version,push_stale,audit,apps'); // '' = up/down only
define('ALERT_SSL_DAYS', '30,14,7');                          // days-left tiers

// Email channel, independent of the webhook (either one arms the alerting).
// One digest mail per batch. Recommended transport: direct SMTP submission to
// your mail server (vendored PHPMailer, lib/phpmailer/ — nothing to set up on
// the host). Without ALERT_SMTP_HOST it falls back to PHP mail() (local MTA).
define('ALERT_EMAIL_TO', '');    // comma list of recipients, '' = off
define('ALERT_EMAIL_FROM', '');  // default: ncstatuscheck@<hostname>
define('ALERT_SMTP_HOST', '');   // e.g. 'mail.example.org', '' = mail() fallback
define('ALERT_SMTP_PORT', 587);
define('ALERT_SMTP_SECURITY', 'starttls'); // 'starttls' | 'tls' | 'none'
define('ALERT_SMTP_USER', '');
define('ALERT_SMTP_PASS', '');

Vea config-example.php para la lista completa y comentada de opciones (incluyendo DEMO_MODE y PUSH_SCRIPT_VERSION).

🛡️ Seguridad

Medidas implementadas

  • Autenticación básica HTTP obligatoria, duplicada por una verificación de autenticación a nivel de aplicación en cada endpoint de administración (defensa en profundidad)
  • Protección CSRF: token HMAC inyectado automáticamente en cada solicitud mutante (lib/csrf-client.js + csrf_require())
  • Guardia anti-SSRF en cada URL proporcionada por el operador (loopback, RFC1918, link-local rechazados; redirecciones solo HTTPS; verificación de IP posterior a la conexión)
  • HTTPS requerido con certificados Let's Encrypt
  • Protección de archivos de datos y registros: reglas de nginx (ver arriba) reflejadas por archivos .htaccess incluidos para Apache; servers.json con chmod 0600 automáticamente (tokens dentro)
  • Encabezados de seguridad (CSP, X-Frame-Options, nosniff, Referrer-Policy) en cada página servida por PHP
  • Validación estricta de URL en todas las entradas
  • Scripts de cliente ejecutados como root: la configuración de la instancia se carga como root y el archivo de destinos decide dónde se envían los datos recolectados — ambos son rechazados a menos que no sean escribibles por grupo/mundo ni propiedad de un tercero
  • Aislamiento entre instancias monitoreadas: un push solo se acepta cuando la URL en el cuerpo coincide con una entrada Y pasa en el token de entrada, por lo que un servidor monitoreado comprometido no puede leer ni sobrescribir los datos de otro. / están protegidos por autenticación de administrador + CSRF. Verificado de extremo a extremo contra un escenario de cliente comprometido

Recomendaciones

  • Use contraseñas seguras para la autenticación HTTP
  • Restrinja el acceso a direcciones conocidas — la pestaña de filtrado de IP de administración genera las reglas por usted (ver más abajo)
  • Monitoree los registros en busca de intentos de intrusión
  • Mantenga PHP y las dependencias del sistema actualizadas

Banner de estado de config.php (admin)

config.php está en .gitignore y se edita manualmente por servidor, por lo que se desvía — silenciosamente, ya que casi todas las constantes tienen un valor alternativo en el código. Un banner en la parte superior de la página de administración informa qué está realmente mal, y solo cuando algo lo está: un PUSH_SCRIPT_VERSION dejado atrás por un incremento, ningún transporte de alertas configurado, una etiqueta de cierre final que emite un byte antes de cualquier header(), un directorio de caché no escribible, constantes ausentes que caen silenciosamente a valores predeterminados.

Solo lectura por diseño y sin acción de guardado, por la misma razón que la pestaña de Notificaciones: config.php es propiedad de root y contiene secretos. El contenido del archivo nunca viaja — solo información sobre él — y ningún secreto se lee.

Filtrado de IP (pestaña de administración)

Todo lo anterior es a nivel de aplicación: cualquiera en Internet aún puede alcanzar el monitor y sondearlo, y solo la contraseña los detiene. La pestaña de filtrado de IP genera las reglas que colocan una lista blanca delante de la aplicación, por lo que los hosts desconocidos no pueden hablar con ella en absoluto. Es defensa en profundidad, no un reemplazo para la autenticación básica o los tokens de push — y solo produce texto para revisar y pegar, nunca escribe una configuración de servidor web o cortafuegos.

Dos clases de fuente, deliberadamente desiguales, para que un servidor monitoreado comprometido no pueda alcanzar la administración:

ClaseQuiénPuede alcanzar
pushinstancias monitoreadas solo en modo Push/push-api.php, nada más
adminbastión / VPN / IP de oficina fijatodo

Las instancias consultadas en modo Básico/Extendido no abren ninguna conexión entrante y no obtienen ninguna entrada en la lista blanca.

Las direcciones provienen de dos fuentes, y la diferencia importa: el registro DNS de un dominio monitoreado es su dirección de ingreso, mientras que su push sale desde su egreso. Donde difieren, solo la segunda funciona. Por lo tanto, push-api.php registra la dirección de origen real de cada push (source_ip en la caché de push), y la pestaña la agrega a la lista blanca, informando la discrepancia. Hasta que un servidor haya hecho push una vez, recurre a DNS A+AAAA y lo indica.

Tres salidas:

  • nginx (recomendado) — un archivo conf.d autónomo (geo + map) más una sola línea if ($ncsc_forbidden) { return 403; } en el vhost. No es necesario duplicar el bloque fastcgi, los archivos estáticos también están cubiertos (admin.html es uno), y /.well-known/acme-challenge/ permanece abierto para que la renovación de certificados no se rompa silenciosamente.
  • Apache 2.4 — <LocationMatch> con una anticipación negativa más un <Location> para el endpoint de push, para que las dos secciones no se superpongan y nada dependa del orden de fusión de Apache. Todas las direcciones de una regla van en una línea Require ip: varias líneas dentro de <RequireAll> se combinan con AND, lo que nadie puede satisfacer.
  • ufw — tosco por naturaleza (un filtro de paquetes ve puertos, no URL), por lo que no puede expresar la división push/admin. Úselo solo como capa exterior.

El generador se niega a emitir algo cuando no se proporciona ninguna dirección de administración, advierte cuando la propia dirección del operador no está cubierta, y advierte cuando la solicitud llegó a través de un proxy (tanto geo como Require ip leen el peer de transporte, por lo que detrás de un proxy todos los clientes se ven iguales). El fragmento de ufw generado coloca la regla SSH primero, mantiene el puerto 80 abierto para el desafío HTTP-01, y detalla la trampa de IPv6: a diferencia de nginx, que rechaza una dirección v6 no listada, ufw no filtra v6 en absoluto a menos que IPV6=yes esté configurado — un host de doble pila estaría de otro modo completamente abierto a través de IPv6.

Limitación conocida, mostrada en la propia página: una vez aplicadas las reglas, esta pestaña no descubre nada nuevo. Un push rechazado es rechazado por el servidor web antes de que llegue a PHP, por lo que la dirección registrada permanece como la última que logró pasar — y aún parece verificada. Dos consecuencias: agregar un servidor Push significa regenerar y reaplicar las reglas, o su primer push será rechazado; y si la dirección de una instancia cambia, la nueva solo es legible en el registro de acceso del servidor web (grep 'push-api.php' access.log | grep ' 403 '). Por lo tanto, la pestaña muestra la fecha de última vista de cada dirección observada y la marca una vez que es más antigua que un ciclo completo de push perdido — el mismo umbral que la alerta push_stale, que cubre el mismo punto ciego desde el otro lado.

Distinguir un problema de filtrado de cualquier otro: un GET simple en el endpoint de push separa las capas limpiamente, sin efecto secundario y sin necesidad de token — ejecútelo desde la máquina en cuestión, ya que lo que se juzga es la dirección de salida de esa máquina:```bash curl -sS -o /dev/null -w '%{http_code}\n' https://your-monitor/push-api.php

root@kitploit:~
| Respuesta | Significado |
|---|---|
| `403` | bloqueado por el filtrado de IP |
| `401` | filtrado superado, Basic auth está respondiendo — el problema está en otro lado |
| `405` | la solicitud llegó a la aplicación (GET no es un método aceptado allí) |
| nada / timeout | no es el filtrado: un filtro responde, no se queda en silencio |

Vuelva a ejecutar con `-u usuario:contraseña` para salir de dudas ante un `403`: si el código no se mueve, realmente es el filtrado. Verificado tanto en nginx como en Apache (incluso con `Require valid-user` activado), el filtro responde *antes* de la autenticación — y un `403` proveniente de la propia aplicación siempre lleva JSON en el cuerpo.

La lógica de los fragmentos reside en `lib/hardening-rules.php`, que es puro y está cubierto por `tests/run.php`: los fragmentos son el producto aquí, y uno incorrecto o bloquea al operador o deja un agujero. Tanto la salida de nginx como la de Apache han sido verificadas conductualmente (servidores reales, direcciones de origen reales, incluidos intentos de path-traversal de la clase `push`).

### Análisis automatizado (etapa `security` del CI)

El escaneo de dependencias (`npm/pnpm audit`, Snyk Open Source, Dependabot) no tiene efecto aquí: no hay `package.json` ni `composer.json` — no hay nada que escanear. El riesgo reside en el código personalizado (~15k líneas de PHP, ~6k de JS) y en los scripts de shell que se ejecutan **como root** en las instancias monitoreadas (`tools/*.sh`). El pipeline está orientado hacia allí:

| Trabajo | Herramienta | Bloqueante | Alcance |
|---|---|---|---|
| `secrets_scan` | gitleaks | sí | secretos confirmados (working tree) |
| `sast_semgrep` | semgrep (`p/php`, `p/javascript`, `p/owasp-top-ten`) | sí | SSRF, authz/CSRF faltante, XSS |
| `shellcheck` | shellcheck (`--severity=warning`) | sí | `tools/*.sh` — root en hosts cliente |
| `dockerfile_misconfig` | trivy misconfig | sí | `deploy/docker/` |
| `container_cve` | trivy image | no (`allow_failure`) | la imagen que `deploy/docker` construye, más `nginx:alpine` |
| `ui_tests` | node (sin dependencias) | sí | invariantes de escape de `lib/ui-common.js` (ambas regresiones XSS pasadas) |
| `phpmailer_freshness` | GitHub API | no (`allow_failure`) | pin vendido vs versión upstream |
| `deploy_selfcheck` | nc-selfcheck.sh | sí | el conjunto de reglas de nginx enviado (reglas de denegación + cabeceras de seguridad) levantado en un contenedor desechable |

Todos los trabajos bloqueantes tienen una **línea base de cero hallazgos**, por lo que cualquier nueva alerta es una señal real. Dos decisiones deliberadas, documentadas en línea en `.gitlab-ci.yml`:

- **`php.lang.security.injection.echoed-request` está excluido** de semgrep: marca cada `echo json_encode()` como XSS, que es lo que cada endpoint de la API hace legítimamente aquí (respuestas JSON, no HTML). Representó 10 de 10 hallazgos en la primera ejecución, todos falsos positivos. Mantenerlo entrenaría a todos a ignorar el trabajo.
- **Los dos trabajos con `allow_failure` reportan hechos upstream** (un CVE en `nginx:alpine` o uno cuya corrección aún no ha llegado a la rama de Alpine, una nueva versión de PHPMailer) que una solicitud de fusión no puede solucionar. Rojo pero tolerado es la señal precisa — "momento de reconstruir / actualizar el vendoring" — no una razón para bloquear trabajo no relacionado. `phpmailer_freshness` reporta una API de GitHub inalcanzable o con límite de tasa como un *salto*, nunca como "desactualizado".
- **`container_cve` escanea la imagen que construye, no la etiqueta `FROM`.** El Dockerfile endurece la base con `apk --no-cache upgrade` (la imagen oficial de PHP va por detrás de los repositorios de Alpine — envió c-ares 1.34.6-r0 mientras que 1.34.8-r0, que corrige CVE-2026-33630, ya estaba publicado). Escanear la etiqueta base reportaría, por lo tanto, CVEs que la imagen enviada ya no tiene: un trabajo permanentemente naranja que nadie lee.

Las listas blancas son intencionalmente estrechas: `.gitleaks.toml` excusa cadenas de marcador de posición **literales**, nunca archivos de documentación completos (incluir `README.md` en la lista blanca cegaría el escaneo el día que se pegue un secreto real dentro) — por lo tanto, un nuevo token de ejemplo en la documentación debe agregarse allí. `.trivyignore` contiene una sola entrada, `DS-0002`, argumentada en el archivo: el maestro de php-fpm debe iniciar como root para lanzar sus workers a `www-data` (uid 82).

### Verificación posterior al despliegue (`nc-selfcheck.sh`)

El CI puede bloquear la configuración *enviada* (el trabajo `deploy_selfcheck` anterior levanta el conjunto de reglas de nginx en un contenedor y lo sondea), pero no puede verificar el servidor al que realmente desplegó — host diferente, credenciales de Basic-auth, permisos del sistema de archivos. `tools/nc-selfcheck.sh` cierra esa brecha. Es un script bash independiente y de solo lectura (mismo modelo que `nc-audit.sh`) que se ejecuta después de cada despliegue:```bash
# Black-box, no credentials: confirms Basic auth is enforced (401) and that
# sensitive files are blocked (cache/, servers.*, .git, config.php source).
bash tools/nc-selfcheck.sh https://monitoring.example.com

# + security headers behind Basic auth:
bash tools/nc-selfcheck.sh -u user:pass https://monitoring.example.com

# + filesystem checks (run ON the host): servers.json / config.php / CSRF-secret
# permissions, and a stray closing "?>" in config.php.
bash tools/nc-selfcheck.sh --webroot /var/www/ncstatuscheck https://monitoring.example.com

Sale con un código distinto de cero ante cualquier hallazgo crítico (fuga de fuente, archivo secreto no bloqueado, almacén de tokens legible por todos, falta de autenticación Basic), por lo que puede bloquear un despliegue — intégralo en tu script de sincronización/despliegue como un paso posterior. WARN/INFO nunca fallan la ejecución.

🧪 Pruebas y desarrollo

Modo de desarrollo```php

// In config.php define('ENV', 'dev');

root@kitploit:~
En modo de desarrollo, se muestra información adicional (versión de PHP, servidor web).

### Pruebas del servidor
Utilice la interfaz de administración para añadir un servidor por URL. El servidor será consultado en la siguiente actualización de datos.

### Registros de depuración
Revise los archivos de registro en `cache/`:
- `monitor.log` — Registros generales de la aplicación
- `cron.log` — Registros completos del script de recolección (`cron-update.php`)
- `ping.log` — Registros de sondeos ligeros de subida/bajada (`cron-ping.php`)
- `alerts.log` — Despacho proactivo de alertas (webhook/correo electrónico), nunca registra secretos de webhook ni credenciales SMTP

### Suite de pruebas```bash
php tests/run.php   # plain-PHP assertions, no framework — exit 0 = all green

Cubre la lógica de negocio pura (reglas de versión/aplicaciones, advertencias, máquina de estados de tiempo de actividad y disponibilidad, máquina de estados de desduplicación/rearme de alertas, constructores de correos electrónicos).

🤝 Contribución

Reportar un error

Abre un nuevo issue con:

  • Una descripción detallada del problema
  • Pasos para reproducir
  • Registros de errores si están disponibles
  • Tu configuración de entorno

Proponer una mejora

  1. Abre un issue para discutir tu idea
  2. Haz un fork del proyecto
  3. Crea una rama para tu funcionalidad
  4. Implementa con documentación
  5. Envía una solicitud de merge

📝 Licencia

Este proyecto está licenciado bajo GNU AGPL v3.

👥 Créditos

NcStatusCheck es desarrollado por ézéo, una cooperativa digital especializada en soluciones de código abierto.

Contribuyentes

  • Equipo ézéo — Desarrollo inicial y mantenimiento

¿Necesitas ayuda? Consulta los issues o contacta al equipo de ézéo.

Descargar herramienta
SecciónCampos
Sistema NextcloudVersión, modo debug, memcache local/distribuido, bloqueo de archivos, espacio en disco
PHPVersión, memory_limit, upload_max_filesize, max_execution_time, FPM, OPcache
Servidor webNombre + versión, protocolo HTTP
Base de datosTipo, versión, tamaño
CachéRedis, tasa de aciertos de APCu
Usuarios activosÚltimos 5 min, 1 h, 24 h, 7 días
<slug>
latest.ezeo.coop
latest_ezeo_coop
<slug>.conf
/etc/cron.d/ncstatuscheck-<slug>
targets-<slug>.conf
ncstatuscheck-push-<slug>.log
…-<slug>.<md5>.last

Nextcloud ejecutándose en Docker (imagen oficial, compose, AIO): completamente soportado — el script se instala en el host (cron root + acceso al demonio Docker), nunca dentro del contenedor, y occ se ejecuta a través de docker exec: OCC_CMD=docker exec -u www-data <container> php occ (contenedor AIO: nextcloud-aio-nextcloud). El generador de script de administración tiene un tipo de instalación predefinido que rellena esto. Nunca añada -t (sin TTY bajo cron); mantenga -u www-data (la imagen oficial rechaza occ como root).

Despliegue / actualizaciones en flota: como el núcleo es un único archivo idéntico, actualizar la lógica en muchos servidores = reemplazar ese único archivo (el marcador ↑ señala servidores que ejecutan una versión anterior). Consulte deploy/ansible/ para un playbook listo para usar (o un simple bucle scp). El monitor permanece pasivo — nunca envía código a la flota; el ancla de confianza es su propio acceso SSH, no el monitor.

Migración desde una instalación pre-v4 (script monolítico por instancia): elimine el antiguo /usr/local/bin/ncstatuscheck-push-<slug>.sh y /etc/cron.d/ncstatuscheck-<slug> antes de instalar el núcleo + configuración (el targets-<slug>.conf se reutiliza tal cual), de lo contrario realizará un doble envío.

hash_equals()
esa
request_push
request_push_all
  • Reporte de destinos de push: cada instancia declara a qué monitores envía push (solo URLs, nunca tokens); la página de detalle las muestra y se dispara una alerta cuando el conjunto cambia — una línea adicional en targets.conf copia silenciosamente cada push a un tercero de otro modo
  • Sanitización de payload de push: los IDs de aplicación están en una lista blanca de caracteres; los campos libres de Docker (nombre, imagen, versión, estado) se limpian de <>"'& en la ingesta, además del escape en tiempo de renderizado
  • Verificación SSL/TLS para conexiones salientes — nunca deshabilitada, incluyendo el transporte de alertas SMTP
  • Respuestas remotas acotadas (2 MB): un servidor monitoreado controla completamente lo que responde y nada autentica esa dirección. Sin límite, un servidor que solo transmite datos agota la memoria de PHP — un error fatal que ningún try/catch puede capturar, lo que mataría la ejecución de la recolección a mitad del bucle y, con ella, todas las alertas para toda la flota
  • Anonimización en modo demo cubre más que la URL: nombres de contenedores, hosts de registro privado en referencias de imágenes y el nombre de host citado dentro de mensajes de error de cURL se limpian, tanto en el panel como en la página de detalle