Why Game Servers Are Prime SYN Flood Targets
If you run a Minecraft, FiveM, Rust, ARK, or CS2 server, you are operating a publicly advertised IP address with a well-known port. Server list crawlers, master server heartbeats, and query protocols broadcast your IP to anyone who looks. Attackers do not need to scan for it. They just open the server browser.
Game servers also tend to run on bare metal or unmanaged VPS instances without enterprise-grade upstream filtering. The hosting provider might offer basic null-routing at 10 Gbps, but a SYN flood does not need 10 Gbps to be effective. A modest 50,000 SYN packets per second is enough to exhaust the TCP backlog on a default Linux kernel configuration, and your game server will start dropping legitimate connections long before the link saturates.
There is another factor that makes game servers uniquely vulnerable: operators expect high packet rates. A Rust server with 250 players can easily generate 40,000+ packets per second of legitimate UDP game traffic. When a SYN flood adds another 80,000 PPS of TCP traffic, the total PPS might not look alarming to someone who is used to seeing big numbers. The attack hides in the noise unless you know exactly where to look.
What a SYN Flood Looks Like on a Game Server
A SYN flood against a web server causes HTTP timeouts. A SYN flood against a game server causes something different and often more confusing. Here is what your players and your monitoring will report:
- Rising ping for connected players. Even though game traffic is UDP, the kernel is burning CPU cycles processing the flood of SYN packets. Softirq load increases, and UDP packet processing gets delayed. Players see their ping spike from 30ms to 200ms+ within seconds.
- New players cannot connect. Most game servers use TCP for the initial handshake, authentication, or map download. Minecraft, FiveM, and ARK all establish a TCP connection before switching to UDP for gameplay. If the SYN backlog is full, new TCP connections time out and players see "Connection timed out" or "Server not responding."
- Server disappears from the server list. Query protocols (like Valve's A2S_INFO on UDP port 27015) stop responding because the kernel is too busy with SYN processing. The master server marks your server as offline, and it vanishes from the browser. Even after the attack stops, it can take minutes to reappear.
- RCON and admin panels stop working. RCON (Remote Console) uses TCP. If the SYN backlog is exhausted, your own admin tools cannot connect, which means you cannot even restart the server or kick problematic players during the attack.
- No bandwidth alarm fires. A SYN packet is 40-60 bytes. At 200,000 PPS, that is roughly 80 Mbps. On a 1 Gbps link, your bandwidth utilization is under 10%. Most hosting dashboards will show the link as barely loaded.
The defining characteristic of a game server SYN flood is that everything breaks but nothing looks overloaded in traditional bandwidth monitoring. You need packet-level and connection-state visibility.
Game Server Traffic vs. Web Traffic
To detect a SYN flood on a game server, you first need to understand what normal traffic looks like. Game servers are not web servers. The traffic profile is fundamentally different.
Web servers handle mostly TCP traffic. A baseline is easy to establish: X connections per second, Y requests per second, Z bytes per second. Any sudden spike in SYN packets relative to established connections is suspicious.
Game servers are UDP-heavy. Minecraft uses TCP for the game protocol itself, but most other engines (Source, Unreal, Raknet) use UDP for gameplay and only use TCP for ancillary services. A typical game server might see this traffic split:
- UDP port 7777 (game traffic): 20,000-80,000 PPS, depending on player count
- UDP port 27015 (query/A2S): 500-2,000 PPS from server list scanners
- TCP port 7777 or 7778 (join/auth): 2-20 new connections per minute during normal operation
- TCP port 27020 (RCON): Near zero unless an admin is connected
That TCP profile is the key. Under normal conditions, your game server sees almost no TCP SYN traffic. When a SYN flood hits, the SYN rate jumps from single digits per second to tens or hundreds of thousands. That contrast makes detection straightforward if you are monitoring the right counters.
Detecting SYN Floods with /proc/net/snmp
The Linux kernel tracks TCP extension statistics in /proc/net/snmp and /proc/net/netstat. Two counters are critical for SYN flood detection:
TcpExtSyncookiesSent- Increments every time the kernel sends a SYN cookie because the SYN backlog is full. Under normal operation, this counter should be zero or near zero.TcpExtTCPReqQFullDrop- Increments when a SYN is dropped because the request queue is full and SYN cookies are disabled or the cookie validation failed. This represents lost connections.
Here is how to read them:
cat /proc/net/netstat | awk '/TcpExt:/ {if(NR%2==1){split($0,h)} else {for(i=1;i<=NF;i++) if(h[i]~/SyncookiesSent|TCPReqQFullDrop/) print h[i]"="$i}}'
On a healthy game server with no attack traffic, the output looks like this:
TcpExtSyncookiesSent=0 TcpExtTCPReqQFullDrop=0
During a SYN flood, you will see something like this:
TcpExtSyncookiesSent=847293 TcpExtTCPReqQFullDrop=12841
These are cumulative counters. To measure the rate, sample them twice with a one-second gap:
# Sample every second and print the delta
while true; do
a=$(grep -c '' /dev/null; cat /proc/net/netstat | awk '/TcpExt:/{if(NR%2==1){split($0,h)}else{for(i=1;i<=NF;i++)if(h[i]=="TcpExtSyncookiesSent")print $i}}')
sleep 1
b=$(grep -c '' /dev/null; cat /proc/net/netstat | awk '/TcpExt:/{if(NR%2==1){split($0,h)}else{for(i=1;i<=NF;i++)if(h[i]=="TcpExtSyncookiesSent")print $i}}')
echo "$(date +%H:%M:%S) SyncookiesSent/sec: $((b - a))"
done
If SyncookiesSent/sec is above zero, your kernel is actively defending against a SYN flood. If it is above 1,000, you are under a significant attack. On a game server, where legitimate TCP SYN traffic is minimal, any sustained nonzero value warrants investigation.
Per-Port Monitoring: Game Port vs. Query Port
Not all SYN floods target the same port. Attackers sometimes hit the game port (e.g., TCP 7777), sometimes the query port (TCP 27015), and sometimes random high ports to exhaust the global SYN backlog. You need per-port visibility.
Use ss to count SYN-RECV sockets grouped by destination port:
ss -tn state syn-recv | awk 'NR>1 {split($4,a,":"); port=a[length(a)]; count[port]++} END {for(p in count) printf "port %-6s SYN-RECV: %d\n", p, count[p]}' | sort -t: -k2 -rn
Normal output on a game server:
port 7777 SYN-RECV: 2 port 27020 SYN-RECV: 0
During a SYN flood targeting the game port:
port 7777 SYN-RECV: 4891 port 27020 SYN-RECV: 0
This tells you exactly which port is under attack. If the flood targets your game port, players cannot join. If it targets your RCON port, you lose admin access. If it targets a port you are not even listening on, it still consumes kernel resources and degrades game performance.
Using ss and conntrack to Identify SYN-RECV Buildup
The ss command gives you a real-time view of the TCP state machine. During a SYN flood, the SYN-RECV state is where connections pile up. Here is how to monitor the total SYN-RECV count over time:
# Count SYN-RECV sockets every second watch -n 1 'echo "SYN-RECV: $(ss -tn state syn-recv | tail -n +2 | wc -l) | ESTABLISHED: $(ss -tn state established | tail -n +2 | wc -l)"'
On a healthy server, SYN-RECV will be in single digits while ESTABLISHED will reflect your active player sessions. During an attack, SYN-RECV will climb into the thousands while ESTABLISHED starts dropping as existing connections time out.
If you are running conntrack (common if you use iptables NAT or Docker), you can also check the conntrack table for SYN-RECV saturation:
# Check conntrack table usage cat /proc/sys/net/netfilter/nf_conntrack_count cat /proc/sys/net/netfilter/nf_conntrack_max # Count SYN_RECV entries in conntrack conntrack -L 2>/dev/null | grep SYN_RECV | wc -l # Watch conntrack table fill rate watch -n 1 'echo "conntrack: $(cat /proc/sys/net/netfilter/nf_conntrack_count) / $(cat /proc/sys/net/netfilter/nf_conntrack_max)"'
If nf_conntrack_count is approaching nf_conntrack_max, you are about to start dropping all new connections, including legitimate game traffic. The default nf_conntrack_max on most systems is 65536 or 131072, which a SYN flood can exhaust in seconds.
Checking the source distribution
Real SYN floods from botnets come from thousands of unique source IPs. A quick check:
# Top 10 source IPs in SYN-RECV state
ss -tn state syn-recv | awk 'NR>1 {split($3,a,":"); print a[1]}' | sort | uniq -c | sort -rn | head -10
If you see thousands of unique IPs each with 1-3 SYN-RECV sockets, that is a distributed botnet. If you see a handful of IPs with hundreds of connections each, it is a smaller-scale attack that is easier to block with simple firewall rules.
iptables Rate Limiting for Game Server Ports
Once you have confirmed a SYN flood, you can deploy emergency iptables rules targeted at your game server ports. The goal is to rate-limit SYN packets without blocking legitimate players.
First, create a chain specifically for game server SYN protection:
# Create a dedicated chain for game port SYN limiting iptables -N GAME_SYN_LIMIT 2>/dev/null # Rate limit SYN packets to the game port (7777) # Allow 20 new SYN/sec with burst of 40 (enough for player joins) iptables -A INPUT -p tcp --dport 7777 --syn -j GAME_SYN_LIMIT iptables -A GAME_SYN_LIMIT -m hashlimit \ --hashlimit-above 20/sec \ --hashlimit-burst 40 \ --hashlimit-mode srcip \ --hashlimit-name game_syn \ --hashlimit-htable-expire 30000 \ -j DROP iptables -A GAME_SYN_LIMIT -j ACCEPT # Rate limit SYN packets to the query port (27015) iptables -A INPUT -p tcp --dport 27015 --syn -m limit \ --limit 10/sec --limit-burst 20 -j ACCEPT iptables -A INPUT -p tcp --dport 27015 --syn -j DROP # Rate limit SYN packets to RCON (27020) - very restrictive iptables -A INPUT -p tcp --dport 27020 --syn -m limit \ --limit 2/sec --limit-burst 5 -j ACCEPT iptables -A INPUT -p tcp --dport 27020 --syn -j DROP
Key points for game server operators:
- Use
hashlimit, notlimit, for the game port. Thelimitmodule is global. If an attacker sends 100k SYN/sec, the global rate limit will consume all 20 allowed SYN/sec with attack traffic, and legitimate players get blocked.hashlimitwithsrcipmode applies the limit per source IP, so each player gets their own bucket. - Set the burst higher than you think. When a player connects, some game engines send multiple SYN packets in quick succession (connection attempt, resource download, voice channel). A burst of 40 handles this without false positives.
- RCON should be very restrictive. You only need 1-2 RCON connections at a time. Rate limiting it to 2/sec is aggressive but safe.
For Minecraft servers specifically, where the game protocol is entirely TCP:
# Minecraft SYN protection (port 25565) # Higher limit because ALL game traffic is TCP iptables -A INPUT -p tcp --dport 25565 --syn -m hashlimit \ --hashlimit-above 5/sec \ --hashlimit-burst 10 \ --hashlimit-mode srcip \ --hashlimit-name mc_syn \ --hashlimit-htable-expire 30000 \ -j DROP
Also consider enabling SYN cookies at the kernel level if they are not already active:
# Enable SYN cookies (usually on by default, but verify) sysctl -w net.ipv4.tcp_syncookies=1 # Increase the SYN backlog sysctl -w net.ipv4.tcp_max_syn_backlog=8192 # Reduce SYN-ACK retries (default is 5, lower = faster cleanup) sysctl -w net.ipv4.tcp_synack_retries=2
Putting It Together: A Detection Script
Here is a minimal bash script that checks all the indicators and prints a status line. Run it in a tmux session alongside your game server:
#!/bin/bash
# game-syn-monitor.sh - SYN flood monitor for game servers
GAME_PORT=7777
WARN_THRESHOLD=50
CRIT_THRESHOLD=500
prev_cookies=$(awk '/TcpExt:/{if(NR%2==1){split($0,h)}else{for(i=1;i<=NF;i++)if(h[i]=="TcpExtSyncookiesSent")print $i}}' /proc/net/netstat)
while true; do
sleep 1
curr_cookies=$(awk '/TcpExt:/{if(NR%2==1){split($0,h)}else{for(i=1;i<=NF;i++)if(h[i]=="TcpExtSyncookiesSent")print $i}}' /proc/net/netstat)
cookie_rate=$((curr_cookies - prev_cookies))
prev_cookies=$curr_cookies
syn_recv=$(ss -tn state syn-recv dst :${GAME_PORT} | tail -n +2 | wc -l)
established=$(ss -tn state established dst :${GAME_PORT} | tail -n +2 | wc -l)
if [ "$cookie_rate" -ge "$CRIT_THRESHOLD" ] || [ "$syn_recv" -ge 1000 ]; then
status="CRITICAL"
elif [ "$cookie_rate" -ge "$WARN_THRESHOLD" ] || [ "$syn_recv" -ge 100 ]; then
status="WARNING"
else
status="OK"
fi
printf "\r%s [%s] cookies/s=%-6d syn-recv=%-5d established=%-4d" \
"$(date +%H:%M:%S)" "$status" "$cookie_rate" "$syn_recv" "$established"
done
How Flowtriq Detects This Automatically
Everything described above works, but it requires you to be watching a terminal when the attack happens. Game server attacks often happen at peak hours, during tournaments, or at 3 AM when a rival community decides to knock your server offline. You will not always be at your keyboard.
Flowtriq's lightweight agent runs on your game server and samples /proc/net/snmp, /proc/net/netstat, /proc/net/dev, and the connection state table every second. It calculates the per-second rate of change for every relevant counter, including TcpExtSyncookiesSent, TcpExtTCPReqQFullDrop, SYN-RECV socket count, and per-interface PPS.
Instead of relying on fixed thresholds, Flowtriq builds a rolling baseline of your server's normal traffic profile. It learns that your Rust server normally sees 45,000 UDP PPS and near-zero TCP SYN traffic. When SYN packets jump from 3/sec to 15,000/sec, the anomaly detection fires within 1-2 seconds of attack onset.
The alert includes:
- The exact attack vector (SYN flood) and target port
- Current SYN-RECV count and SYN cookie send rate
- Top source IPs and ASNs contributing to the flood
- A PCAP capture of the attack traffic for forensic analysis
- Duration and peak PPS once the attack subsides
Alerts go to Discord, Slack, PagerDuty, OpsGenie, email, SMS, or a custom webhook. For game server operators, the Discord integration is particularly popular because you can pipe alerts directly into your staff channel.
Flowtriq also tracks attacks historically, so when you file an abuse report with the attacking network or request better upstream filtering from your hosting provider, you have timestamped, detailed evidence of every incident.
Stop SYN floods before your players notice
Flowtriq monitors your game server every second. Per-second detection, automatic classification, PCAP forensics, and instant alerts to Discord, Slack, or PagerDuty. $9.99/node/month.
Start your free 7-day trial →