🖥️ Informe VPS Educaluxe
📊 Estado General del Servidor
| Sistema Operativo | Ubuntu 24.04.4 LTS (Noble Numbat) |
| CPU | 6 cores — AMD EPYC Processor (with IBPB) |
| RAM total | 12 GB (11 GiB disponibles al sistema) |
| Swap | 2 GB |
| Disco | 193 GB (16 GB usados — 9%) |
| Uptime | 8 días 21 horas (estable) |
| Acceso SSH | ⚠ Password auth activo — hardening pendiente |
| Panel web | CloudPanel v6.0.8 → https://panel.educaluxe.net |
💻 Recursos del Sistema
Uso de disco por directorio
| Directorio | Tamaño | Contenido |
|---|---|---|
/home/clp/ | 1.4 GB | Panel CloudPanel + assets |
/home/educaluxe/ | 1.1 GB | Moodle principal (educaluxe.net) |
/home/mysql/ | 1.3 GB | Datos MariaDB |
/home/educaluxe-divinonet/ | 565 MB | Moodle divinonet |
/home/educaluxe-web/ | 216 MB | Sitio web (web.educaluxe.net) |
/home/educaluxe-mail/ | 192 KB | Proxy mailcow (solo config) |
/home/educaluxe-docker/ | 148 KB | Config Portainer (solo config) |
🌐 Sitios Web Activos
Todos los sitios son gestionados por CloudPanel via Nginx. PHP usa versión 8.3 para todos los sitios reales.
| Dominio | Tipo | DocumentRoot | Backend | Estado |
|---|---|---|---|---|
educaluxe.netwww.educaluxe.net |
Moodle | /home/educaluxe/htdocs/moodle/public |
PHP-FPM 8.3 :18002 | ⚠ server_name duplicado |
divinonet.educaluxe.net |
Moodle | /home/educaluxe-divinonet/htdocs/moodle/public |
PHP-FPM 8.3 :18001 | ✓ OK |
web.educaluxe.net |
Web/CMS | /home/educaluxe-web/htdocs/web.educaluxe.net |
Nginx :8080 → PHP-FPM 8.3 :18003 | ⚠ Config dual (revisar) |
mail.educaluxe.net |
Webmail | /home/educaluxe-mail/… |
proxy → mailcow :7080 | ✓ OK |
docker.educaluxe.net |
Portainer | /home/educaluxe-docker/… |
proxy → :9000 | ⚠ :9000 directo aún expuesto |
panel.educaluxe.net |
CloudPanel | /home/clp/htdocs/app/files/public |
proxy → :8443 | ✓ OK (SSL propio) |
educaluxe.net.conf contiene dos bloques server {} con www.educaluxe.net referenciado en ambos. Puede causar comportamientos inesperados en la redirección www → non-www. Revisar y consolidar desde el panel CLP.
🔒 SSL / Certificados
| Dominio | Emitido | Expira | Días restantes | Estado |
|---|---|---|---|---|
educaluxe.net | 2026-05-23 | 2026-08-21 | ~82 días | ✓ Válido |
divinonet.educaluxe.net | 2026-05-22 | 2026-08-20 | ~81 días | ✓ Válido |
web.educaluxe.net | 2026-05-30 | 2026-08-28 | ~89 días | ✓ Válido |
mail.educaluxe.net | 2026-05-22 | 2026-08-20 | ~81 días | ✓ Válido |
panel.educaluxe.net | — | — | — | SSL propio CLP |
/etc/nginx/ssl-certificates/. No instalar Certbot global para no interferir con mailcow ACME ni con CLP.
🐳 Docker & mailcow
mailcow lleva 8+ días estable. Sus puertos de correo son intencionales y no deben bloquearse.
Ver todos los containers Docker (19 activos)
| Container | Imagen | Puertos | Estado |
|---|---|---|---|
| portainer | portainer/portainer-ce | 0.0.0.0:9000 | ⚠ Expuesto |
| mailcow-postfix | ghcr.io/mailcow/postfix | 25, 465, 587 | ✓ Intencional |
| mailcow-dovecot | ghcr.io/mailcow/dovecot | 110, 143, 993, 995, 4190 | ✓ Intencional |
| mailcow-nginx | ghcr.io/mailcow/nginx | 127.0.0.1:7080/7443 | ✓ Solo localhost |
| mailcow-mysql | mariadb:10.11 | 127.0.0.1:13306 | ✓ Solo localhost |
| mailcow-redis | redis:7.4.6-alpine | 127.0.0.1:7654 | ✓ Solo localhost |
| mailcow-rspamd | ghcr.io/mailcow/rspamd | interno | Interno |
| mailcow-clamd | ghcr.io/mailcow/clamd | interno | ✓ Healthy |
| mailcow-sogo | ghcr.io/mailcow/sogo | interno | Interno |
| mailcow-acme | ghcr.io/mailcow/acme | interno | ✓ Gestiona SSL |
| mailcow-unbound | ghcr.io/mailcow/unbound | interno (DNS) | ✓ Healthy |
| mailcow-watchdog | ghcr.io/mailcow/watchdog | interno | Interno |
| mailcow-netfilter | ghcr.io/mailcow/netfilter | interno | Interno |
| mailcow-memcached | memcached:alpine | interno | Interno |
| mailcow-php-fpm | ghcr.io/mailcow/phpfpm | interno | Interno |
| mailcow-olefy | ghcr.io/mailcow/olefy | interno | Interno |
| mailcow-ofelia | mcuadros/ofelia | interno | Cron jobs |
| mailcow-dockerapi | ghcr.io/mailcow/dockerapi | interno | Interno |
| mailcow-postfix-tlspol | ghcr.io/mailcow/postfix-tlspol | interno | Interno |
docker.educaluxe.net ya hace proxy con SSL, el acceso directo http://IP:9000 sigue funcionando sin autenticación de Nginx. Requiere regla en la chain DOCKER-USER.
⚙️ PHP Multi-versión
CloudPanel instala todas las versiones PHP disponibles. Solo PHP 8.3 tiene pools de sitios activos.
| Versión | Puerto FPM | Pool de sitio | Estado |
|---|---|---|---|
| PHP 7.1 | :11000 | Ninguno | ⚠ Sin sitio — consume RAM |
| PHP 7.2 | :12000 | Ninguno | ⚠ Sin sitio — consume RAM |
| PHP 7.3 | :13000 | Ninguno | ⚠ Sin sitio — consume RAM |
| PHP 7.4 | :14000 | Ninguno | ⚠ Sin sitio — consume RAM |
| PHP 8.0 | :15000 | Ninguno | ⚠ Sin sitio — consume RAM |
| PHP 8.1 | :16000 | Ninguno | ⚠ Sin sitio — consume RAM |
| PHP 8.2 | :17000 | Ninguno | ⚠ Sin sitio — consume RAM |
| PHP 8.3 | :18001 / :18002 / :18003 | divinonet / educaluxe / web | ✓ En uso activo |
| PHP 8.4 | :19000 | Ninguno | ⚠ Sin sitio — consume RAM |
| PHP 8.5 | :20000 | Ninguno | ⚠ Sin sitio — consume RAM |
⚡ Varnish Caché
Varnish está instalado como capa de caché HTTP. Configurado con backend en 127.0.0.1:8080.
Flujo esperado vs. flujo real
Flujo esperado (con Varnish activo):
Flujo real detectado (posible bypass):
0.0.0.0:6081. Cualquiera puede hacer peticiones HTTP directas al backend sin pasar por Nginx, saltándose SSL, headers de seguridad y rate limiting. Debe restringirse a 127.0.0.1:6081.
grep -r "6081\|varnish" /etc/nginx/sites-enabled/ para confirmar si Nginx redirige tráfico a Varnish o va directo al backend.
🗄️ MariaDB
| Versión | MariaDB 10.11.14 |
| Puerto host | 3306 — ⚠ bind en 0.0.0.0 |
| Puerto Docker (mailcow) | 127.0.0.1:13306 — ✓ Solo localhost |
| Datos | /home/mysql/ — 1.3 GB |
| Credenciales root | ⚠ Desconocidas — requiere contraseña |
bind-address = 127.0.0.1 en /etc/mysql/mariadb.conf.d/50-server.cnf.
🔌 Puertos Abiertos
Públicos (0.0.0.0)
Solo localhost ✅
🛡️ Estado de Seguridad
| # | Ítem | Estado | Prioridad |
|---|---|---|---|
| 1 | Clave SSH en /root/.ssh/authorized_keys | ⚠ Vacío — debe hacerse PRIMERO | 🔴 Alta |
| 2 | SSH PermitRootLogin | yes — acceso root directo | 🔴 Alta |
| 3 | SSH PasswordAuthentication | yes — brute force posible | 🔴 Alta |
| 4 | MariaDB bind-address | 0.0.0.0 — expuesto a internet | 🔴 Alta |
| 5 | Portainer :9000 público | Docker bypasa UFW | 🔴 Alta |
| 6 | Fail2ban | Solo jail SSH — faltan Nginx | 🟡 Media |
| 7 | Varnish :6081 | HTTP público sin SSL | 🟡 Media |
| 8 | ProFTPD puerto 21 | FTP plano (requerido por CLP) | 🟡 Media |
| 9 | Backups configurados | Sin crontab root — sin backup automático | 🟡 Media |
UFW — Reglas actuales
# Reglas UFW activas [ 1] 22/tcp ALLOW Anywhere # SSH [ 2] 80/tcp ALLOW Anywhere # HTTP [ 3] 443 ALLOW Anywhere # HTTPS [ 4] 8433:8443/tcp ALLOW Anywhere # CLP backend (rango incluye 8443) [ 5] 443/udp ALLOW Anywhere # QUIC/HTTP3 # ⚠️ IMPORTANTE: Docker bypasa UFW directamente # Puerto 9000 (Portainer) está abierto aunque no aparezca aquí
🔧 Plan de Hardening
Agregar clave SSH pública (HACER PRIMERO)
Sin esto, si se desactiva la contraseña quedarás sin acceso. Verificar en nueva terminal antes de continuar.
# PowerShell local: Get-Content "C:\Users\FamCM\.ssh\id_ed25519.pub" # En el VPS: mkdir -p /root/.ssh && chmod 700 /root/.ssh echo "PEGAR_CLAVE_PUBLICA_AQUI" >> /root/.ssh/authorized_keys chmod 600 /root/.ssh/authorized_keys
SSH Hardening — Deshabilitar contraseña
Cambiar PermitRootLogin a prohibit-password y desactivar PasswordAuthentication.
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d) sed -i 's/^PermitRootLogin yes/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config systemctl reload ssh
MariaDB — Restringir a localhost
Evitar exposición de la base de datos a internet. Crítico.
sed -i 's/.*bind-address.*/bind-address = 127.0.0.1/' \
/etc/mysql/mariadb.conf.d/50-server.cnf
systemctl restart mariadb
ss -tlnp | grep 3306 # Debe mostrar 127.0.0.1:3306
Portainer — Bloquear acceso directo :9000
Docker bypasa UFW. Usar la chain DOCKER-USER de iptables. Portainer seguirá accesible en https://docker.educaluxe.net.
iptables -I DOCKER-USER -i eth0 -p tcp --dport 9000 -j DROP apt install -y iptables-persistent netfilter-persistent save # Acceso futuro via túnel SSH: # ssh -L 9000:localhost:9000 -N root@164.68.96.33
Fail2ban — Agregar jails para Nginx y MariaDB
Actualmente solo protege SSH. Añadir protección contra brute force en web y base de datos.
[sshd] enabled = true maxretry = 3 [nginx-http-auth] enabled = true [nginx-botsearch] enabled = true [mariadb-auth] enabled = true filter = mysqld-auth logpath = /var/log/mysql/error.log
Varnish — Restringir a localhost
Cambiar el bind de Varnish de 0.0.0.0:6081 a 127.0.0.1:6081.
# En /etc/varnish/varnish.params o /etc/default/varnish # Buscar y cambiar: -a 0.0.0.0:6081 → -a 127.0.0.1:6081 systemctl restart varnish
🖥️ CloudPanel v6.0.8
El único panel instalado es CloudPanel v6.0.8. No existe CyberPanel ni ningún otro panel en el servidor.
| Binario CLI | /usr/bin/clpctl |
| Daemon | /usr/sbin/clp-agent |
| URL panel | https://panel.educaluxe.net |
| Nginx propio | Instancia separada de Nginx del sistema — proceso como usuario clp |
| PHP propio | Instancia PHP-FPM para el panel (en /home/clp/services/) |
⏰ Cron Jobs
| Archivo | Propósito | Estado |
|---|---|---|
/etc/cron.d/clp | Tareas internas CloudPanel | Sistema |
/etc/cron.d/educaluxe | Cron Moodle principal | Contenido no verificado |
/etc/cron.d/educaluxe-divinonet | Cron Moodle divinonet | Contenido no verificado |
/etc/cron.d/php | Limpieza sesiones PHP | Sistema |
/etc/cron.d/staticroute | Rutas de red estáticas | Sistema |
/etc/cron.d/sysstat | Métricas del sistema (sar) | Sistema |
/etc/cron.d/e2scrub_all | Verificación filesystem ext4 | Sistema |
cat /etc/cron.d/educaluxe
📦 Actualizaciones Pendientes
| Paquete | Versión actual | Nueva versión |
|---|---|---|
vim | 9.1.0016-1ubuntu7.13 | 9.1.0016-1ubuntu7.14 |
vim-common | 9.1.0016-1ubuntu7.13 | 9.1.0016-1ubuntu7.14 |
vim-runtime | 9.1.0016-1ubuntu7.13 | 9.1.0016-1ubuntu7.14 |
vim-tiny | 9.1.0016-1ubuntu7.13 | 9.1.0016-1ubuntu7.14 |
xxd | 9.1.0016-1ubuntu7.13 | 9.1.0016-1ubuntu7.14 |
rclone | 1.60.1+dfsg-3ubuntu0.24.04.4 | 1.60.1+dfsg-3ubuntu0.24.04.5 |
apt upgrade -y # Aplicar todas las actualizaciones pendientes
🚀 Análisis: Convertir el VPS en Plataforma Reseller
¿Qué necesitas para ofrecer hosting como reseller?
| Función requerida | CloudPanel (actual) |
|---|---|
| Cuentas de reseller (sub-admin que gestiona sus propios clientes) | ❌ No existe |
| Límites de disco por cliente (GB) | ❌ No existe |
| Límites de ancho de banda por cliente | ❌ No existe |
| Límites de número de dominios/sitios por cliente | ❌ No existe |
| Panel separado por cliente final | ❌ No existe |
| Módulo de facturación / billing | ❌ No existe |
| Integración WHMCS | ❌ No oficial |
| Suspensión automática de cuentas | ❌ No existe |
| Estadísticas de uso por cliente | ❌ No existe |
| El cliente puede crear sus propios sitios | ❌ No |
Opciones de paneles con capacidad reseller
Ideal si: ofreces hosting gestionado donde tú haces el trabajo técnico.
Instalar sin mail: --exim no --dovecot no para no conflictuar con mailcow.
No recomendado para este servidor.
Jerarquía de cuentas (con panel reseller real)
Tabla comparativa final
| Panel | Precio | Reseller | Límites | Billing | Conflicto stack |
|---|---|---|---|---|---|
| CloudPanel (actual) | Gratis | ❌ | ❌ | ❌ | Ninguno |
| HestiaCP | Gratis | ✅ | ✅ | WHMCS/FOSSBilling | Mail (evitable) |
| ISPConfig | Gratis | ✅ | ✅✅ | WHMCS | Mail (evitable) |
| DirectAdmin | ~$2/mes | ✅ | ✅ | WHMCS oficial | Mail (evitable) |
| cPanel/WHM | $15–45/mes | ✅✅ | ✅✅ | WHMCS completo | Alto |
✅ Recomendación Final
🅰️ Escenario A — Mínimo impacto: CloudPanel + FOSSBilling
Para: hosting gestionado donde tú administras todo
- Mantener CloudPanel tal como está
- Instalar FOSSBilling (open source, gratuito) en
billing.educaluxe.net - Cada cliente recibe credenciales del portal de facturación
- Tú creas los sitios en CloudPanel y los asignas manualmente al usuario del cliente
- Cliente ve su factura, abre tickets — pero no crea sitios por su cuenta
🅱️ Escenario B — Reseller real (recomendado si vas a escalar): HestiaCP + FOSSBilling
Para: hosting comercial con clientes self-service
- Migrar sitios actuales (Moodle) a carpetas seguras primero
- Instalar HestiaCP sin módulos de mail para no conflictuar con mailcow
- Crear paquetes de hosting con límites (Starter: 1 GB disco / 1 dominio / 1 DB...)
- Crear cuentas de reseller para intermediarios
- Integrar FOSSBilling para billing y portal de clientes
# Instalación HestiaCP sin mail (para no conflictuar con mailcow):
bash hst-install.sh --exim no --dovecot no --spamassassin no --clamav no \
--nginx yes --php yes --vsftpd yes --mysql yes
🅲 Escenario C — Reseller moderno con DirectAdmin ($2/mes)
Para: quien prefiere UI moderna y soporte oficial
- Obtener licencia en directadmin.com (~$2/mes)
- Migrar sitios y datos antes de instalar
- Mismo proceso que HestiaCP pero con UI más pulida y WHMCS oficial
🎯 Mi recomendación directa
Dado que ya tienes Moodle, mailcow y CloudPanel funcionando en producción, la ruta más segura es:
- Hacer el hardening de seguridad (pasos 1–5)
- Instalar FOSSBilling para facturación
- Ofrecer hosting administrado con CloudPanel
- Evaluar migración a HestiaCP en un VPS de prueba
- Preparar plan de migración de Moodle
- Migrar en ventana de mantenimiento programada
Recursos y documentación
| Herramienta | Documentación | Demo |
|---|---|---|
| CloudPanel | cloudpanel.io/docs | demo.cloudpanel.io |
| HestiaCP | hestiacp.com/docs | demo (puerto 8083) |
| ISPConfig | ispconfig.org/docs | — |
| DirectAdmin | docs.directadmin.com | demo.directadmin.com |
| FOSSBilling | fossbilling.org/docs | fossbilling.org/demo |