RE:NODE
Browse hosting

Security14 min read

DDoS attacks on game servers, explained honestly

What the three attack layers actually do, why UDP games are cheap to hit, what upstream filtering can and cannot drop, and what you can do that helps more.

0 readers

A denial-of-service attack against a game server is usually neither sophisticated nor expensive. Someone lost a round, or wants your players, or wants twenty dollars, and they rent capacity from a service that advertises itself as a stress tester for a few pounds a month. What arrives is one of about five well-known techniques, most of which have been the same for a decade. Upstream filtering drops the obvious ones before they reach the machine, which handles the majority of what actually gets sent. The rest - the traffic that is shaped like real players doing real things - is not a network problem and cannot be solved with a bigger pipe. This post is about telling those two categories apart, because the response to each is completely different and most advice on the subject conflates them.

What an attack actually looks like from inside#

Before anything else, know the symptoms, because an attack is regularly mistaken for a crash and a crash is regularly mistaken for an attack.

During a volumetric attack:

  • Players time out, all at once, or cannot connect at all.
  • The console is quiet. No errors, no stack traces, nothing unusual in the log.
  • Memory and CPU look normal or low on the graphs, because the server is doing less work than usual, not more.
  • If you can reach the machine another way, the server process is running and healthy.

That combination - dead to players, alive and idle on the graphs - is the signature. The traffic is being dropped or is saturating something before the game process ever sees it, so from the server's point of view everybody just left.

Compare that with a crash: the console has the last thing it said before it died, the memory graph usually shows a climb, and the restart is recorded. And compare it with an application-layer attack, which looks like the opposite of a flood: CPU pinned, tick rate on the floor, the log full of connection attempts, and the server visibly doing far too much work.

The three layers, and which one you are seeing#

Attacks are grouped by which part of the stack they exhaust. The grouping is not academic: each layer is stopped in a different place, by a different party.

LayerWhat it exhaustsExamplesWho can stop it
VolumetricLink capacityUDP floods, amplificationThe network upstream of you
ProtocolConnection state, packet rateSYN floods, fragment floodsThe network, and the kernel
ApplicationThe game's own CPU and logicQuery floods, join bots, RCON guessingYou, in the game's config

Volumetric is the one everybody pictures: enough bits per second to fill the pipe. It does not matter what your server does with them, because the congestion happens before they arrive. The only place this can be fixed is upstream, where there is more capacity than the attack.

Protocol attacks are smaller in bits and larger in packets. A SYN flood opens half-connections that consume tracking state on anything stateful in the path. A fragment flood sends IP fragments that never complete, so reassembly buffers fill. These are cheap to send and are stopped by stateless filtering and by sensible kernel defaults, net.ipv4.tcp_syncookies among them.

Application attacks send small amounts of perfectly valid traffic that costs you a lot to process. A server browser query costs an attacker one small packet and costs you a response built from live server state. A join attempt costs them nothing and costs you an authentication round trip, a world entry and possibly a save. This is the layer that filtering cannot help with, and it gets its own section below.

Reflection and amplification, the cheap part#

Most of what a booter service actually sends is reflection, because reflection is how a small budget becomes a large attack. The mechanism depends on one fact about UDP: there is no handshake, so the source address on a packet is whatever the sender writes in it, and a server that receives it replies to that address.

source address forgedlarge repliesdropped on the wayAttackersmall spoofed requestsPlayerstime outOpen UDP serversDNS, NTP, memcachedThe uplinkfills up hereYour servernever sees requests
How a reflection attack reaches your server

The attacker sends a small request to a third-party server that answers UDP, writing your address as the source. The third party sends its reply to you. It is not compromised and it is not complicit; it is answering a question it believes you asked. Amplification is the ratio between the size of the request and the size of the reply, and for some protocols it is enormous:

ProtocolPortTypical amplification
DNS5328-54x
NTP monlist123up to about 557x
SSDP1900around 30x
CLDAP38956-70x
memcached11211thousands to tens of thousands
Source engine query27015single figures to about 45x

Those figures are the ones cited in the US-CERT advisory on UDP-based amplification and in the incident reports from the large memcached events. The practical meaning: an attacker with a modest connection can direct tens of gigabits at you by borrowing other people's bandwidth, and the packets arrive from thousands of innocent addresses rather than from theirs. Blocking the sources is pointless because the sources are victims too.

