Skip to content

Repository files navigation

Postern

Server-side authentication for Minecraft. Registration, login, IP sessions and a freeze that actually holds. Commands only — players need no client mod.

One codebase covers four targets; the shared logic is written once and the loaders differ only in which events they subscribe to.

Supported targets

Minecraft Loader Artifact Status
1.20.1 Forge postern-forge-1.20.1-<ver>.jar verified on a real server
1.20.1 NeoForge postern-neoforge-1.20.1-<ver>.jar builds; not verified by running
1.20.1 Fabric postern-fabric-1.20.1-<ver>.jar builds; not verified by running
1.21.1 NeoForge postern-neoforge-1.21.1-<ver>.jar builds; not verified by running
1.21.1 Fabric postern-fabric-1.21.1-<ver>.jar builds; not verified by running

On 1.20.1 NeoForge is still a fork of Forge from before the two diverged — same net.minecraftforge.* packages, same mods.toml — so that target reuses the Forge entry point and buildscript unchanged, differing only in one coordinate.

Classic Forge above 1.20.1 is not built, and not by choice. ModDevGradle's legacy plugin needs a universal-srg artifact that Forge stopped publishing at 1.20.2, and the only alternative — ForgeGradle 6 — refuses to run on Gradle 9, which this tree requires for Loom and ModDevGradle. ForgeGradle 7 is unreleased. Worth revisiting when either changes.

"Verified" here means a real, reobfuscated server was started with the jar and a game client actually joined it. Confirmed that way: the freeze engages (a joined player cannot move or interact), registration issues recovery codes, an IP session lets a returning player back in without a password, and the admin commands answer from the console.

The other four targets have not been started at all. Not yet exercised even on the verified one: /logout, /changepassword, /recover, the damage protection, limbo freeze mode, and the lockout after repeated wrong passwords. They are covered by unit tests, which is not the same thing.

The word is deliberately narrow because everything short of a real client proves less than it looks. 0.1.0 passed a green build, 179 unit tests, a development server and a production server — and still froze nobody, because its mixins were never applied. Only a client joining showed it.

Classic Forge above 1.20.1 is not planned — that ecosystem moved to NeoForge.

Installing

  1. Download the jar for your Minecraft version and loader from the releases page.
  2. Drop it into the server's mods/ folder. Nothing goes on the client.
  3. Start the server once. Postern writes config/postern/config.yml and config/postern/lang/, then creates its SQLite database next to them.
  4. Edit the config if you want; /postern reload applies it without a restart.

The server must be in offline mode (online-mode=false) for any of this to make sense — that is the situation the mod exists for.

If the database cannot be opened, the server refuses to start. That is deliberate: a mod that cannot check a password must not let everyone in.

Commands

Players:

Command Alias What it does
/register <password> <repeat> /reg creates the account, issues recovery codes
/login <password> /l logs in
/logout drops the session; the next join asks for the password
/changepassword <current> <new> changes it and invalidates saved sessions
/recover <code> <new password> uses one of the recovery codes

Aliases are configurable.

Administrators (/postern, OP level 2):

/postern reload
/postern user info|register|resetpassword|unregister|unlock|transfer|forcelogin
/postern session list|clear <player|all>
/postern db status|reconnect

reload names the settings it could not apply live instead of silently ignoring them. transfer warns that a rename leaves world data behind.

Why another one

The mod exists because of three specific complaints about the alternatives, and each is a design goal rather than a feature bullet.

You cannot configure them. Postern ships a commented config.yml that explains every option, separate language files with every string, and /postern reload that applies both without a restart. A typo never stops the server: bad values are reported in the log and replaced, out-of-range numbers are clamped.

The freeze leaks. Most mods enumerate what to forbid and eventually miss a packet — EasyAuth has an open issue titled exactly "Fail to freeze player before login". Postern inverts it: a single interception point passes a whitelist of six packet kinds and drops everything else, so a packet added by a future Minecraft version is closed by default rather than open by default.

No admin tools. Reset a password, unlock an account, force a login, inspect sessions, check the database — from in game.

On top of that, Forge is a first-class target on 1.20.1. The strongest existing mod, EasyAuth, supports Fabric, Quilt and NeoForge — but not Forge, where much of the 1.20.1 audience actually is.

Notable behaviour

Sessions are bound to an IP address, which is all a server-side mod can bind to. Behind carrier-grade NAT two unrelated people share one address, and everyone on the host's own machine appears as 127.0.0.1. Postern says so in the config next to the option and drops sessions on /logout, password change, admin action and address change.

Capitalisation of a nickname is not cosmetic. On an offline-mode server a player's identity is derived from the exact name they connect with, so Notch and notch are different characters with different inventories. Postern finds the account case-insensitively but refuses the login with an explanation rather than dropping the player into what looks like a wiped world.

Password hashing never runs on the main thread. At the default cost a single BCrypt verification takes 200–400 ms — four to eight server ticks. Running it inline would be both a lag spike and a free denial-of-service vector.

What it does not do

  • No client mod. The password therefore stays in the player's own chat history, reachable with the up arrow. No server-side mod can remove it.
  • No premium (licensed account) verification. Everyone uses a password. The cryptographic session check is designed but not implemented, and the config says nothing about it rather than promising it.
  • No proxy support. Velocity and BungeeCord are unsupported, and Postern cannot detect them. Behind a proxy that does not forward player info the server sees one address for everybody, which would turn IP sessions into "anyone may enter any account" — switch session.enabled off if you run one.
  • Plugin messages do not reach a frozen player. custom_payload is not on the whitelist, because it is the channel mods use for their own handshakes and opening it would let an arbitrary mod act for an unauthenticated player. Mods that require a play-phase handshake with a timeout will not get along with the freeze.

Building

gradlew buildAll

That builds all four targets; the artifacts land in versions/<version>-<loader>/build/libs/. Plain gradlew build only builds the currently active Stonecutter node.

Java 17 (1.20.1) and Java 21 (1.21.1) are required, and Gradle downloads whichever is missing — neither has to be installed on the machine.

To run a development server for the active node:

gradlew :1.20.1-forge:runServer

Note that a development server runs on Mojang mappings, so it cannot catch mapping or mixin-application faults. Those show up only on a real server, and the build guards against the known one: verifyRefmap fails the build if the Forge jar has no refmap.

Licence

MIT — see LICENSE. The jar bundles third-party libraries, one of them under LGPL-2.1; THIRD-PARTY.md lists them and the obligations that come with them, and LICENSE-LGPL-2.1.txt is the licence itself. All three also travel inside every jar under META-INF/.

About

Server-side authentication for Minecraft 1.20.1 — Forge and Fabric from one codebase. Registration, login, IP sessions, and a freeze that actually holds.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages