Server-side password authentication for Minecraft Forge servers running in offline mode.
Players can join with an unmodified vanilla client.
Important
Server Login is designed for servers with online-mode=false. It protects in-game identities with passwords, but it does not restore Mojang authentication, encrypt Minecraft traffic, or replace a firewall, anti-DDoS service, VPN, or secure proxy tunnel.
Offline-mode servers do not verify that a player owns the username they connect with. Server Login closes that gap with a fail-closed authentication gate: until a player signs in, the server blocks movement, chat, commands, damage, inventory actions, world interaction, and unapproved network packets.
The mod runs entirely on the server. Players stay at their logout position and authenticate through /login; no client mod, custom launcher, or waiting-room teleport is required.
- Server-only installation — vanilla Minecraft 1.20.1 clients can connect normally.
- Unified login flow — one
/logincommand handles both registration and sign-in. - Fail-closed packet gate — unknown and unauthenticated connections remain locked by default.
- Strong password storage — PBKDF2-HMAC-SHA256 with a random per-account salt and a default work factor of 600,000 iterations.
- Brute-force resistance — per-account lockouts, one in-flight credential check per player, a server-wide rate limit, and an address-based rate limit.
- Safe session binding — authentication belongs to the live connection, preventing a reconnect from inheriting an older session.
- Configurable timeout — warning and automatic disconnect, or manual queue management when the timeout is disabled.
- Administrator tools — inspect accounts, review the login queue, remove lost accounts, and kick stalled logins.
- LuckPerms integration — exposes the
serverlogin:authenticatedcontext. - Administrator chat — local proximity chat plus a separate global admin-only channel.
- Translatable messages — English and Russian ship with the mod, and every string can be reworded per server without rebuilding.
| Component | Supported version |
|---|---|
| Minecraft | 1.20.1 |
| Mod loader | Forge 47.4.10 or newer within the 47.x line |
| Java | 17 or newer |
| Runtime side | Dedicated server |
| Client installation | Not required |
| LuckPerms | Optional |
- Install a Minecraft 1.20.1 Forge server using Forge 47.4.10 or newer.
- Place
serverlogin-1.0.3.jarin the server'smodsdirectory. - Set
online-mode=falseinserver.properties. - Restart the server.
- Review the generated configuration at
config/serverlogin-common.tomlbefore opening the server to the public.
Accounts are stored per world in world/serverlogin/users.json.
| Command | Purpose |
|---|---|
/login <password> or /l <password> |
Sign in to an existing account |
/login <password> <password> or /l <password> <password> |
Register a new account; both values must match |
/changepassword |
Start the private password-change prompt |
/logout |
Close the current authenticated session |
The mod shows the correct usage after a player connects. New passwords are 6–64 characters by default. The separate /register and /reg commands are intentionally not used.
Account management requires permission level 3.
| Command | Purpose |
|---|---|
/auth count |
Show the number of registered accounts |
/auth status <player> |
Check whether an account exists |
/auth remove <player> |
Remove an account and immediately re-lock that player if online |
/auth queue |
List pending players, wait times, timeout state, and failed attempts |
/auth kick <player> [reason] |
Disconnect a player who is still waiting to authenticate |
Players with permission level 2 or higher use local administrator chat by writing normally. The default radius is 100 blocks in the same dimension. Global admin-only chat is available through /adminchat, /ac, /localchat, or /local chat.
Before authentication, incoming packets are denied unless explicitly permitted. The filter runs at the connection layer, before normal gameplay event handlers, so container clicks, sign and book edits, creative slot changes, completion requests, and other gameplay actions never reach the server.
Keep-alive, pong, teleport confirmation, client information, and resource-pack negotiation remain available. Movement packets are discarded and the player is returned to the original anchor position.
The [gate] configuration controls the small pre-authentication surface:
allowedCommandscontains command roots without/or arguments. It defaults tologinandl.allowedPayloadChannelscontains either an entire namespace such asvoicechator one exact channel such asvoicechat:secret.maxCredentialChecksPerSeconddefaults to 8, with a burst capacity of twice that value.maxCredentialChecksPerAddressPerMinutedefaults to 30.
An allowed payload namespace exposes every payload owned by that mod, not just its handshake. For a public server, enable diagnostics.logBlockedPayloads, connect once with the real modpack, inspect the reported channels, and replace broad namespaces with the exact channels the pack needs.
Address-based throttling is only accurate when the server sees the real player address. Behind Velocity or BungeeCord, configure IP forwarding correctly; otherwise every connection appears to originate from the proxy.
The [diagnostics] options are off by default and exist for troubleshooting. verboseLogging
records every authentication step, logDisconnectStacks names the mod behind each disconnect, and
joinWatchSeconds keeps reporting whether a player is still connected after joining — useful when
sessions die shortly after login. Kicks and network exceptions are logged either way.
Server Login is installed on the server only, so a vanilla client has no translation files for it. Every player-facing string is therefore resolved on the server and sent as plain text, selected by one config option:
[general]
language = "en_us"en_us and ru_ru ship with the mod. Any wording can be replaced without rebuilding by creating
config/serverlogin/lang/<language>.json containing only the keys you want to change:
{
"login.success": "Welcome back, adventurer!",
"kick.timeout": "You took too long. Reconnect and try again."
}The full key list is serverlogin/lang/en_us.json inside the mod JAR. Keys missing from an
override fall back to the bundled catalogue, so a partial file is fine. Placeholders such as
{0} are substituted in order and must be kept.
When LuckPerms is installed, Server Login publishes this context:
serverlogin:authenticated=true|false
Use it to deny permission-sensitive features to players who have not authenticated yet, without adding a compatibility patch for every server mod.
- The mod never stores plaintext passwords. The account database contains salts, hashes, and work-factor metadata.
- Server Login diagnostics record password length and outcomes, never the password value.
- Minecraft clients may retain
/logininput in local command history. Do not leave a logged-in client accessible on a shared computer. - Other server mods may log command arguments. Exclude
/loginand/lfrom third-party command logging. - Offline-mode traffic does not provide transport confidentiality. On an untrusted network path, use a VPN or a properly secured proxy tunnel.
- Back up
world/serverlogin/users.jsontogether with the world. Losing it means losing the local account registry.
Please report suspected vulnerabilities privately through GitHub Security Advisories. See SECURITY.md for the disclosure policy.
Clone the repository and build with JDK 17 or newer:
./gradlew buildOn Windows:
.\gradlew.bat buildThe reobfuscated mod JAR is written to build/libs.
Run the Forge GameTest suite with:
./gradlew runGameTestServerOptional local compatibility mods may be placed in libs; they are detected automatically and are not required for a normal build.
Server Login is available under the MIT License.
