Brazil's biggest MU Online portal — since 2003
Tutorial Advanced Admin

How to set up 2FA for staff accounts in MU Online

Learn how to protect your MU Online server's administrator and GM accounts with two-factor authentication, from the web panel to database and game-server access.

BR Bruno · Updated on Jul 10, 2026 · ⏱ 12 min read
Quick answer

Staff accounts are the most valuable target on any MU Online server. A compromised GM can generate excellent items, grant infinite resets, ban legitimate players, or drain the Web Shop in minutes. And, unlike an ordinary player account, the damage from a compromised administrative account is practic

Staff accounts are the most valuable target on any MU Online server. A compromised GM can generate excellent items, grant infinite resets, ban legitimate players, or drain the Web Shop in minutes. And, unlike an ordinary player account, the damage from a compromised administrative account is practically irreversible for the server's reputation. Two-factor authentication (2FA) is the most cost-effective defense you can deploy: even if an administrator's password leaks in a phishing attack, the attacker still needs the second physical factor.

In this tutorial you'll set up 2FA at every relevant layer of a MU Online server: the web panel (AMS/UserControlPanel or a custom panel), SSH/RDP access to the machine, the SQL Server database, and, when possible, the in-game GM login itself. The examples assume a common stack (Windows Server + SQL Server + PHP panel), but the concepts apply to any combination. File details and table names vary by season and emulator (IGCN, MuEMU/Season 6, X-Files, among others), so treat the paths as an EXAMPLE and adapt.

Prerequisites

Before you start, make sure you have:

  1. Administrative access to the machine (physical or VPS) where the server runs.
  2. Access to the server's web panel with permission to edit the source code, or to the panel's repository.
  3. Access to SQL Server with a sysadmin account (to create the 2FA support tables).
  4. A TOTP authenticator app installed on the team's phones (Google Authenticator, Aegis, Authy, or similar).
  5. An up-to-date inventory of all privileged accounts: site administrators, in-game GMs, database accounts, and operating-system users.
  6. A second verified contact channel for each team member (for recovery), preferably in person or via a known phone number.

Reserve a maintenance window. Enabling 2FA incorrectly can lock you out of your own panel, so always keep an emergency account documented in a secure place (offline vault).

How TOTP works (the real concept)

The most widely used standard is TOTP (Time-based One-Time Password), defined in RFC 6238. The server and the user's app share a secret (a Base32 string) generated once at enrollment. Every 30 seconds, both sides compute a 6-digit code using HMAC-SHA1 over the secret and the current time. If the two codes match, the login is approved.

This has three practical implications:

  • The server's clock must be synchronized (use NTP). If the time drifts more than 1–2 windows, every code fails.
  • The secret never travels after the initial enrollment, which makes TOTP resistant to network interception.
  • You must store the secret encrypted in the database, never in plain text.

Step 1 — Prepare the database

Create a table to store the secrets and the 2FA state per staff account. Example for SQL Server (adapt the names to your emulator):

CREATE TABLE Staff2FA (
    AccountID     VARCHAR(10)  NOT NULL PRIMARY KEY,
    SecretEnc     VARBINARY(256) NOT NULL,  -- encrypted TOTP secret
    Enabled       BIT          NOT NULL DEFAULT 0,
    RecoveryCodes VARBINARY(512) NULL,       -- hashes of the backup codes
    LastUsedStep  BIGINT       NULL,         -- prevents replay of the same code
    CreatedAt     DATETIME     NOT NULL DEFAULT GETDATE()
);

The LastUsedStep field stores the last accepted time step and prevents a valid code from being reused within the same 30-second window (replay protection). Encrypt SecretEnc with a key that lives outside the database (for example, in an environment variable or the application vault), so that a database dump doesn't leak the secrets.

Step 2 — Enable 2FA in the web panel

