RE:NODE

Security14 min read

What we do about attacks, and what no host can do

Which attacks upstream filtering actually drops, why player-shaped floods get through, and the query, whitelist and moderation settings that do the rest.

Updated

0 readers

Every host advertises protection, and most of them mean the same thing: upstream filtering that drops obvious volumetric floods before they reach the machine. That is real, it is worth having, and it stops the kind of attack most people can afford to buy. It is also not everything. Filtering works by finding traffic that does not look like a player. The moment an attack does look like a player - a few thousand machines opening real connections and making real queries - the network layer has nothing left to measure, and the problem moves to your server's settings, your allow list and your moderation. This post is about exactly where that line falls, what sits on each side of it, and what you can change today.

What an attack on a game server actually is#

"DDoS" covers three different problems that happen to share a name. They are stopped in different places, by different people, and confusing them is why so many server owners buy the wrong thing.

Volumetric. Fill the pipe. The attacker does not care what your server does with the packets; the goal is to send more bits per second than the link can carry, so that legitimate packets are dropped by a router somewhere upstream. Put a number on it: a busy game server moves roughly 50-150 KB/s per player. A hundred players is something like 15 MB/s, or 120 Mbit/s. A cheap booter subscription sends tens of gigabits. There is no plan you can buy where your server "absorbs" that, because the congestion happens before your server is involved. This is the only category where the host is the one who fixes it.

Protocol and state exhaustion. SYN floods that leave half-open TCP connections, fragmented UDP that never reassembles, connection tables filled with sessions that go nowhere. The volume is modest; the damage is to a table with a finite number of rows. Kernel and firewall settings handle most of this, and so does any competent upstream filter.

Application layer. The expensive one. A flood of unauthenticated query packets to your server browser port. Thousands of login attempts against a Minecraft server running online-mode=false. A Source engine connect flood. A mod command that loads chunks, and somebody discovering they can make a hundred accounts run it. The traffic is small, valid and indistinguishable from players. No filter upstream of your server can safely drop it, because dropping it means dropping players.

Motive is usually dull. A rival community, a player you banned last Tuesday, someone who wants your server's name, or a teenager who paid four dollars for a month of "stress testing". Extortion happens but is rarer than people expect. The practical consequence is that attacks on small servers are usually short, cheap and repeated, rather than sustained and sophisticated.

What upstream filtering drops#

Filtering sits between the public internet and the node, and it works on the traffic that is structurally wrong or structurally pointless.

  • Volumetric floods aimed at ports nothing is listening on. A UDP flood to port 3479 on a machine that only answers on 27015 is free to discard.
  • Reflection and amplification, which is the bulk of what a booter service actually sends. The attacker spoofs your address as the source, sends a small request to a third-party server, and that server sends a large reply to you. The attacker's own bandwidth is multiplied.
  • Malformed traffic. Packets with impossible header combinations, spoofed sources that fail basic sanity checks, fragments that never complete.

Amplification is worth understanding because it explains why the filter can be confident. These figures come from the US CISA advisory on UDP-based amplification, and they are ratios of reply size to request size:

ProtocolRough amplificationWhy it exists
memcachedup to tens of thousandsDebug interface exposed to the internet
NTP monlistaround 557xReturns the last 600 clients
DNS28-54xA small query, a large record set
SSDParound 30xDevice discovery replies
Quake network protocolaround 64xServer info replies
Steam protocolaround 5.5xServer info replies

The last two lines are the interesting ones for game hosting: your own query port is a reflector. It answers anybody, over UDP, with more bytes than it received. That is the same mechanism, pointed at somebody else. It is a reason to think about the query port as an exposure rather than a convenience, which the section below goes into.

Filtering is always a trade. Push the thresholds down and you drop real players during a launch night when four hundred people connect in three minutes; push them up and more of the attack arrives. Anybody who tells you their filtering has no false positives has either not been attacked or is not measuring.

What filtering cannot drop#

Traffic that looks exactly like a player is not distinguishable from a player at the network layer. That sentence is the whole limit, and it has more consequences than it first appears to.

  • A botnet that completes the handshake. If the machines actually connect, authenticate where authentication exists, and send well-formed game packets, they are players as far as any router can tell. The defence is in the game: an allow list, a password, a ban, a slot limit, a rate limit on joins.
  • Query floods at a plausible rate. One query per second from three thousand addresses is three thousand queries per second at your server and one harmless request from each source. Per-source rate limiting sees nothing wrong.
  • Expensive commands. Anything in your game or your mods that costs more CPU to answer than it costs to ask. World generation, large inventory operations, a plugin that runs a database query per chat message. This is an application bug being exploited, not a network event, and more bandwidth does not touch it.
  • The call coming from inside. A leaked RCON password, a subuser who fell out with you, an admin's account without two-factor. Read RCON, safely and subusers and least privilege, because these are far more common causes of a ruined server than any flood.
