Módulo VPSManager para WHMCS con configuración externa, acceso seguro al panel y métricas Graphite para LX.
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 
 
 
psarria 1174c120de Add server-side Graphite Basic authentication over HTTPS pirms 17 stundām
WhmcsHelpers Initial public release of WHMCS VPSManager module pirms 17 stundām
assets Initial public release of WHMCS VPSManager module pirms 17 stundām
docs Add server-side Graphite Basic authentication over HTTPS pirms 17 stundām
lib Add server-side Graphite Basic authentication over HTTPS pirms 17 stundām
templates Initial public release of WHMCS VPSManager module pirms 17 stundām
tests Add server-side Graphite Basic authentication over HTTPS pirms 17 stundām
tools Initial public release of WHMCS VPSManager module pirms 17 stundām
.gitignore Initial public release of WHMCS VPSManager module pirms 17 stundām
AUDIT.md Add server-side Graphite Basic authentication over HTTPS pirms 17 stundām
README.md Add server-side Graphite Basic authentication over HTTPS pirms 17 stundām
config.example.php Add server-side Graphite Basic authentication over HTTPS pirms 17 stundām
vpsmanager.php Initial public release of WHMCS VPSManager module pirms 17 stundām

README.md

WHMCS VPSManager

Módulo VPSManager para WHMCS con controles de reinicio, parada, arranque, firewall, snapshots, suspensión/reactivación, enlace al panel y métricas Graphite de servicios LX.

Esta versión parte del módulo facilitado y conserva su comportamiento de provisioning. CreateAccount ya devolvía success sin provisionar; TerminateAccount, ChangePackage y ChangePassword estaban vacíos y siguen así. No se debe asumir que estas funciones estén implementadas. El tratamiento de errores de los comandos de provisioning sigue siendo el heredado: un success no acredita por sí solo que el backend ejecutó la acción. No se ha reescrito suspensión/reactivación ni su contrato HTTP.

Requisitos e instalación

  • PHP 8.1 o posterior con cURL, JSON y certificados CA actualizados. Probado con PHP 8.1.
  • WHMCS con módulos de provisioning y los custom fields actuales del producto.
  • Acceso HTTPS desde PHP a Graphite. Las consultas no las realiza el navegador.
  • La versión y la plantilla reales de WHMCS no se han facilitado. Validar el módulo en staging antes de sustituirlo en producción; las pruebas locales no equivalen a esa validación.

Instalar vpsmanager.php, lib/, WhmcsHelpers/, templates/ y assets/ dentro de <WHMCS>/modules/servers/vpsmanager/. Mantener el nombre del directorio vpsmanager. No instalar .git/, tests/ ni tools/ en el servidor web. Los ficheros vacíos logo.png y hooks.php del original no se distribuyen.

No se cambia el orden de las opciones existentes del módulo ni los nombres de sus custom fields. Es obligatorio que uuid, vtype, gzid, url, username y password sean campos administrados por el servidor/administrador, no editables ni mostrados al cliente. Revisar la configuración de custom fields y la plantilla WHMCS: el módulo ya no imprime contraseñas, pero no puede corregir una plantilla externa que imprima esos campos.

Configuración externa

Copiar config.example.php fuera del árbol web y del repositorio, normalmente a:

/etc/open6hosting/whmcs-vpsmanager.php

La variable de entorno O6H_VPSMANAGER_CONFIG permite usar otra ruta absoluta. Si se utiliza PHP-FPM, comprobar que el pool realmente transmite esa variable.

  • vpsmanager_api_url: base de la API VPSManager, sin barra final. Se admite HTTP para conservar la compatibilidad con la API original; preferir HTTPS o transporte privado protegido. No deshabilitar la verificación TLS.
  • graphite_url: base HTTPS de Graphite, sin /render/, credenciales embebidas, query string ni fragmento. La implementación añade /render/.
  • graphs_url: base HTTPS de la vista completa antigua, opcional.
  • graphs_authorization_confirmed: poner a true únicamente tras comprobar que la vista completa autentica al cliente y autoriza el VPS solicitado. Con URL ausente o sin esa comprobación se conserva el botón Graphs, desactivado. El UUID en la URL no es un control de acceso. Las nuevas tres gráficas no dependen de esa vista externa.

