Hardening a Minecraft Server With a Firewall
Opening port 25565 is step one. What else is reachable on that machine is the part most setup guides skip entirely.
Hardening a Minecraft Server With a Firewall
Opening the game port is the easy part. What else is left open on the same machine is usually the actual risk.
Most setup guides stop at "open port 25565." A server exposed to the internet benefits from a firewall configured deliberately — allowing exactly what's needed and nothing else, rather than leaving every other port reachable by default.
Start With a Default-Deny Policy
On Ubuntu/Debian with ufw:
sudo ufw default deny incoming
sudo ufw default allow outgoingThis blocks everything inbound by default — every service that needs to be reachable gets explicitly allowed afterward, rather than everything being open until manually closed.
Allow Only What's Actually Needed
sudo ufw allow 22/tcp # SSH — see note below
sudo ufw allow 25565/tcp # Minecraft Java
sudo ufw enableAdd additional rules only for ports actually in use — a Bedrock/Geyser port (19132/udp), a web map port (8100/tcp), or RCON (25575/tcp, and only if RCON is actually being used remotely) — rather than opening a wide range speculatively.
Securing SSH Specifically
SSH is the most commonly targeted port on any internet-facing server. A few hardening steps worth doing beyond just allowing the port:
sudo ufw limit 22/tcplimit (instead of allow) rate-limits repeated connection attempts from the same IP — a basic defense against brute-force login attempts.
Changing SSH to a non-default port and disabling password authentication in favor of key-based login are both common additional steps, configured in /etc/ssh/sshd_config.
Installing fail2ban
fail2ban monitors logs (SSH, and other services with a configured filter) and temporarily bans IPs showing repeated failed login attempts:
sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2banDefault settings cover SSH out of the box — additional jails can be configured for other exposed services as needed.
Restricting Database Access
If MySQL is running on the same machine for plugin data (see the MySQL cross-server guide), it generally shouldn't be reachable from the open internet at all:
sudo ufw deny 3306/tcpunless it's specifically needed by another machine, in which case allowing it only from that machine's specific IP is safer than opening it broadly.
Checking What's Actually Listening
sudo ss -tulnplists every port actually listening on the machine — a useful sanity check against what the firewall rules assume is running, since a forgotten test service or default install can leave something open that was never intentionally exposed.
This Isn't a One-Time Setup
Firewall rules need revisiting whenever a new service, plugin, or port requirement gets added — a web map plugin, a new proxy, or a monitoring tool each potentially need their own explicit rule, and the default-deny approach means anything forgotten simply doesn't work rather than silently staying open.