dropped herepasses throughboth portsquery repliesBooter trafficreflection, floodsUpstream filterdrops volumetricNode in Germanyshared uplinkYour servergame and query portsPlayer-shapedjoins and queries
What each layer can and cannot filter
A host that promises no downtime under any attack is selling you a sentence, not a service.

Your address is the target, and it leaks#

The first instinct is to hide the server's address. For most servers this is already impossible, and understanding why saves you a lot of wasted effort.

If your server is listed in a public browser, its address is published by design. The Steam master server list, the Minecraft server list ping, and every community tracker that scrapes them all exist to hand your address to strangers. That is the point of being listed. A listed server has a public address in the same way a shop has a public door.

What is worth controlling is the leaks that are not deliberate:

  • A DNS record that points at the machine. play.example.com resolving to the game server's address is fine and normal, but an old A record for the website on the same box is a free map. DNS records explained and subdomains for servers cover keeping these tidy.
  • A Discord status bot that posts the raw address in an embed, in a channel anybody can join.
  • Screenshots of the console. The address, the port and occasionally an RCON password, all legible.
  • Crash reports and mod logs pasted into a public support channel. Many of them include the bind address and the full command line.
  • A web map on the same machine. Dynmap or BlueMap on port 8123 is an HTTP service announcing exactly where the game server lives.

The Cloudflare question comes up constantly, so here it is plainly: the orange cloud proxies HTTP and HTTPS. It does not proxy Minecraft, Source, or any other UDP game traffic on a normal plan, so putting your website behind it hides the website's address and nothing else. If the website and the game server share a machine, the game port still tells anyone who asks. Cloudflare for websites and game servers goes through what the proxy does and does not cover.

Changing address is the last resort, and it is not a button. Open a ticket and ask rather than assuming a new one is available; expect the answer to depend on what is actually happening rather than on how annoyed you are.

Query ports: the loudest thing you expose#

Most games answer on two ports: one for the game, one for the server browser. The query port is unauthenticated by design - it has to answer strangers, because strangers are how people find you. Game server ports explained covers the general pattern; what matters here is that the query port is both the cheapest thing to flood and the thing that makes you a reflector.