Configurar solamente los valores privados reales en el fichero externo, nunca en el archivo de ejemplo. No se han incluido valores de producción en este repositorio.

Permisos recomendados: directorio 0750, fichero 0640, propietario administrador y un grupo que permita lectura al usuario real de PHP-FPM/servidor web. Adaptar usuario y grupo a la instalación. PHP no debe poder escribir esa configuración. Nunca chmod 777. La configuración PHP es código de confianza controlado por el administrador.

La falta de configuración no debe generar un fatal del módulo: las métricas muestran un aviso discreto, los comandos que requieren la API devuelven un error genérico y los selectores de nodos/paquetes quedan vacíos. No guardar una configuración de producto hasta restablecer estos selectores.

Métricas LX

Solo vtype = lx. El UUID debe tener formato hexadecimal 8-4-4-4-12, por ejemplo el UUID ficticio 00000000-0000-4000-8000-000000000001. Los targets internos son:

Gráfica / serie Target bajo lx.<uuid>. Transformación
Carga / 1 min load.load.shortterm Ninguna
Carga / 5 min load.load.midterm Ninguna
Carga / 15 min load.load.longterm Ninguna
Memoria usada memory.memory-used Bytes, presentación IEC
Memoria libre memory.memory-free Bytes, usada para calcular el total
Red RX interface-eth0.if_octets.rx Bytes/s → bits/s, una vez al presentar
Red TX interface-eth0.if_octets.tx Bytes/s → bits/s, una vez al presentar

La carga no es porcentaje de CPU. Memoria total = usada + libre en el mismo timestamp; porcentaje = usada / total × 100 si ambos datos existen y el total es positivo. No hay una capacidad fija. Una serie de memoria ausente no se interpreta como cero. La red ya contiene tasas: no se aplica derivative ni nonNegativeDerivative, ni se calcula volumen mensual.

Se agrupan los siete targets en una petición, con format=json, until=now y maxDataPoints=1000. Se conserva la resolución devuelta por Graphite, los timestamps y los huecos null; no se unen las líneas a través de esos huecos. El resumen corresponde al timestamp más reciente de la gráfica y muestra su fecha/hora local del navegador; no sustituye un dato ausente por una muestra antigua. No existe actualización automática.

Rangos: 1h, 6h, 24h por defecto, 7d, 30d. Cualquier otra entrada cae a 24h. Los enlaces recargan clientarea.php?action=productdetails&id=<servicio>&metrics_range=<rango>. No hay endpoint AJAX ni endpoint de métricas accesible directamente. WHMCS autoriza el servicio antes de invocar vpsmanager_ClientArea; el módulo solo toma UUID/tipo de $params y nunca de GET/POST. Cambiar id vuelve a pasar por la autorización de WHMCS.

PHP mantiene verificación TLS y no sigue redirecciones. Connect timeout 3 s, total 5 s, respuesta limitada a 2 MiB. Un fallo HTTP, timeout, JSON inválido o dato mal formado muestra Las métricas no están disponibles temporalmente. sin bloquear los demás controles. Las series ausentes pueden convivir con las disponibles. No se registran cuerpos HTTP, excepciones detalladas, configuración, credenciales ni parámetros completos de WHMCS.

Graphite admite autenticación HTTP Basic sobre HTTPS mediante configuración privada:

'graphite_auth' => 'basic',
'graphite_username' => '', // Completar solo en el fichero privado.
'graphite_password' => '', // Completar solo en el fichero privado.

Usuario y contraseña son de una cuenta técnica exclusiva para WHMCS, no de los clientes. Se envían mediante las opciones de autenticación cURL, nunca en la URL, HTML o JavaScript. Una configuración Basic incompleta o inválida impide enviar la petición; no hay fallback anónimo. HTTP 401/403 y redirecciones muestran el aviso genérico de métricas no disponibles. TLS sigue siendo obligatorio. none conserva compatibilidad con instalaciones anteriores, pero NO protege Graphite: para el despliegue protegido seleccionar basic.

