Protecting an Unturned server from DDoS attacks
Which ports an Unturned server really needs, why 27017 has been obsolete since 2021, how to limit query floods, join floods and plugin load, and from which attack size on only upstream filtering still helps.
An Unturned server that disappears from the server list for a few minutes every evening and drops every player with a timeout rarely has a hardware problem. Usually an attack is running, and it runs exactly when the server is busiest. This article starts with what you can secure yourself at no extra cost, then shows where those measures technically end, and finally explains what has to happen in the network in front of the server.
Everything here refers to the Unturned Dedicated Server (U3DS, SteamCMD app ID 1110390) on Debian 12, Debian 13, Ubuntu 22.04 LTS or Ubuntu 24.04 LTS. The commands are written for root. As a normal user, put sudo in front of them. If the attack is running right now, do not change the configuration and do not restart the server: capture the measurements first (section 10), because once the attack is over they are gone.
Why Unturned servers get attacked so often
Unturned servers get attacked because their address is public, because the game traffic runs over UDP, and because an attack costs whoever orders it neither skill nor any serious amount of money. All three points apply more strongly here than they do for most other games.
A public Unturned server publishes its IP address all by itself. It has to, because otherwise nobody would find it: the Steam server browser queries it directly, and third-party lists such as unturned-servers.net or BattleMetrics carry the IP address and the port in plain text. unturned-servers.net states that it checks every five minutes whether the server accepts UDP connections on the server port. For an attacker that is not work, it is a search form.
Then there is the player base. Unturned is free to play, the barrier to entry is zero, and there is real competition between roleplay and survival projects for the same players. A banned player, an offended former admin or a neighboring project does not need any access to your server to make it unusable for an hour. For the details of what a DDoS attack is and why spoofed source addresses make it so hard to trace, read What is a DDoS attack?.
The ports that actually matter
An Unturned server occupies exactly two consecutive UDP ports: the value set in Commands.dat and that value plus one. By default those are 27015 and 27016. The official documentation by Smartly Dressed Games describes the split like this: the first port carries the server list queries, the second one carries the in-game traffic. Only the first one is configured, the second follows automatically.
Name My Unturned Server
Port 27015
MaxPlayers 24
Map PEI
Mode Normal
Perspective Both
Owner 76561198000000000
Commands.dat lives at U3DS/Servers/<instance>/Server/Commands.dat. Its format is idiosyncratic and a frequent source of errors: one command per line, no equals sign, the value separated by a single space, and the commands are case sensitive. Lines starting with // are comments.
The most important point for your firewall is this: port 27017 has not been needed since version 3.21.30.0 of November 21, 2021. Before that release an Unturned server required three ports, because the Steam query sat on port plus two. With that update the query shares the port with the server itself, and the third port became obsolete. Router guides, host wikis and forum posts still name 27017 to this day. An open 27017 no longer gives you anything, it is pure attack surface.
Equally important: Unturned has no built-in RCON port. The official documentation only knows console input and console output, which can be replaced through the ICommandInputOutput interface. Every remote console you see on an Unturned server comes from a plugin and brings its own TCP port with it. You have to find that port yourself and restrict it yourself, because nobody has secured it for you.
| Item | Value (default) | Protocol | Where it is set |
|---|---|---|---|
| Query port (Steam A2S, server list) | 27015 | UDP | Port in Commands.dat |
| Game port | 27016 (port plus one) | UDP | not configurable separately |
| Third port 27017 | obsolete since 3.21.30.0 (2021-11-21) | none | close it |
| Second server on the same machine | 27017, the third one 27019 | UDP | Port, spacing of two |
| RCON | no built-in port | TCP through a plugin only | plugin configuration |
| Bind address | all interfaces | none | Bind in Commands.dat |
| Packets per player and second | 50.0 | UDP | Max_Packets_Per_Second |
| Maximum accepted ping | 750 ms | none | Max_Ping_Milliseconds |
| Join rate per time window | 10 attempts in 40.0 seconds | none | Rate_Limit_Kick_Threshold |
| Queue | 8 slots, 64 at most | none | Queue_Size in Commands.dat |
| Anti-cheat | VAC and BattlEye, both enabled | none | VAC_Secure, BattlEye_Secure |
| Amplification factor of the Steam query | 5.5 (US-CERT TA14-017A) | UDP | property of the protocol |
| Normal inbound packet rate with 24 players | around 1,200 packets per second | UDP | 24 times 50 |
| Saturation of a 1 Gbps uplink | 125 MB/s, around 1.49 million packets per second at 64 bytes | none | physics of the uplink |
| Attacks filtered on KernelHost servers | 473.4 Gbps at 41.5 million packets per second; 112.2 Gbps UDP flood | UDP | measurements from operations |
What you can do yourself before spending money
This section is the longest one, and that is deliberate. A cleanly configured Unturned server survives small and medium attacks under its own power, no matter who hosts it.
1. Take stock: what is actually listening
Before you write a single rule, check what your server offers to the outside. Do not guess, look:
ss -lnup
ss -lntp
The first command shows the listening UDP sockets, the second one the TCP sockets. The interesting column is the local address. 0.0.0.0:27015 and [::]:27015 mean "reachable from the entire internet", 127.0.0.1:3306 means "local only" and needs no firewall rule. Next to the game you will often find an RCON plugin, a web panel, a database and an old test server on 27017 that nobody uses any more. A port scan from outside gives you the attacker's view, and for Unturned it explicitly has to cover UDP:
nmap -Pn -sU -p 27000-27050 YOUR.SERVER.IP.ADDRESS
nmap -Pn -p- --min-rate 1000 YOUR.SERVER.IP.ADDRESS
2. Leave open only 27015 and 27016
Two UDP rules facing the outside are enough for Unturned. The game itself needs no TCP port at all: the official documentation explicitly requires UDP for both ports, and the networking layer of the game (Steam Networking Sockets, the default since an update) works over UDP exclusively. Anyone who opens TCP on top of that is following an outdated guide.
ufw allow 22/tcp comment 'SSH'
ufw allow 27015/udp comment 'Unturned query'
ufw allow 27016/udp comment 'Unturned game'
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ufw status verbose
The order matters, otherwise you lock yourself out. The full guide including the escape route is in Setting up the UFW firewall without locking yourself out. If you run several instances, keep the recommended spacing of two (27015, 27017, 27019) and open exactly the two ports each instance really occupies.
A web panel, a database or an RCON plugin have no business on the open internet. Restrict the respective port to your own address with ufw allow from 203.0.113.10 to any port 8080 proto tcp, or reach the interface through a local SSH forward with ssh -N -L 8080:127.0.0.1:8080 root@YOUR.SERVER.IP.ADDRESS. The database gets bound to 127.0.0.1.
3. Securing the query port without dropping off the server list
The query port is the most sensitive spot of an Unturned server. Through it the server answers the Steam queries A2S_INFO, A2S_PLAYERS and A2S_RULES. Block it completely and the server vanishes from every server list, even though it is running perfectly.
An A2S reply is considerably larger than the request. US-CERT lists the Steam protocol in its overview of UDP-based amplification attacks (TA14-017A) with a bandwidth amplification factor of 5.5. In practice that means an attacker sends queries with a spoofed source address to other people's game servers and directs the roughly five and a half times larger replies at the actual target. Your server is then not the victim but the amplifier against a third party. In the other direction, a query flood is enough to make the server disappear from the server browser without a single player being dropped. Operators report exactly that: the server is running, the players on it notice nothing, but it can no longer be found.
Against small query floods an upper limit per source address helps. Legitimate queries are rare: the Steam browser asks once per listing, status services every few minutes.
iptables -I INPUT -p udp --dport 27015 -m hashlimit --hashlimit-name unturned_query --hashlimit-mode srcip --hashlimit-above 10/sec --hashlimit-burst 20 -j DROP
iptables -I INPUT -p udp --dport 27016 -m hashlimit --hashlimit-name unturned_game --hashlimit-mode srcip --hashlimit-above 300/sec --hashlimit-burst 500 -j DROP
The second number follows directly from the game: out of the box Unturned limits a player to 50 packets per second (Max_Packets_Per_Second). So 300 packets per second and source address leave a single connection plenty of headroom, even when several players sit behind the same address. Both values are starting points, not truths. Measure a week of normal operation first, otherwise you throw out your own players.
Plain iptables rules are gone after a reboot. On Debian and Ubuntu you save them with apt-get install -y iptables-persistent and netfilter-persistent save. Under UFW, such rules belong in /etc/ufw/before.rules, because otherwise they disappear with the next ufw reload.
On top of that comes one habit that costs nothing: if your website or your Discord bot shows the player count, do not query the server from the visitor's browser, but cache the result at fixed intervals instead. Otherwise a busy status page produces one query per visitor instead of one per interval.
4. Setting the built-in limits in Config.json
Unturned ships a section in Config.json, in the same Server folder as Commands.dat, that matters more for defense than its name suggests. The defaults are:
"Server": {
"VAC_Secure": true,
"BattlEye_Secure": true,
"Max_Ping_Milliseconds": 750,
"Timeout_Queue_Seconds": 15.0,
"Timeout_Game_Seconds": 30.0,
"Max_Packets_Per_Second": 50.0,
"Join_Rate_Limit_Window_Seconds": 40.0,
"Rate_Limit_Kick_Threshold": 10,
"Use_FakeIP": false
}
Max_Packets_Per_Second limits a connected player to 50 packets per second. Join_Rate_Limit_Window_Seconds and Rate_Limit_Kick_Threshold drop a connection that exceeds the limit more than ten times within 40 seconds. VAC_Secure and BattlEye_Secure require both anti-cheat systems on the client side and thereby keep most throwaway clients out.
One thing has to be clear: these limits work against clients that actually join or try to. They do not work against a flood with spoofed source addresses, because no session is ever created there. They still matter, because they catch the most common single case: one manipulated client that overloads the server all by itself. Leaving Max_Ping_Milliseconds at 750 is sensible; set lower, the server throws out half a round on every brief network hiccup.
5. Taking load off connection tracking
This point is almost always overlooked and explains outages that look like a volumetric attack but are not one. The kernel creates connection tracking (conntrack) entries for UDP traffic as well, and with spoofed source addresses every new address means a new entry. Once the table is full, the kernel drops packets indiscriminately: the attack and your players go out together. The system log then says nf_conntrack: table full, dropping packet.
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
dmesg -T | grep -i conntrack
The most effective step is not to have the Unturned traffic tracked in the first place. The game manages its sessions itself and needs no state tracking in the kernel:
iptables -t raw -A PREROUTING -p udp --dport 27015 -j NOTRACK
iptables -t raw -A PREROUTING -p udp --dport 27016 -j NOTRACK
Make sure that your allow rules for these two ports no longer rely on ESTABLISHED,RELATED after that, but exist as explicit accept rules. Only then is it worth raising nf_conntrack_max. Whoever enlarges the table first only postpones the problem by minutes and spends memory on it.
If packets arrive faster than the server process picks them up, the receive buffer of the socket overflows on top of that. To the players it looks like packet loss although the uplink is free:
net.core.rmem_max = 16777216
net.core.rmem_default = 1048576
net.core.netdev_max_backlog = 16384
Put the values under /etc/sysctl.d/ and activate them with sysctl --system. The kernel tells you whether they are needed: if UdpRcvbufErrors in nstat -az is rising, or if ss -lunp permanently shows something in the receive queue, they take effect. If both stay at zero, the adjustment changes nothing. That is headroom, not protection.
6. Join floods, the queue and the whitelist
A join flood is an attack in which the attacker uses the regular join path to burn slots and processing time instead of filling the uplink. Unturned brings four tools against it, all of them in Commands.dat:
Queue_Size 32sets the queue. The default is 8 slots, the maximum is 64. A queue that is too large helps an attacker, one that is too small drops real players on every restart.Whitelistedswitches the server to whitelist mode. Players are added from the console withpermit <SteamID64>and removed withunpermit <SteamID64>.Password YourPasswordexcludes everybody who has nothing but the address from a list.Filterrejects players with invalid characters in their name, andMaxPlayers 24keeps the slot count at what the hardware really carries.
A whitelist protects your game logic, not your uplink. An attacker who floods your server does not want to join at all. His packets get rejected, but they have arrived all the same, and that is exactly the point.
7. RocketMod, OpenMod and the plugin side
Unturned has two widely used plugin platforms, and both run in the same process as the server. RocketMod is the older one: its original maintainers stopped maintaining it on December 20, 2019 and released the source code under the MIT license. Since then Smartly Dressed Games maintains the fork Legally Distinct Missile (LDM), which ships with the dedicated server already: you copy Rocket.Unturned from the Extras folder into the Modules folder. The developers explicitly recommend the fork, because it fixes old Rocket problems such as threading exceptions and teleportation exploits.
OpenMod is the newer successor, developed by one of the original Rocket maintainers. It does not replace RocketMod but runs alongside it and can load existing Rocket plugins through an integration. For defense this means two things.
First: every plugin is attack surface inside the main process. A plugin that fires a database query on every chat message or every game event is a self-built denial of service. A single player who triggers that event in a loop then takes the server down without any bandwidth at all. Keep the plugin list short, prefer open-source plugins, and measure the server frame rate after every addition.
Second: because Unturned has no RCON port of its own, every remote console comes from a plugin. After installing one, use ss -lntp to check which TCP port it has opened, and restrict it to your own address. An exposed remote console with a weak password is not a DDoS problem, it is a takeover problem.
8. Workshop content and the join process
Workshop content makes joining expensive, and that has a direct effect on how attackable you are. It is controlled through WorkshopDownloadConfig.json in the same Server folder:
{
"File_IDs": [],
"Ignore_Children_File_IDs": [],
"Query_Cache_Max_Age_Seconds": 600,
"Max_Query_Retries": 2,
"Use_Cached_Downloads": true,
"Should_Monitor_Updates": true,
"Shutdown_Update_Detected_Timer": 600
}
File_IDs holds the Workshop IDs of your maps and mods. On startup the server downloads them together with their dependencies, and every player downloads them automatically while connecting. Three consequences are worth knowing. First, joining takes a long time with large mod lists, and after an attack all players come back at the same time, which loads the server a second time. Second, Should_Monitor_Updates stops the server as soon as a Workshop file is updated: the default Shutdown_Update_Detected_Timer of 600 seconds then leads to a restart that operators regularly mistake for a successful attack. Third, every mod is third-party code on your server.
In practice that means: keep the list as short as possible, check the server log for the Workshop update message first after every unexpected restart, and only turn Should_Monitor_Updates off if you schedule updates yourself.
9. The server list, the Server Code and the Fake IP feature
Your IP address cannot be kept secret as long as the server is publicly listed. Every player who has connected once knows it, and the third-party lists publish it anyway. Two habits still help: never publish the raw address yourself, and connect your players through a hostname so that changing the address does not break every reference. The classic pitfall is the forgotten A record pointing at the old address, which makes any change pointless.
For internet hosting you need a Game Server Login Token (GSLT) from the Steam game server management for app ID 304930 anyway. It additionally keeps your Server Code the same across restarts instead of having it regenerated on every start.
Unturned also offers a Fake IP feature. It is switched on with "Use_FakeIP": true in Config.json, and the console command CopyFakeIP gives you the address you then publish. The traffic runs over the Steam Datagram Relay network afterwards, the assigned addresses are in the range 169.254.0.0 to 169.254.255.255, and the real address of the server is no longer shown to players. Valve describes the traffic as authenticated, encrypted and rate limited.
The price for that is high and rarely mentioned: the address and the port change on every restart, a domain name cannot be pointed at it without your own scripts, and the Steam lists "Favorites" and "History" do not work with it, only the bookmark feature does. Above all, the feature only protects the game path. Your server keeps its real address, and SSH, web panel, database and website stay reachable through it. Anyone who knows the address from an old DNS record, a status page or an earlier connection still attacks it directly. So the Fake IP feature is no substitute for filtering in the network in front of the server, it merely reduces the number of people who know your address at all.
10. Logging, so that you are not guessing during an attack
The most important step is the one almost nobody takes beforehand: build a baseline while everything is still normal. Without a normal value you cannot say after an incident whether 40,000 packets per second was a lot or simply a Friday evening. With apt-get install -y vnstat sysstat the measurement runs permanently in the background. During an incident four commands are enough:
sar -n DEV 1 10
ip -s link show eth0
dmesg -T | tail -50
tcpdump -ni eth0 udp portrange 27015-27016 -c 200 -q
One rule for tcpdump: always cap it with -c, because a capture under full load puts extra strain on a server that is already overloaded. How to read the numbers and how to tell an attack from a software fault is covered in Detecting a DDoS attack on your server.
Where these measures stop
Everything so far runs on your server, which means at the far end of the uplink. A firewall rule decides about a packet that has already traveled down the wire. You can drop it, but you cannot un-send it.
Do the math once. A typical game server sits on 1 Gbps, which is 125 megabytes per second, and the uplink is full as soon as somebody sends more. Normal operation stays far below that: with 24 players and the 50 packets per player and second allowed out of the box, around 1,200 packets per second arrive. A booter service produces a multiple of that without any preparation at all.
The second figure is the packet rate, and it almost always hits earlier than the bandwidth does. With small packets of 64 bytes, around 1.49 million packets per second fit into an uplink of 1 Gbps. Depending on CPU and network card, a normal server kernel handles a few hundred thousand of them before it starts dropping. So an attack that does not even fill a third of your uplink can still take your server down, because the processing time goes into the dropping. Operators experience this as "the utilization was not even high, and yet everything was gone".
For a sense of the magnitudes that really occur: on KernelHost servers we have filtered, among others, an attack of over 473.4 Gbps at over 41.5 million packets per second against a voice server, and a UDP flood of over 112.2 Gbps against a game server. There is no local setting for that. Volumetric attacks have to end in the network in front of the server.
What KernelHost puts up against it
The always-on protection included with every server
DDoS protection at KernelHost is built in two layers and permanently active, with nothing for you to switch on, order or configure:
- Layer 1: 17 Tbps of mitigation capacity in the global scrubbing network. Volumetric attacks are scrubbed close to their source, before they reach the datacenter.
- Layer 2: Arbor real-time filtering with 3.2 Tbps in Frankfurt am Main. Directly in front of the server, protocol-specific patterns are detected and dropped, packet by packet.
Two properties make the difference. The protection runs permanently and does not have to react to an attack first, so there are no opening minutes in which the server is gone. And no null-routing is used: your IP address stays on the network, only the malicious packets are dropped. Whoever takes the IP address off the network achieves the same result for you as the attacker does. The location is Frankfurt am Main. Which games and protocols are covered is listed in Game server DDoS protection with real-time filtering.
Advanced DDoS Protection for projects under constant fire
Some projects are attacked not occasionally, but deliberately and for weeks on end. For those there is Advanced DDoS Protection from EUR 50.00 per month, PrePaid, with no minimum term and no setup fee. The difference is not more capacity, it is control:
- A dedicated protected IP from the Frankfurt core, which your server is switched over to inside our own network. Nothing has to be rebuilt on your side.
- Self-managed protection rules per port and protocol in the customer panel: you define separately what is allowed on 27015 UDP (the queries) and what is allowed on 27016 UDP (the game traffic), without writing a ticket for it.
- Changes take effect in real time, so you can fine-tune while an attack is still running, for example by tightening the queries and leaving the game traffic untouched.
- A protection profile that matches the game, and profiles for modified and custom applications on any TCP or UDP port, which covers a plugin with a port of its own.
The two tiers compared
| Feature | Included always-on DDoS protection | Advanced DDoS Protection |
|---|---|---|
| Price | included in every server package, at no surcharge | from EUR 50.00 per month, PrePaid |
| Filtering capacity | 17 Tbps of global scrubbing plus Arbor real-time filtering with 3.2 Tbps in Frankfurt am Main | the same two-layer filtering |
| IP address | the IP address of your server | an additional dedicated protected IP |
| Rule set | automatic profiles, no configuration needed | your own rules per port and protocol in the customer panel |
| Changes | are applied automatically | take effect in real time, even during an attack |
| Game profile | optimized profiles for common games, Unturned included | a profile matched to the game, also for modified applications |
| Null-routing | no | no |
| Term | tied to the server package | PrePaid, no minimum term, no notice period, no setup fee |
For most Unturned projects the included always-on protection together with a clean server configuration is enough. Advanced DDoS Protection is the answer to somebody taking it personally.
Common mistakes and how to fix them
"My guide says I have to open 27015 through 27017": the guide is older than November 2021. Since version 3.21.30.0 an Unturned server needs only two ports, because the Steam query no longer sits on port plus two. Close 27017 unless a second instance runs there.
"The server is running, but it is on no server list any more": that is the typical picture of a query flood, or of a rule of your own that is too tight on 27015 UDP. Use iptables -L INPUT -n -v to check whether your own rule is counting hits. If the counters climb hard, you are currently filtering away your own list entries. Never block 27015 completely.
"All players drop at the same time with a timeout": first check whether connection tracking has overflowed (dmesg -T | grep -i conntrack). Once the table is full, the kernel drops indiscriminately. Timeout_Game_Seconds is 30 seconds out of the box: whoever comes back within that time keeps their slot.
"The server restarts in the middle of the session": that is rarely an attack. Check the log for the message about a detected Workshop update. Should_Monitor_Updates shuts the server down after the default period of 600 seconds.
"I changed the IP address and was offline again two hours later": the attacker got the new address from the same source as the old one, usually a server list, a Discord bot or an old DNS record. Changing the address buys time, it is not a solution.
"I enabled the Fake IP feature and am still being attacked": it hides the address from new players, but it does not take it away from the server. Anyone who knows it from an old list entry, a status page or an earlier connection still reaches your server directly, and with it SSH and any web panel on the machine.
"My previous provider blocked my IP address": that is null-routing. The provider protects its own network with it, and for you the result is identical to a successful attack, usually for hours afterwards. If in doubt, ask whether traffic is filtered or null-routed. The answer says more about your availability than any hardware spec.
"I do not see anything unusual in tcpdump": if the traffic is already filtered in the network upstream, nothing arrives on the server, exactly as expected. That is the normal case when the filtering works. The other way round applies as well: once the uplink is saturated, even the SSH session you wanted to measure with may no longer reach you. Use the VNC console in the customer panel then, which works independently of the network of the guest system.
In short
- An Unturned server needs exactly two open UDP ports: the
Portvalue set inCommands.dat(27015 by default) and that value plus one (27016). The game itself needs no TCP. - Port 27017 has been obsolete since version 3.21.30.0 of November 21, 2021, because the Steam query no longer sits on port plus two. Anyone who still has it open is following an outdated guide.
- Unturned has no built-in RCON port. Every remote console comes from a plugin, brings its own TCP port with it and has to be restricted by you.
- Query port 27015 is the most sensitive spot: a query flood makes the server invisible in the server list without touching a single player, and according to US-CERT TA14-017A the Steam protocol has an amplification factor of 5.5.
- The limits in
Config.json(Max_Packets_Per_Second50.0,Rate_Limit_Kick_Threshold10 per 40 seconds) only work against clients that really join, not against spoofed source addresses. - A 1 Gbps uplink is full at 125 megabytes per second, and with packets of 64 bytes already at around 1.49 million packets per second. Normal operation with 24 players sits at around 1,200 packets per second. Everything above that is decided by the network in front of the server, not by your firewall.
- At KernelHost the two-layer always-on protection is included with every server package at no surcharge and active from provisioning onwards, without null-routing. Anyone who wants to steer the filter rules themselves adds Advanced DDoS Protection from EUR 50.00 per month.
If your project already runs at KernelHost, the filtering is active without you having to do anything. If you still notice something unusual, open a support ticket so that we can fine-tune the filter rules for your IP address. During an ongoing attack you can also reach us through the WhatsApp emergency chat at +43 650 8209883.
Frequently asked questions
Which ports do I have to leave open for an Unturned server?
Do I have to open port 27017 for Unturned?
My Unturned server is running but has dropped off every server list. Is that an attack?
Does Unturned have a built-in RCON port?
Does the Unturned Fake IP feature protect against DDoS attacks?
Can I defend myself against a DDoS attack with iptables or UFW?
At what attack size can my Unturned server no longer handle it on its own?
Why do Unturned servers get attacked so often?
Do RocketMod or OpenMod plugins help against DDoS attacks?
Does my server at KernelHost go offline during an attack?
Does DDoS protection at KernelHost cost extra?
When do I additionally need Advanced DDoS Protection for my Unturned server?
2026 KernelHost GmbH. All rights reserved. This guide is protected by copyright. Republishing it on other websites, in whole, in part or in edited form, is not permitted without our written consent. Quoting with a source credit and a link is expressly welcome.

