Módulo VPSManager para WHMCS con configuración externa, acceso seguro al panel y métricas Graphite para LX.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

12 KiB

Copias de seguridad: instalación controlada y contrato

Estado: lógica validada mediante instalación controlada; integración deshabilitada al cierre. Diseño visual posterior probado localmente y pendiente de desplegar. No activación automática. Base: 1174c120dec0982b4c628a353c66cdaeab894b1e, rama original main, árbol original limpio. El HEAD remoto coincidía al consultar git ls-remote origin HEAD el 19/09/2026. Rama de trabajo: feature/client-backups-summary. No se ha hecho push ni merge.

Contratación y autorización

El propietario ha unificado las opciones en el nombre exacto Backup diario. En WHMCS 8.13.3-release.1 se observaron desde AdminServicesTabFields dos casos: marcado → clave presente, tipo PHP integer, valor original 1; desmarcado → clave presente, tipo PHP integer, valor original 0. Los IDs y evidencias particulares se mantienen fuera del repositorio público.

La regla fija exige integración habilitada con enabled === true, resolución aplicable exactamente ['Backup diario'], presencia mediante array_key_exists y valor === 1. No hay lista configurable de valores activos ni conversiones. Se deniegan 0, "1", true, 1.0, null, arrays, claves ausentes y cualquier valor desconocido. El ejemplo conserva enabled=false: la confirmación de valores no autoriza un despliegue ni valida el origen de copias.

BackupOption::applicable() resuelve únicamente los grupos vinculados al producto del servicio autorizado mediante tblhosting.packageidtblproductconfiglinks.pid/gidtblproductconfigoptions.gid. No usa LIKE, ni el primer resultado global, ni IDs de opciones para conceder acceso. Las definiciones duplicadas o no Sí/No fallan cerradas. El nombre antiguo Backup diario VPS se conserva solo en la detección de definiciones/conflictos: no tiene una regla de activación validada y no concede acceso. Si ambas claves están presentes con valores no idénticos (!==), se registra OPTION_CONFLICT con el ID y se deniega, sin elegir arbitrariamente.

La entrada es una función de módulo invocada por WHMCS. El registro ClientAreaCustomButtonArray conserva los cinco botones existentes y añade Backups solo si es elegible. La función vpsmanager_Backups vuelve a comprobarlo. Antes de caché/HTTP, BackupAccess comprueba CurrentUser, cuenta de cliente, permiso products, y pertenencia del servicio en la base de datos. No confunde el usuario delegado con el ID de la cuenta cliente. Versiones sin estas interfaces fallan de forma cerrada. La autorización efectiva del router WHMCS y sus accesos delegados debe comprobarse en la instalación real autorizada.