La protección de entrada se configura en Apache; actualizar este módulo no cierra por sí solo el acceso público. Seguir la guía Apache, incluyendo la protección de rutas Render/API y puertos de backend. No compartir la cuenta técnica con clientes. graphs_authorization_confirmed debe permanecer en false para la vista Graphs antigua, que carece de autorización por VPS.

Interfaz y acceso al panel

Las vistas y la lógica Graphite están separadas de las operaciones existentes. Las tres cards usan clases compatibles con Bootstrap y estilos limitados al módulo. Se reutiliza window.Chart si es Chart.js 4.x; en otro caso se carga Chart.js 4.4.8 localmente y se restaura cualquier window.Chart previo. No se consultan CDNs en visitas. No se ha podido inspeccionar la plantilla instalada; comprobar compatibilidad en staging. El eje temporal numérico permite timestamps irregulares sin adaptador de fechas externo.

Antes: el módulo insertaba usuario/contraseña ISPConfig en JavaScript y los enviaba por AJAX desde el navegador, tanto en cliente como en administración.

Después: Acceder al Panel abre únicamente el login HTTPS en otra pestaña, con noopener noreferrer. No se incorpora usuario ni contraseña. No hay autologin: el código recibido no incluía un mecanismo SSO seguro. No se ha inventado ninguno. Las URLs inseguras, con credenciales, query string o fragmentos no generan enlaces activos.

Las plantillas de acciones conservan las operaciones y añaden escape HTML y el token CSRF de WHMCS. El módulo depende del dispatcher de WHMCS para autenticación, autorización y validación del token. No exponer las acciones mediante un endpoint personalizado.

Desarrollo y pruebas

Desde la raíz del repositorio:

find . -type f -name '*.php' -not -path './.git/*' -print0 | xargs -0 -n1 php -n -l
php -n tests/run.php
node tests/frontend.cjs
node --check assets/metrics.js
python3 tools/audit.py

php -n es deliberado: el test sustituye cURL por dobles y no realiza ninguna conexión. Cubre configuración, UUID/tipo/rangos, fallos HTTP/JSON/timeout, respuesta grande, series parciales, huecos, alineación temporal, cálculos, ausencia de secretos en HTML, manipulación GET/POST y rutas/payloads de las operaciones existentes. Los fixtures usan dominios .invalid, IPs de documentación y contraseñas ficticias identificadas con FAKE_. Los tests JS verifican unidades, huecos, carga local y conservación de otra versión de Chart.js.

tools/scope-chart.cjs genera el bundle aislado a partir del fichero upstream, cuya licencia MIT y procedencia constan en assets/Chart.js.LICENSE.md y assets/THIRD-PARTY.md. No confundir esa licencia con una licencia para nuestro proyecto.

La prueba de aislamiento de UUID invoca el hook con los parámetros de un servicio y peticiones GET/POST que intentan elegir otro. La prueba end-to-end del dispatcher requiere WHMCS real: con dos clientes y servicios distintos, verificar que el cliente A no puede acceder al id del B, con cualquiera de los cinco rangos, ni alterar los campos UUID/tipo. Verificar además token CSRF de las acciones, biblioteca/tema instalado, CSP y los controles en staging. No se han ejecutado reinicios, restauraciones o suspensiones sobre infraestructura real.

Historial, publicación y licencia

El repositorio público debe empezar con un único commit limpio, sin importar historial anterior. No copiar el ZIP original, backups, configuración real ni el directorio de trabajo. tools/audit.py revisa árbol, índice o archivos versionados; revisar también sus límites en AUDIT.md. Ningún escáner prueba la ausencia absoluta de todos los posibles secretos.

Destino previsto: https://gitea.open6hosting.com/Open6Hosting/whmcs-vpsmanager. No hacer force-push sobre un repositorio existente.

Licencia del proyecto pendiente de decisión del titular. No se concede una licencia open source por defecto. Se conserva el aviso de copyright original de WhmcsHelpers/CustomField.php; confirmar también los derechos de redistribución de ese helper antes de declarar una licencia global. La licencia de Chart.js solo cubre ese componente de terceros.

Referencias de integración