The last row is the one that concerns game hosting directly. Source engine query ports were used as reflectors for years, which is why Valve added a challenge to A2S_INFO: the server now replies to an unknown source with a small challenge number and only answers properly when that number comes back. It is the same logic as a TCP handshake, retrofitted onto a query protocol, and it removed a popular reflector from the internet.

The real fix for all of this is ingress filtering at the networks that let spoofed packets out, which has been a published best practice since 2000 and is still not universally deployed. Until it is, reflection remains cheap.

Why game servers are the easy target#

Four properties make a game server unusually attractive, and none of them are about how important you are.

Your address is public by design. Players have to reach it. It is in a server browser, on a listing site, in a Discord channel, in a screenshot. There is no version of running a public server where the address is a secret.

Most game traffic is UDP. No handshake means spoofing is trivial and stateless floods are cheap. It also means a filter cannot use connection state to tell a real client from a forged packet without knowing the game's protocol. TCP vs UDP for game servers is the background on why games chose UDP and what that costs.

The service is latency-sensitive. A website that takes an extra 400 ms is slower. A game server that takes an extra 400 ms is unplayable. An attacker does not need to take you offline; they only need to make it not worth playing, which takes a fraction of the traffic.

The motive is usually personal. A rival community, a banned player, a clan with a grudge, or extortion aimed at someone who has fifty regulars and no technical staff. This means attacks recur, arrive at your peak hour, and stop when the person gets bored - which is why a ten-minute outage on a Friday evening is the common case rather than a sustained campaign.

What filtering can do, and what it cannot#

Here is the honest account, and it is the same one on the security page.

Upstream filtering drops obvious volumetric floods before they reach the machine. It also drops reflection traffic, which as described above is most of what gets sent, and malformed traffic that no legitimate client would produce. That is real and it is worth having: it covers the large majority of what a booter service can actually generate, and it works because those categories are identifiable without knowing anything about your game.

What it cannot do is separate traffic that looks exactly like a player from a player. At the network layer there is no difference between a real client sending a join packet and an attacker sending the same packet. Distinguishing them needs the game's own state - who has authenticated, who is rate-limited, which identity has joined nine times in a minute - and that state lives in the game server, not in a filter upstream.

Three more limitations worth knowing, because they explain behaviour you may see:

  • Filtering has a threshold. Something has to trigger before mitigation engages, and the seconds before it does are real. A short, sharp burst can be over before any of it matters.
  • Filtering can cost you legitimate traffic. Aggressive rules against UDP floods can drop real players' packets, which is why mitigation is a balance rather than a switch, and why "just filter harder" is not free.
  • Nothing filters the last hop into a player's house. If an attacker targets a player rather than your server, that is their ISP's problem and there is nothing you or your host can do about it. Voice chat and peer-to-peer features are how addresses leak for that.

No host can promise otherwise. A host that promises no downtime under any attack is selling you a sentence, not a service. What we actually do about attacks is the short version of the same position.

The attacks that look exactly like players#

This is the category people are least prepared for, because it does not look like a network event at all. The server is up, the link is fine, and the game is unusable. All of these are handled in the game's configuration, not upstream.

Query floods. Repeated server-browser queries, at a rate no browser would produce. Each one makes the server build a response containing its current player list and map. The fixes are a query cache or rate limit if the game has one, moving the query port off the default, and in some engines turning off public listing while it happens. Several games' server plugins provide exactly this; see rate limits and abuse.

Join floods and bot joins. Clients that connect, occupy a slot through the handshake and world entry, then disconnect and return. Minecraft is the classic victim because connections are TCP and cheap for the client to make, and the mitigation is an anti-bot plugin or a proxy in front that authenticates before the backend sees anything. Velocity in front of a Minecraft network is the standard shape of that.

RCON brute force. Repeated guesses at your remote console password, which both burns CPU and occasionally succeeds. If RCON is exposed at all it should have a password nobody has seen, never share a value with anything else, and ideally be restricted to addresses you control. Using RCON safely covers it.

In-game resource exhaustion. Not a network attack at all: a player doing something legal that costs the server enormously. Spawning thousands of entities, building a machine designed to lag, exploiting a mod's pathfinding, abusing a map-download feature. Moderation, permissions and entity limits are the whole answer here.

The uncomfortable pattern across all four: the most effective application-layer attacks on a small community are usually launched by somebody who is already in it.

What you can do that helps more than any filter#