Instalación, sin ejecución automática

  1. Respaldar el directorio actual del módulo y la configuración privada, conservando permisos. Registrar el commit instalado y los checksums. No usar operaciones reales sobre VPS/copias como pruebas de regresión.
  2. Revisar el diff de la rama frente al commit base. Requisitos: PHP compatible con el módulo (probado 8.1.2), extensiones DOM/libxml y cURL. No instalar tests, fixtures, documentación, herramientas ni .git bajo el directorio web. Copiar únicamente el módulo y sus dependencias runtime en una ventana controlada, con la integración desactivada.
  3. Ampliar el archivo privado que ya carga Config::load() (variable O6H_VPSMANAGER_CONFIG o /etc/open6hosting/whmcs-vpsmanager.php) con la sección backups de config.example.php, manteniendo intactas las opciones de Graphite/API. Permisos ajustados al usuario PHP; nunca guardar credenciales en el repo o en URLs/comandos.
  4. Configurar el endpoint HTTPS fijo del CGI, sin query/fragmento/credenciales embebidas, y autenticación HTTP Basic sobre TLS verificado. Si la instalación usa otro mecanismo, no activar hasta adaptar/probarlo. Preferir una cuenta separada de integración si es posible, aunque conserve privilegios administrativos; de lo contrario se admite la credencial administrativa existente. Esos privilegios son un riesgo residual aceptado, no un criterio de NO_GO.
  5. Confirmar la zona horaria IANA del origen. Crear un directorio de caché privado, modo 0700, accesible al usuario PHP y fuera de todas las raíces/alias web; configurar cache_directory. Los archivos usan 0600. Directorios públicos o permisivos se rechazan; un error de caché no impide la consulta, pero registra CACHE y elimina la ventaja de caché entre peticiones. Programar limpieza administrativa de JSON antiguos en ese directorio si cambian muchos servicios/mapeos: no se incluye un cron automático.
  6. Por producto, comprobar si ya existe backuppc_host. Crear solo si falta, sin duplicados ni migraciones de dominio: texto, exclusivamente administrativo, no pedido, no factura, no campo de comunicaciones. Guardar un mapeo explícito. El código exige adminonly='on', showorder='', showinvoice='', tipo text; confirmar estos valores de esquema en la versión instalada. No modificar campos automáticamente. La plantilla completa y los emails pueden tener personalizaciones: verificar que nunca exponen el nombre ni el valor.
  7. La pareja activo/inactivo ya se observó en esta instalación y el diagnóstico fue deshabilitado y retirado, restaurando el módulo original con checksum verificado. Antes de activar, comprobar que no ha cambiado el nombre, tipo de opción ni versión/comportamiento de WHMCS. Si cambia el contrato, mantener desactivado y repetir una observación administrativa acotada; no ampliar la regla por aproximación.
  8. En la instalación real autorizada, comprobar contratado/no contratado, servicio ajeno cambiando ID, sin sesión, delegado permitido y denegado, revocación, cambio de mapeo y conflicto de nombres. Comprobar la página completa, DOM, HTML, emails y solicitudes del navegador: ninguna referencia al proveedor, host o credenciales; solo rutas WHMCS para esta función.
  9. Probar fallo del backend y aislamiento respecto a los controles existentes. Desactivar cualquier caché HTTP/CDN de páginas privadas y confirmar que nunca comparte respuestas entre cuentas. El callback añade Cache-Control: private, no-store.
  10. Activar únicamente tras superar esas comprobaciones y la revisión operativa. No iniciar, borrar, parar, descargar ni restaurar copias para validar esta lectura.

Contrato operativo de credenciales y lectura

La cuenta disponible tiene capacidades administrativas amplias. Se acepta expresamente el riesgo residual: una filtración o compromiso del servidor podría permitir acciones fuera de esta integración. Los controles del módulo limitan sus peticiones, no reducen los privilegios efectivos de esa cuenta. No se exige una cuenta de solo lectura como condición de GO.

Credenciales exclusivamente server-side, en configuración privada fuera de Git y de toda raíz/alias HTTP; nunca HTML, Smarty, JavaScript, navegador, URLs, logs ni mensajes de error. No volcar configuración, cabeceras Basic, argumentos o excepciones en instrumentación/APM; comprobar también la configuración efectiva de logs de la instalación. Preferir identidad de integración separada para poder revocarla independientemente.

La única interfaz de transporte es BackupHttp::getHostSummary($configPrivada, $hostValidado): configuración interna, sin URL o parámetros arbitrarios desde el navegador. Genera exclusivamente GET <endpoint-fijo>?host=<host-validado>. No existe interfaz genérica request/action/proxy de copias. Autenticación, permiso, pertenencia y contratación estricta preceden la lectura del campo administrativo; el host de params/GET/POST no se utiliza. No implementa start, stop/dequeue, delete, keep, restore, browse, descarga ni edición. No ejecuta enlaces, formularios o acciones del HTML y no sigue redirects.

Son NO_GO: credenciales expuestas, endpoint controlado por petición, host controlado por cliente, proxy genérico, redirects, introducción de acciones, logs con credenciales o consulta de servicios ajenos. Mantener backups.enabled=false hasta completar las demás pruebas reales de WHMCS y HTTPS y revisar sus resultados. Este cambio de contrato no autoriza despliegue.

Datos y comportamiento