The web panel is usually the most exposed entry point, so start with it. The enrollment flow is:

  1. The administrator logs in normally with username and password.
  2. The panel generates a random 20-byte Base32 secret.
  3. The panel displays a QR Code (format otpauth://totp/MyMU:user?secret=BASE32&issuer=MyMU) to scan in the app.
  4. The administrator types the current code to confirm the app was set up correctly.
  5. Only then is Enabled set to 1 and the recovery codes shown a single time.

A minimal verification example in PHP using a TOTP library:

require 'vendor/autoload.php';
use OTPHP\TOTP;

// secret retrieved and decrypted from the database
$totp = TOTP::createFromSecret($secretBase32);
$totp->setPeriod(30);

if ($totp->verify($_POST['codigo'], null, 1)) { // tolerance window = 1
    // also validate LastUsedStep to prevent replay
    liberarLogin($accountId);
} else {
    registrarFalha2FA($accountId, $_SERVER['REMOTE_ADDR']);
}

The third parameter (1) allows a tolerance window for small clock desynchronizations. Don't raise this value beyond 1 without need, as it widens the attack window.

Step 3 — Protect operating-system access

A protected panel is useless if the attacker can RDP or SSH directly into the machine. On Windows servers, avoid exposing port 3389 (RDP) to the internet; put everything behind a VPN and, if possible, require 2FA on the VPN. For RDP itself, tools like Duo or equivalent solutions add an approval prompt. On Linux, configure pam_google_authenticator on SSH:

sudo apt install libpam-google-authenticator
google-authenticator   # generates the QR and the recovery codes per user

Then edit /etc/pam.d/sshd to include auth required pam_google_authenticator.so and set ChallengeResponseAuthentication yes (or KbdInteractiveAuthentication yes in recent versions) in sshd_config. Always combine this with public-key authentication, never 2FA alone replacing the key.

Step 4 — Protect the database

SQL Server has no native TOTP, but you reduce the risk like this:

  • Never expose port 1433 to the internet. Access only via VPN or tunnel.
  • Use Windows (Integrated) authentication whenever possible, inheriting the 2FA from the OS login.
  • Create application accounts with minimum privilege (only the necessary tables), separate from the administrative accounts.
  • Log and alert on logins by the sa account.

Step 5 — 2FA for GMs inside the game

Some emulators allow requiring an extra step for GM commands. Since few support native TOTP, a practical approach is to allow the most dangerous administrative commands (create item, grant zen, ban) only from accounts whose web login has already passed 2FA, or to require a secondary in-game administrative password. This varies quite a bit by season/emulator; consult your core's documentation before editing binaries.

LayerRecommended methodAcceptable alternativeAvoid
Staff web panelTOTP via appFIDO2 keyPassword only
Access VPNTOTP or pushCertificate + passwordDirect access without VPN
SSH (Linux)Public key + TOTPKey + strong passwordPassword alone
RDP (Windows)VPN + 2FA on the VPNRDP Gateway with MFA3389 open
SQL ServerWindows authDedicated account + VPNsa exposed
In-game GM commandsAccount with web 2FASecondary admin passwordFree commands

Table of factors by account sensitivity

Account typeMinimum factorCredential rotation
Site adminTOTP + recovery code90 days
Senior GMTOTP90 days
Junior GM / moderatorTOTP120 days
Application account (DB)Secret in a vault180 days

Common errors and fixes

ProblemLikely causeFix
All codes are rejectedServer clock desynchronizedConfigure NTP and check the time zone; TOTP uses UTC
A code works twiceMissing LastUsedStep checkRecord and block reuse of the same time step
GM locked out of the panelLost the phone with no recovery codeReset via a second verified channel, never via Discord
Secrets leak in a database dumpSecret saved in plain textEncrypt SecretEnc with a key outside the database
Brute-force attack on the codeNo attempt limitLock the account after 5 failures and alert the admin
2FA bypassed via open RDPOS layer unprotectedClose the port and require VPN with MFA

Recovery and rotation best practices

Generate 8 to 10 single-use recovery codes at enrollment and store only their hash in the database. Instruct the team to keep them offline. Define a reset process that requires verification through a known second channel (a phone call, physical presence), because social engineering against support is the most common vector for taking down 2FA. Rotate the secrets periodically and immediately revoke access for anyone who leaves the team.

Launch checklist

  • All staff accounts inventoried and classified by sensitivity
  • Staff2FA table created with encrypted secrets
  • Server clock synchronized via NTP (UTC)
  • 2FA mandatory in the web panel for all staff
  • Replay protection (LastUsedStep) validated
  • Attempt limit and brute-force lockout active
  • VPN with MFA in front of RDP/SSH/SQL
  • Ports 1433 and 3389 closed to the internet
  • Recovery codes generated and stored offline
  • Second-channel reset process documented
  • Emergency account tested and stored in a vault
  • Team trained on phishing and SIM swapping

With 2FA deployed at every layer, you eliminate most scenarios where a leaked password turns into a compromised server. If you're still building the structure from scratch, it's worth reviewing the guide on how to create a MU Online server to make sure the security foundation is right from the start. Remember: 2FA is a layer, not a silver bullet. Combine it with strong passwords, least privilege, and continuous monitoring for a truly solid defense.

Frequently asked questions

Is SMS 2FA secure enough for my team?

SMS is better than nothing, but it's vulnerable to SIM swapping. Prefer TOTP apps like Google Authenticator or physical FIDO2 keys for accounts with administrator privileges.

Do I need to change the emulator to support 2FA?

Not necessarily. 2FA is applied at the access layers (web panel, SSH, database, and RDP), which sit outside the emulator. The game core rarely needs to be modified.

What happens if a GM loses the phone with the authenticator?

That's why you generate recovery codes at enrollment and keep an in-person reset process or a second verified channel. Never reset just because someone asked on Discord.

Can I use the same TOTP secret for several administrators?

Never. Each account must have its own unique secret. Sharing secrets eliminates traceability and non-repudiation.

Does 2FA replace the need for strong passwords?

No. 2FA is a second layer. Strong, unique passwords and a password manager remain mandatory for every team member.

BR
Events, maps & items editor

Bruno specializes in MU Online events, maps, bosses and item economy. He documents every detail based on real gameplay.

Keep reading

Related articles