Ranked roughly by how much difference each one makes.

  1. Keep the address off things that are not the server list. Do not publish the raw IP where you would not publish your home address. Use a hostname for players, and know that a hostname is a convenience rather than a hiding place: an A record resolves to the address, and an SRV record for Minecraft does the same. Connecting a domain to a game server explains what a name does and does not buy.
  2. Separate your website from your game server. Put the website on different hosting with a different address. A web front end can sit behind a proxy that hides its origin; a game server on UDP cannot. This matters because the website is usually how people find the game address in the first place. Cloudflare for websites and game servers is specific about what the orange cloud proxies and what it never will.
  3. Treat the query port as an exposure. It is how listing sites find you, and it is also how attackers do. Run it because you want to be listed, not by habit, and do not leave a second one allocated that nothing uses. Game server ports explained covers which ports each game really needs.
  4. Assume somebody in your community will eventually be the problem. Keep staff permissions minimal and revocable, do not share administrative passwords, and keep an activity log you can read afterwards. Subusers and least privilege is the mechanism for that on the panel side.
  5. Rate-limit at the game layer. Connection throttles, query caching, an anti-bot plugin, a queue. These are the only defences that work against the traffic filtering cannot see.
  6. Have backups you have restored. An attack is not the only bad day, and the recovery path is the same one. A backup nobody has restored is a hypothesis.
  7. Turn on two-factor for the account that controls all of it. Most "we got DDoSed" stories that end badly are actually account compromise stories. Two-factor on your panel account takes two minutes.

What does not help, despite being suggested constantly: changing your IP address. It works until the address is rediscovered, which for a public server is measured in hours, and it breaks every saved favourite your players have.

During an attack#

A short procedure, because in the moment people improvise badly.

  1. Confirm what you are looking at. Check the console and the graphs. Idle server, no log activity, players gone: volumetric or protocol. Pinned CPU, log full of connections: application layer.
  2. Write down the time. Start, end, and what players reported. Without timestamps nobody can look anything up afterwards.
  3. Do not restart repeatedly. It does not clear a flood, it loses unsaved progress, and it makes the incident harder to read later.
  4. Open a ticket with the timestamps. From the panel it reaches all staff and attachments stay private. Include whether the game was reachable from anywhere at all, and any trace you managed to take - reading traceroute and mtr has the method.
  5. If it is application layer, change the game's configuration. Turn off public listing, raise connection throttles, whitelist temporarily. A whitelist is a blunt instrument and it ends the incident immediately.
  6. Afterwards, work out how they found you and who cared. Attacks on small servers are almost always personal, and the answer to "who" is usually available if you ask your regulars.

One last note on bandwidth: attack traffic is traffic. Unmetered means you are not billed per gigabyte, not that a shared uplink can absorb anything indefinitely. Bandwidth and fair use sets out what the word actually covers.

FAQ#

Can a host guarantee my server stays up during an attack?

No, and any host saying otherwise is describing a marketing position rather than a technical one. Upstream filtering drops obvious volumetric floods, reflection and malformed traffic, which is most of what gets sent. Traffic shaped like real players is not distinguishable at the network layer and has to be handled in the game.

Will hiding behind a domain name protect me?

No. A domain is a convenience for your players, not a shield: the record resolves to the same address and anybody can look it up in a second. Proxies that genuinely hide an origin address work for web traffic over TCP; they do not carry the UDP that game servers use.

Why is my server unplayable when the graphs look fine?

Because the bottleneck is not the server. A flood is congestion upstream of the machine, so the game process sees fewer packets than usual, not more, and reports a healthy idle server while nobody can reach it. Idle graphs plus absent players is the signature of a network event rather than a fault.

Are booter and stresser services actually a threat?

Yes, in the narrow sense that they are cheap, easy to buy and generate exactly the traffic described here. They are also mostly reflection, which is the category filtering handles best. The threat they represent to a small community is a bad half hour at peak time, repeated, rather than a sustained outage.

What is a join flood and how do I stop it?

Clients connecting repeatedly to consume slots and handshake work. It is stopped inside the game: an anti-bot plugin, a connection throttle, a proxy that authenticates before the real server is involved, or temporarily a whitelist. No amount of upstream filtering helps, because each connection is individually legitimate.

Should I pay extra for protection as an add-on?

Read what the add-on actually does before paying for it. If it is upstream filtering of volumetric and reflection traffic, that is worth having and many hosts include it. If it is a number of gigabits with no description of what is dropped, you are buying a figure rather than a behaviour.


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