Una sola petición a endpoint?host=..., exclusivamente el host administrativo validado con \A[A-Za-z0-9][A-Za-z0-9._-]{0,63}\z. No se siguen redirecciones, enlaces ni formularios. TLS verificado, límite por fragmento recibido de 2 MiB, conexión 2 s y total 5 s por defecto. Códigos HTTP distintos de 200 fallan. No hay endpoint público nuevo ni consultas del navegador al origen.

DOM/libxml analiza sin resolución externa y con LIBXML_NONET. La identidad se exige en el único h1 exacto del detalle. Las tablas se reconocen por cabeceras; tamaños exigen el grupo Totals; la unión es por número interno. Se rechazan duplicados. Las filas y tablas pueden reordenarse. El número de copia, host, conteo de ficheros, HTML, enlaces y configuración no llegan a la plantilla.

El contrato público contiene disponibilidad, actualización, indicación de datos antiguos, zona, actividad reconocida, total/desglose, inicio de última completa, antigüedad en horas y hasta cinco filas con inicio/tipo/duración/tamaño/incidencias. Todas las variables se escapan en HTML. La plantilla Smarty recibe únicamente HTML propio ya escapado y reconstruido; no HTML del origen.

Las fechas son inicios, nunca finales calculados. Se normalizan a timestamps con zona explícita; minutos inexistentes o ambiguos por cambio horario fallan de forma cerrada porque el HTML no incluye offset. El formato presentado es d/m/Y H:i T, con zona IANA visible; validar coherencia con el tema/locale instalado. MiB/1024 son GiB lógicos aproximados, no ocupación ni transferencia. Filled no modifica incidencias. Cuatro contadores presentes a cero significan «Sin incidencias registradas»; alguno positivo, «Con incidencias»; faltantes, «Información no disponible». No se suma un total de errores. Idle significa solo ausencia de actividad; estados desconocidos se omiten. No hay alarmas SLA ni promesas de restauración.

Una tabla reconocida con cabecera completa y sin filas se trata como cero retenido (caso sintético probado); la ausencia de tabla es error, nunca cero. No se han aportado ejemplos reales de detalle sin copias: cualquier otra estructura fallará cerrada hasta disponer de evidencia.

La caché contiene datos normalizados sin credenciales ni host. Su clave es SHA-256 de versión/configuración/servicio/host. Autorización y contratación se repiten antes de leerla. TTL 120 s; ante fallo, datos antiguos hasta 900 s desde su obtención, con aviso y fecha originales. Caducados: indisponibilidad. Cambios de mapeo/destino/configuración no reutilizan entradas anteriores. Logs administrativos: solo códigos fijos y servicio; no excepciones ni respuestas del origen.

Rollback

Desactivar backups.enabled inmediatamente en la configuración privada. Restaurar el módulo respaldado o distribuir el archivo runtime del commit base 1174c120dec0982b4c628a353c66cdaeab894b1e desde un checkout de preparación. No hacer reset destructivo en un árbol compartido. Limpiar la caché privada de esta integración y la caché de plantillas WHMCS según el procedimiento de la instalación. Retirar únicamente la sección de configuración nueva si se desea; conservar Graphite/API. No hay migraciones ni cambios en contratación que revertir. Puede conservarse el campo administrativo desactivado/documentado, o retirarlo solo tras respaldar sus valores y aprobarlo. Retirar el diagnóstico temporal y restaurar la función administrativa si sigue instalado.

Comprobar que desaparece Backups y que panel/gráficas y botones existentes conservan comportamiento. No confundir un rollback de código con revertir contratos.

Referencias de integración consultadas

Estas referencias no sustituyen la validación de la versión y tema instalados.

Corrección tras callback WHMCS real

La petición real confirmó servicio y opción integer1, cliente y sesión correctos, pero Client::hasPermission lanzó una excepción. Se sustituye por CurrentUser::user()->getClientsByPermission(‘products’), exigiendo que el array de modelos WHMCS\User\Client incluya la cuenta actual, antes de verificar la pertenencia del servicio. API y resultado para el propietario comprobados en la instalación; no se omite autorización por ser propietario o administrador. Pruebas: 192 de regresión y 227 de backups PASS. La comprobación web posterior y delegados reales siguen pendientes.