DUXPLIMA Documentation

Two-factor login

Approving a login from Discord: the freeze, GeoIP, denial and the IP whitelist.

With 2FA on, a linked player joining the server is frozen and a Discord DM asks whether the login is theirs. Approve and they play; deny and they are kicked or banned; ignore it and the timeout kicks them.

It is the single strongest protection against a stolen Minecraft session on a staff account, and it lives in two-factor.yml.

Enabling it

two-factor:
  enabled: false
  timeout: 120
  freeze-player: true
  use-geoip: true
  geoip-database: "plugins/uxmDiscordSync/GeoLite2-City.mmdb"

Only players who have linked an account can be challenged β€” the plugin needs a Discord user to ask.

The freeze

freeze-restrictions:
  movement: true
  commands: true
  drop-items: true
  pickup-items: true
  damage: true
  interact: true

Each restriction is enforced separately, and damage: true covers both taking and dealing it. Leave all six on: a frozen player who can still be hurt can be killed while waiting for a phone notification, and one who can still run commands can /home out of whatever situation the challenge was protecting.

Block breaking and placing are blocked with interact.

The prompt

embed:
  color: "#ffaa00"
  title: "πŸ” Login Verification Required"
  description: |
    **Player:** %player_name%
    **Server:** %server_name%
    **IP Address:** %ip_address%
    **Location:** %location%
    **Session Code:** %session_code%
    **Time:** %timestamp%
  thumbnail: "https://mc-heads.net/avatar/%player_name%/64"
  footer: "You have %timeout% seconds to respond"

buttons:
  approve: "βœ… Yes, this is me"
  deny: "❌ No, this is not me"

%ip_address% and %location% are what make the prompt useful β€” a login from a city the player has never been to is the signal they act on. %location% requires GeoIP.

GeoIP

use-geoip: true needs MaxMind's free GeoLite2-City database, downloaded from MaxMind and placed at the path in geoip-database. Without the file, %location% is empty and everything else still works.

The database is updated by MaxMind periodically; a stale copy gives progressively vaguer answers rather than wrong ones.

Denial and timeout

on-deny:
  kick-player: true
  kick-message: "..."
  ban-player: false
  ban-duration: "24h"
  ban-reason: "Unauthorized login attempt"
  notify-admins: true
  admin-permission: "uxmdiscordsync.admin.notify"

on-timeout:
  kick-player: true
  kick-message: "..."

Deny means the player is saying this is not me β€” someone else has their session. A kick stops that login; ban-player: true with a duration stops the next fifty. 24h is a reasonable default, and permanent is available for staff accounts.

Timeout is treated more gently, and correctly so: the usual cause is a player who did not see the DM, not an attacker.

notify-admins: true messages everyone holding uxmdiscordsync.admin.notify, which is how you find out that an account is under attack while it is happening.

IP whitelist

ip-whitelist:
  - "127.0.0.1"
  - "192.168.0.0/16"
  - "10.0.0.0/8"

Addresses that skip the challenge, CIDR supported. The defaults are the private ranges, which is what stops your own proxy or a LAN test client from being challenged on every join.

Do not whitelist a public range

Every address in this list can join a linked account without verification. The defaults are private ranges that cannot be reached from the internet. Adding a public range, or a player's home address as a convenience, removes the protection for anyone who can reach it.

Before you enable it

Test with your own account first. A 2FA system with a wrong guild id, a bot that cannot DM, or a timeout shorter than a phone notification takes to arrive will lock every linked player out of the server, staff included β€” and the fix requires editing the config and restarting.

Set freeze-player: true and a generous timeout for the first day.