Game familyQuery mechanismNotes
Source (CS2, TF2, Garry's Mod)A2S over UDP, usually game port or +1Rate limit cvars exist
Minecraft JavaStatus ping on the game portPlus optional GameSpy query
ValheimSteam query on game port +1Both UDP, both needed for the list
Unreal-basedUDP query, port varies by gameOften game port +1 or a fixed offset

Two settings actually help.

On Source engine servers, the query rate limiter has been there for years and is off nobody's radar because the defaults are already sensible:

server.cfg
// Per-client query rate before the server stops answering that addresssv_max_queries_sec 3.0// Window in seconds over which the rate is measuredsv_max_queries_window 30// Total queries per second the server will answer from everybodysv_max_queries_sec_global 60

Lowering sv_max_queries_sec_global protects the server at the cost of the server browser showing you as unresponsive to some people. That is usually the right trade during an attack and the wrong one the rest of the time.

On Minecraft, two server.properties keys matter and they are different things:

server.properties
# The GameSpy-style query protocol. Off by default. Leave it off.enable-query=falsequery.port=25565# The server list ping. Turning it off hides you from the multiplayer list# but players who already know the address can still join.enable-status=true

enable-query is an extra, older protocol that exists mainly for third-party status tools. If nothing you run needs it, it is pure exposure. enable-status=false is a blunt instrument worth reaching for during an attack: the server stops answering list pings entirely, which makes the flood cheap to ignore, at the price of looking offline to everybody.

Settings that raise the cost of attacking you#

This is where the real defence lives for the attacks nobody can filter for you.

  1. Allow list. The single most effective control that exists. A private server with white-list=true and enforce-whitelist=true in server.properties, or a populated permittedlist.txt on Valheim, cannot be joined by a botnet at all. If your community is fifty people who know each other, there is no argument against this.
  2. Never run offline mode. online-mode=false on Minecraft means the server does not verify anybody, so anyone can arrive as anyone, including as you. The only legitimate use is behind a proxy doing the authentication, with forwarding configured. Minecraft whitelist and permissions has the detail.
  3. Throttle connections. Bukkit-derived servers have settings.connection-throttle in bukkit.yml, in milliseconds, defaulting to 4000. It is a per-address minimum gap between connection attempts, and it is the cheapest join-flood defence you have.
  4. Packet limits. Paper has a packet rate limiter in its global config with a default limit and per-packet overrides. The file path has moved between Paper versions (paper.yml, then config/paper-global.yml), so check the one your build actually writes rather than copying a path from a three-year-old forum post.
  5. Turn RCON off unless something uses it. Most servers have it enabled and idle, which is a password-protected shell sitting on an open port for no reason.
  6. Firewall the admin surface. Web maps, web admin panels, database ports and RCON should be reachable from the addresses you control and nowhere else. Firewall rules that matter and rate limits and abuse cover the shape of a sensible rule set.
  7. Log who joins. When the attack is a person rather than a botnet, the answer is a ban and a moderation policy, and both need records. Logs worth keeping is the companion piece.

The connection throttle in point three is one line, and on a server that has ever been join-flooded it is the line that ended it:

bukkit.yml
settings:  connection-throttle: 4000

During an attack: the first ten minutes#

  1. Confirm it is an attack. Look at the load graph before you conclude anything. A CPU spike with a normal player count is usually a plugin or a chunk, not a flood; a normal CPU with everyone timing out looks more like the network. Reading a server load graph is the short version.
  2. Do not sit on the restart button. Restarting does not clear a flood, and a server that keeps dying and coming back is indistinguishable from a crash loop.
  3. Go quiet. Turn the allow list on, or set enable-status=false, or drop the global query rate. Making the server boring to attack ends more attacks than anything else, because the attacker is usually paying by the minute.
  4. Talk to players somewhere else. Discord, not the server. Telling three hundred people to keep reconnecting turns your players into the second wave.
  5. Open a ticket with times and logs. "It was laggy earlier" cannot be investigated. A timestamp with a timezone, the console output around it and what you saw in the graphs can be.
  6. Afterwards, rotate. New RCON password, review who has subuser access, check which of the leaks above applied to you.

What we do, stated plainly#

The honest list, with nothing rounded up:

  • Upstream filtering drops obvious volumetric floods, reflection and malformed traffic before it reaches the node. Attacks that look like real players are not filtered, and we will not pretend otherwise.
  • Every server is one container with a hard CPU limit set to the share you bought. A neighbour being attacked, or simply being busy, cannot take your CPU. A server sitting at 100% is slow, not broken, and is never suspended for it.
  • Bandwidth is unmetered in the sense that it is not billed per gigabyte. That is not a licence to saturate a shared uplink, and bandwidth and fair use explains where the line is.
  • At the memory limit the container is stopped and restarted clean rather than left to swap, which keeps one server's problem from becoming the node's.
  • A watcher polls every two minutes for uptime that went backwards or a server that went offline. Restarts you asked for are not counted. Three unexpected restarts in an hour raise a warning on the server page and an automatic ticket; six suspend the server so it stops hurting itself.
  • Backups are on every plan, stored off the machine they protect, and the platform's own backups run nightly to separate hardware and are verified and pruned on a schedule.
  • There is one location, Germany, and one node in the fleet snapshot. We do not publish an uptime percentage, because availability is sampled rather than contractual, and a number we cannot stand behind is worse than no number. The status page shows what there is.

If you want the deeper treatment of attack types themselves rather than the hosting side, DDoS attacks on game servers explained takes them apart one by one.

FAQ#

Does RE:NODE have DDoS protection?

There is upstream filtering that drops obvious volumetric floods, reflection and malformed traffic. That is the accurate description and the only one we use. There is no branded appliance, no advertised capacity figure and no availability guarantee attached to it, because publishing those would mean promising something the filtering does not do.

Will changing my server's port stop an attack?

Occasionally, for a few hours. A flood aimed at a specific port stops working when the port moves, and unsophisticated attacks are aimed at whatever the server list published. It is worth trying and it is not a fix: the new port is in the server list within minutes, and a flood aimed at the address rather than the port does not care.

Can I put my game server behind Cloudflare to hide its address?

Not on a normal plan. The proxy handles HTTP and HTTPS, not the UDP or raw TCP that game servers use. You can hide a website, a web map or a stats page that way, which is worth doing if they share a machine with the game, but the game port remains directly reachable.

My server lagged badly for ten minutes and then recovered. Was that an attack?

Usually not. Ten minutes of lag that fixes itself is much more often a plugin doing something expensive, a chunk being generated, a backup running, or a memory limit being hit. Check the load graph and the console log for that window first; an attack normally shows as packet loss and timeouts rather than a clean CPU spike.

Does a bigger plan survive attacks better?

Against a volumetric flood, no, because the congestion is upstream of anything you rent. Against an application-layer attack, sometimes, because more CPU headroom means the server keeps up with the extra work for longer. The better spend is usually an allow list and half an hour tightening the settings above.

Can my server be suspended because somebody attacked it?

Not for being attacked. Suspension comes from a server that is damaging the platform, such as one stuck in a crash loop after six unexpected restarts in an hour, and it is reversible through a ticket. Being the target of a flood is not misconduct.


Comments

Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.

0/2000