Stopping A2S Query Floods (Rate-Limiting Port 27015)

May 21, 2025 Daemon666 8 min read 11 просмотров

A CS 1.6 server answers every A2S_INFO query it receives on UDP 27015 — that is how it appears in the master list and in server browsers. Attackers abuse this: they blast thousands of spoofed query packets per second, the server dutifully builds and sends a reply to each, and the main game thread spends all its time answering queries instead of simulating the round. Players see rubber-banding, then mass timeouts. This is a query flood, and unlike a raw bandwidth DDoS you can blunt most of it on the host itself.

1. Understand what the flood looks like

Query packets are connectionless: they start with the four bytes 0xFF 0xFF 0xFF 0xFF followed by a request byte such as T (A2S_INFO), U (A2S_PLAYER) or W. They are tiny and cheap to send but force the server to assemble a larger reply, which is why the attack also works as a reflection/amplification vector against third parties. The key fact: a real player sends a handful of queries when browsing, then switches to a full connection. A flood sends the same query byte from many spoofed source addresses, hundreds of times a second each.

2. Confirm it with tcpdump

Before you block anything, verify the traffic is really query spam and not legitimate load. On the host:

tcpdump -ni any udp port 27015 -c 200

A flood shows a torrent of small inbound packets from many source IPs, often with implausible source ports or obviously spoofed ranges. Compare the packet rate to your player count — a 20-slot server does not generate thousands of packets per second of inbound queries under normal play. If CPU is pinned at the same time, cross-check with the HLDS 100% CPU guide.

3. Rate-limit queries with iptables hashlimit

The most effective host-level defence is to cap how many packets any single source IP may send to the game port per second, using the hashlimit module. This lets real browsers and players through while throttling a source that hammers the port:

iptables -A INPUT -p udp --dport 27015 \
  -m hashlimit \
  --hashlimit-name cs_queries \
  --hashlimit-mode srcip \
  --hashlimit-above 30/sec \
  --hashlimit-burst 60 \
  -j DROP

This drops packets from any single IP that exceeds 30 per second (with a short burst allowance of 60). Tune the numbers to your traffic — a busy server with a live feed of joins may need a higher ceiling. Because it keys on source IP, a distributed flood from thousands of hosts each staying under the limit will slip through, which is the boundary where host rules end and DDoS-protected hosting begins.

4. Drop malformed and oversized query packets

Legitimate A2S queries are short. You can discard obviously abusive connectionless packets by length before they reach the game process:

iptables -A INPUT -p udp --dport 27015 -m length --length 1:32 \
  -m hashlimit --hashlimit-name cs_small \
  --hashlimit-mode srcip --hashlimit-above 15/sec -j DROP

Apply the tighter limit to the small connectionless packets while leaving normal in-game traffic (which is larger and belongs to established clients) alone. Keep the rules in the right order and make sure your firewall still permits the port at all — see which ports a CS 1.6 server needs open.

5. Persist the rules

iptables rules vanish on reboot. Save them so a restart does not leave you exposed:

iptables-save > /etc/iptables/rules.v4

On a systemd host, install iptables-persistent (or your distro's equivalent) so the rules reload at boot alongside your HLDS systemd service.

Common errors

  • Server drops off the master list after adding rules — your limit is too aggressive and it is throttling the master server's own queries, or you accidentally blocked outbound. Loosen --hashlimit-above and confirm the port is still reachable. See server not in the master list.
  • Real players still time out during a flood — the attack is distributed and each source stays under your per-IP cap. Host rules cannot fully stop that; you need upstream filtering.
  • CPU still pinned after blocking — the flood may be hitting a different port, or it is a connection flood rather than a query flood. Re-run tcpdump to see the real target port.
  • Legitimate server-list refreshes look like an attack — a popular server receives a lot of queries normally. Do not set the ceiling below what your genuine browse traffic needs, or you will hide yourself.

Verification

With the rules loaded, watch the counters climb only during an actual flood:

iptables -L INPUT -v -n --line-numbers

The DROP rule's packet counter should stay near zero in normal operation and spike when a flood hits. During an attack, confirm the server FPS holds and players stop timing out. If the counter never moves but the server still lags, the traffic is not a simple per-IP query flood and the fight moves upstream to your host or a scrubbing provider. A separate high-ping kicker will not help here — that is for individual laggy players, not query floods.

Участники: Daemon666 ✦
Поделиться: