Cómo configurar 2FA para cuentas de staff en MU Online
Aprende a proteger las cuentas de administradores y GMs de tu servidor de MU Online con autenticación de dos factores, desde el panel web hasta el acceso a la base de datos y al servidor de juego.
Las cuentas de staff son el objetivo más valioso de cualquier servidor de MU Online. Un GM comprometido puede generar ítems excellent, dar reset infinito, banear a jugadores legítimos o drenar el Web Shop en minutos. Y, a diferencia de una cuenta de jugador común, el daño de una cuenta administrativ
Las cuentas de staff son el objetivo más valioso de cualquier servidor de MU Online. Un GM comprometido puede generar ítems excellent, dar reset infinito, banear a jugadores legítimos o drenar el Web Shop en minutos. Y, a diferencia de una cuenta de jugador común, el daño de una cuenta administrativa comprometida es prácticamente irreversible para la reputación del servidor. La autenticación de dos factores (2FA) es la defensa más eficiente en relación con su costo que puedes implementar: aunque la contraseña de un administrador se filtre en un phishing, el atacante todavía necesita el segundo factor físico.
En este tutorial vas a configurar 2FA en todas las capas relevantes de un servidor de MU Online: el panel web (AMS/UserControlPanel o panel propio), el acceso SSH/RDP a la máquina, la base de datos SQL Server y, cuando sea posible, el propio login de GM dentro del juego. Los ejemplos asumen un stack común (Windows Server + SQL Server + panel PHP), pero los conceptos valen para cualquier combinación. Los detalles de archivos y nombres de tablas varían según la season y el emulador (IGCN, MuEMU/Season 6, X-Files, entre otros), así que trata las rutas como EJEMPLO y adáptalas.
Requisitos previos
Antes de empezar, asegúrate de tener:
- Acceso administrativo a la máquina (física o VPS) donde corre el servidor.
- Acceso al panel web del servidor con permiso para editar el código fuente, o al repositorio del panel.
- Acceso al SQL Server con una cuenta
sysadmin(para crear tablas de soporte del 2FA). - Una aplicación autenticadora TOTP instalada en los celulares del equipo (Google Authenticator, Aegis, Authy o similar).
- Un inventario actualizado de todas las cuentas con privilegios: administradores del sitio, GMs in-game, cuentas de base de datos y usuarios del sistema operativo.
- Un segundo canal verificado de contacto con cada miembro del equipo (para recuperación), preferentemente presencial o por teléfono conocido.
Reserva una ventana de mantenimiento. Habilitar 2FA de forma incorrecta puede dejarte fuera de tu propio panel, así que ten siempre una cuenta de emergencia documentada en un lugar seguro (bóveda offline).
Cómo funciona el TOTP (el concepto real)
El estándar más usado es el TOTP (Time-based One-Time Password), definido en la RFC 6238. El servidor y la aplicación del usuario comparten un secreto (una cadena en Base32) generado una única vez en el registro. Cada 30 segundos, ambos lados calculan un código de 6 dígitos usando HMAC-SHA1 sobre el secreto y la hora actual. Si los dos códigos coinciden, el login se aprueba.
Esto tiene tres implicaciones prácticas:
- El reloj del servidor debe estar sincronizado (usa NTP). Si la hora se desvía más de 1-2 ventanas, todos los códigos fallan.
- El secreto nunca viaja después del registro inicial, lo que hace al TOTP resistente a la interceptación de red.
- Debes almacenar el secreto cifrado en la base de datos, nunca en texto plano.
Paso 1 — Preparar la base de datos
Crea una tabla para almacenar los secretos y el estado del 2FA por cuenta de staff. Ejemplo para SQL Server (adapta los nombres según tu emulador):
CREATE TABLE Staff2FA (
AccountID VARCHAR(10) NOT NULL PRIMARY KEY,
SecretEnc VARBINARY(256) NOT NULL, -- secreto TOTP cifrado
Enabled BIT NOT NULL DEFAULT 0,
RecoveryCodes VARBINARY(512) NULL, -- hashes de los códigos de respaldo
LastUsedStep BIGINT NULL, -- previene el replay del mismo código
CreatedAt DATETIME NOT NULL DEFAULT GETDATE()
);
El campo LastUsedStep guarda el último paso de tiempo aceptado e impide que un código válido se reutilice dentro de la misma ventana de 30 segundos (protección contra replay). Cifra SecretEnc con una clave que quede fuera de la base de datos (por ejemplo, en una variable de entorno o en la bóveda de la aplicación), para que un dump de la base no filtre los secretos.
Paso 2 — Habilitar 2FA en el panel web
El panel web suele ser la puerta de entrada más expuesta, así que empieza por él. El flujo de registro (enrollment) es:
- El administrador se loguea normalmente con usuario y contraseña.
- El panel genera un secreto Base32 aleatorio de 20 bytes.
- El panel muestra un código QR (formato
otpauth://totp/MiMU:usuario?secret=BASE32&issuer=MiMU) para escanear en la app. - El administrador escribe el código actual para confirmar que la app se configuró correctamente.
- Solo entonces
Enabledse marca como 1 y se muestran los códigos de recuperación una única vez.
Ejemplo mínimo de verificación en PHP usando una biblioteca TOTP:
require 'vendor/autoload.php';
use OTPHP\TOTP;
// secreto recuperado y descifrado de la base de datos
$totp = TOTP::createFromSecret($secretBase32);
$totp->setPeriod(30);
if ($totp->verify($_POST['codigo'], null, 1)) { // ventana de tolerancia = 1
// valida también LastUsedStep para evitar replay
liberarLogin($accountId);
} else {
registrarFalha2FA($accountId, $_SERVER['REMOTE_ADDR']);
}
El tercer parámetro (1) permite una ventana de tolerancia para pequeñas desincronizaciones de reloj. No aumentes ese valor más allá de 1 sin necesidad, pues amplía la ventana de ataque.
Paso 3 — Proteger el acceso al sistema operativo
El panel protegido no sirve de nada si el atacante consigue RDP o SSH directo a la máquina. En servidores Windows, evita exponer el puerto 3389 (RDP) a internet; ponlo todo detrás de una VPN y, si es posible, exige 2FA en la VPN. Para el RDP en sí, herramientas como Duo o soluciones equivalentes añaden un prompt de aprobación. En Linux, configura pam_google_authenticator en el SSH:
sudo apt install libpam-google-authenticator
google-authenticator # genera el QR y los códigos de recuperación por usuario
Después, edita /etc/pam.d/sshd para incluir auth required pam_google_authenticator.so y ajusta ChallengeResponseAuthentication yes (o KbdInteractiveAuthentication yes en versiones recientes) en el sshd_config. Combina siempre con autenticación por clave pública, nunca 2FA solo sustituyendo la clave.
Paso 4 — Proteger la base de datos
El SQL Server no tiene TOTP nativo, pero reduces el riesgo así:
- Nunca expongas el puerto 1433 a internet. Acceso solo vía VPN o túnel.
- Usa autenticación de Windows (Integrated) siempre que sea posible, heredando el 2FA del login del SO.
- Crea cuentas de aplicación con privilegio mínimo (solo las tablas necesarias), separadas de las cuentas administrativas.
- Registra y alerta sobre los logins de la cuenta
sa.
Paso 5 — 2FA para GM dentro del juego
Algunos emuladores permiten exigir un paso extra para los comandos de GM. Como pocos soportan TOTP nativo, un enfoque práctico es liberar los comandos administrativos más peligrosos (crear ítem, dar zen, ban) solo desde cuentas cuyo login web ya pasó por 2FA, o exigir una contraseña administrativa secundaria in-game. Esto varía bastante según la season/emulador; consulta la documentación de tu core antes de editar binarios.
Tabla de capas y métodos recomendados
| Capa | Método recomendado | Alternativa aceptable | Evita |
|---|---|---|---|
| Panel web de staff | TOTP por app | Llave FIDO2 | Solo contraseña |
| VPN de acceso | TOTP o push | Certificado + contraseña | Acceso directo sin VPN |
| SSH (Linux) | Clave pública + TOTP | Clave + contraseña fuerte | Contraseña sola |
| RDP (Windows) | VPN + 2FA en la VPN | Gateway RDP con MFA | 3389 abierto |
| SQL Server | Auth de Windows | Cuenta dedicada + VPN | sa expuesto |
| Comandos de GM in-game | Cuenta con 2FA web | Contraseña admin secundaria | Comando libre |
Tabla de factores por sensibilidad de la cuenta
| Tipo de cuenta | Factor mínimo | Rotación de credencial |
|---|---|---|
| Admin del sitio | TOTP + código de recuperación | 90 días |
| GM sénior | TOTP | 90 días |
| GM júnior / moderador | TOTP | 120 días |
| Cuenta de aplicación (DB) | Secreto en bóveda | 180 días |
Errores comunes y soluciones
| Problema | Causa probable | Solución |
|---|---|---|
| Todos los códigos son rechazados | Reloj del servidor desincronizado | Configura NTP y verifica el huso; el TOTP usa UTC |
| El código funciona dos veces | Falta de comprobación de LastUsedStep | Registra y bloquea la reutilización del mismo paso de tiempo |
| GM trabado fuera del panel | Perdió el celular sin código de recuperación | Reset vía segundo canal verificado, nunca por Discord |
| Los secretos se filtran en un dump de base | Secreto guardado en texto plano | Cifra SecretEnc con una clave fuera de la base |
| Ataque de fuerza bruta al código | Sin límite de intentos | Bloquea la cuenta tras 5 fallos y alerta al admin |
| 2FA burlado por RDP abierto | Capa del SO desprotegida | Cierra el puerto y exige VPN con MFA |
Buenas prácticas de recuperación y rotación
Genera de 8 a 10 códigos de recuperación de un solo uso en el registro y almacena solo su hash en la base de datos. Instruye al equipo para que los guarde offline. Define un proceso de reset que exija verificación por un segundo canal conocido (llamada, presencia física), porque la ingeniería social contra el soporte es el vector más común para derribar el 2FA. Haz una rotación periódica de los secretos y revoca de inmediato el acceso de cualquier miembro que salga del equipo.
Lista de verificación de lanzamiento
- Todas las cuentas de staff inventariadas y clasificadas por sensibilidad
- Tabla
Staff2FAcreada con secretos cifrados - Reloj del servidor sincronizado vía NTP (UTC)
- 2FA obligatorio en el panel web para todo el staff
- Protección contra replay (
LastUsedStep) validada - Límite de intentos y bloqueo por fuerza bruta activos
- VPN con MFA delante de RDP/SSH/SQL
- Puertos 1433 y 3389 cerrados a internet
- Códigos de recuperación generados y guardados offline
- Proceso de reset por segundo canal documentado
- Cuenta de emergencia probada y guardada en bóveda
- Equipo capacitado sobre phishing y SIM swap
Con el 2FA implementado en todas las capas, eliminas la mayoría de los escenarios en que una contraseña filtrada se convierte en un servidor comprometido. Si aún estás montando la estructura desde cero, vale la pena revisar la guía de cómo crear servidor de MU Online para garantizar que la base de seguridad esté correcta desde el inicio. Recuerda: el 2FA es una capa, no una bala de plata. Combínalo con contraseñas fuertes, privilegio mínimo y monitoreo continuo para una defensa realmente sólida.
Preguntas frecuentes
¿El 2FA por SMS es lo bastante seguro para mi equipo?
El SMS es mejor que nada, pero es vulnerable al SIM swap. Prefiere aplicaciones TOTP como Google Authenticator o llaves físicas FIDO2 para cuentas con privilegios de administrador.
¿Necesito cambiar el emulador para soportar 2FA?
No necesariamente. El 2FA se aplica en las capas de acceso (panel web, SSH, base de datos y RDP), que quedan fuera del emulador. El core del juego rara vez necesita modificarse.
¿Qué pasa si un GM pierde el celular con el autenticador?
Por eso generas códigos de recuperación en el registro y mantienes un proceso de reset presencial o por un segundo canal verificado. Nunca hagas un reset solo por una petición en Discord.
¿Puedo usar el mismo secreto TOTP para varios administradores?
Nunca. Cada cuenta debe tener su propio secreto único. Compartir secretos elimina la trazabilidad y el no repudio.
¿El 2FA sustituye la necesidad de contraseñas fuertes?
No. El 2FA es una segunda capa. Las contraseñas fuertes, únicas y un gestor de contraseñas siguen siendo obligatorios para cada miembro del equipo.