Protecting an ARK server from DDoS attacks

Published on 16 min read

Ports, a rate limit on the query port, RCON and real measurements: what you can secure on an ARK cluster yourself, and at what attack size that is no longer enough.

An ARK cluster rarely goes down at a random moment. Anyone who runs PvP servers knows the pattern: shortly before an enemy base falls, the server becomes unreachable, every player is thrown out, and by the time it comes back the raid is over. This article starts with what you can configure on the server itself, then shows where those measures technically end, and finally what KernelHost puts in front of them.

Why ARK in particular gets attacked so deliberately

With most games, a server outage is annoying. With ARK: Survival Evolved and ARK: Survival Ascended it is a move in the game. Losses in game are permanent, a raid window lasts a few minutes, and any offline raid protection only works for as long as the server is reachable. Take the defenders out of the game for ten minutes and you walk away with resources and creatures. The attack therefore has a concrete payoff and a planned moment, and it repeats itself as soon as it has worked once.

On top of that comes the way a cluster is built. Several maps usually run on the same machine behind the same IP address. An attack therefore does not hit one server, it hits The Island, Ragnarok, Aberration and the transfer between them at the same time. Players who get stuck in the middle of a transfer can lose their character and their items in the worst case. What happens technically during a DDoS attack is described in the article What is a DDoS attack?.

The ports that matter

ARK carries its game traffic entirely over UDP. That is the reason why many firewall guides do not help here: they open TCP.

Port Protocol Purpose Applies to
7777 UDP game traffic both titles
7778 UDP second socket of the engine (game port plus one) Survival Evolved only
27015 UDP status query for the server list both titles
27020 TCP RCON remote control, optional both titles

Survival Evolved additionally occupies the port directly above the game port, because the engine opens a second UDP socket there. Survival Ascended no longer needs that second port. The query port answers status requests in the Steam format (server name, map, player count, in game time) and is the most interesting port for attackers.

In a cluster you assign the ports in steps of two, so that the second socket does not collide with the next instance: 7777 and 7778 for the first map, 7779 and 7780 for the second, plus 27015 and 27016 as query ports.

What you can do yourself before spending money

The following steps cost nothing and work against the most common cases: small targeted floods from a handful of sources, abused query ports and attempts to take control through RCON. They are worth doing even when a network filter is already working in front of the server.

1. Open only what the cluster really needs

An ARK host ends up with more open ports than you would expect: a panel, a database, a web server for the map, plus the game instances. Every one of them is a target for packets. The following nftables ruleset for /etc/nftables.conf lets through what a cluster with two maps needs and drops the rest.

#!/usr/sbin/nft -f

flush ruleset

table inet ark {
    set adminips {
        type ipv4_addr
        flags interval
        elements = { 203.0.113.10 }
    }

    set queryflood {
        type ipv4_addr
        size 65535
        flags dynamic,timeout
        timeout 1m
    }

    chain input {
        type filter hook input priority 0; policy drop;

        iif lo accept
        ct state established,related accept
        ct state invalid drop

        ip saddr @adminips tcp dport { 22, 27020 } accept

        udp dport { 7777-7780 } accept

        udp dport { 27015-27016 } add @queryflood { ip saddr limit rate over 10/second burst 20 packets } drop
        udp dport { 27015-27016 } accept

        icmp type echo-request limit rate 5/second accept
        icmpv6 type { echo-request, nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert } accept

        counter drop
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Enter your own static IP address under adminips before you load the ruleset, otherwise you lock yourself out of SSH.

nft -c -f /etc/nftables.conf
systemctl enable --now nftables
nft list ruleset

nft -c only checks the syntax and changes nothing. The second command is the one that loads the ruleset and makes it survive a reboot. If you prefer working with UFW, you will find that route in Setting up the UFW firewall. One caveat: flush ruleset also deletes the rules created by UFW and Docker. If either of them is running, leave that line out.

2. Rate limit the query port instead of closing it

The query port is the only port where your server sends a noticeably larger answer to any stranger who sends a tiny request. Two problems follow from that. First, your server can be abused as an amplifier: the attacker forges the source address, your server answers a victim it has never heard of, and your line carries the outbound traffic. Second, every answer costs CPU time in exactly the process that also runs the game. A flood against 27015 therefore often shows up as stuttering and not as a dropped connection.

Closing the port is not a solution, because the server then disappears from the server list. The rule above limits per source address instead: ten queries per second with a burst of twenty packets is enough for players and for monitoring, while a source sending thousands of requests per second is dropped. To see which addresses are currently being limited:

nft list set inet ark queryflood

3. Take RCON off the internet

RCON gives full control: whoever has the password can remove players, shut the server down and reach into the game world. The port is TCP, the password sits in plain text in the configuration, and login attempts can be repeated as often as you like. That is why the ruleset above opens it only for the admin address.

[ServerSettings]
RCONEnabled=True
RCONPort=27020
ServerAdminPassword=<long random password>

The file GameUserSettings.ini lives under ShooterGame/Saved/Config/ in the server directory. A usable password is generated by:

openssl rand -base64 24

If a web panel on the same machine uses RCON, access over 127.0.0.1 is enough and the port stays closed from outside. If the panel runs somewhere else, its address belongs in adminips and nowhere else.

4. Take load off connection tracking

A UDP flood often does not kill a Linux server through bandwidth, it kills it through connection tracking. The kernel creates an entry for every incoming UDP packet, the table fills up, and after that it drops the packets of real players as well, which you can recognize by nf_conntrack: table full, dropping packet in the system log. Connection tracking is of no use for game traffic, so take the game ports out of it:

table inet arkraw {
    chain prerouting {
        type filter hook prerouting priority -300; policy accept;
        udp dport { 7777-7780, 27015-27016 } notrack
    }

    chain output {
        type filter hook output priority -300; policy accept;
        udp sport { 7777-7780, 27015-27016 } notrack
    }
}

Both directions are needed, otherwise half entries are created for outbound traffic. Add a few kernel parameters in /etc/sysctl.d/90-ark.conf as well:

net.netfilter.nf_conntrack_max = 262144
net.netfilter.nf_conntrack_udp_timeout = 15
net.netfilter.nf_conntrack_udp_timeout_stream = 60
net.core.netdev_max_backlog = 16384
net.core.rmem_max = 16777216
net.ipv4.tcp_syncookies = 1
sysctl --system
cat /proc/sys/net/netfilter/nf_conntrack_count

If that second value climbs toward the maximum during an attack, connection tracking was the bottleneck and not the line.

5. Whitelist and server password

If your cluster serves a closed group anyway, an access list is the most effective measure against troublemakers. ARK brings one with it, and the server is started with -exclusivejoin for that:

./ShooterGameServer "TheIsland?listen?SessionName=MyCluster?Port=7777?QueryPort=27015?RCONEnabled=True?RCONPort=27020" -server -log -exclusivejoin

The allowed players are then listed, one ID per line, in PlayersExclusiveJoinList.txt in the directory of the server binary. While the server is running you maintain the list through the server console or through RCON:

AllowPlayerToJoinNoCheck <player ID>
DisallowPlayerToJoinNoCheck <player ID>

A server password set through ServerPassword works in a similar way, but experience shows that it gets passed around quickly. Both share the same hard limit: the check happens inside the game process, so only after the packet has arrived. A whitelist does nothing against a packet flood, but it does plenty against the player who is scouting your cluster first.

6. What anti-cheat and plugins do, and what they do not

Both titles run an anti-cheat system out of the box, and on top of that there are server plugins built on the respective server API. Both are useful, but they solve a different problem. Anti-cheat checks whether a connected client has been tampered with, and a plugin can count connection attempts or disconnect players that behave suspiciously. All of these checks run in the same process as the game and only take effect once the packet is being processed. If that process is saturated, the protection logic goes down with it. That is why a plugin that fends off DDoS attacks cannot exist. What does help: keep server files and mods up to date and keep their number small, because a good share of the crashes in ARK clusters are broken mods and not attacks.

7. Your address is in the server list

A publicly listed ARK server publishes its IP address and query port, because otherwise nobody could find it, and those lists are queried and archived automatically around the clock. Your address is therefore known the moment the server has been listed once. Hiding is not an option, because a server that is not listed does not grow. What remains are the side channels through which an address leaks in addition:

  • Old DNS records. An A record that still points at the previous server gives away the old address. Records like that should be deleted.
  • Other services on the same address. A website, a map viewer, a panel, a voice server and a database are each a second way to hit the cluster.
  • Your own Discord. Status bots, screenshots from the console and connection guides often contain the address in plain text.

8. Measure instead of guessing

The most common mistake in the middle of an incident is the wrong diagnosis. A crashed mod, a full file system and a real attack all feel the same to your players. Telling them apart takes a minute. First the packet rate on the network card:

r1=$(cat /sys/class/net/eth0/statistics/rx_packets)
sleep 1
r2=$(cat /sys/class/net/eth0/statistics/rx_packets)
echo "$((r2-r1)) packets per second"

A cluster with fifty players normally sits in the low five-digit range, while six- or seven-digit values are an attack. After that the counters of the network stack:

nstat -az UdpInDatagrams UdpNoPorts UdpRcvbufErrors
ss -ulnp | grep -E '7777|27015'

UdpNoPorts rises when packets arrive on ports where nothing is listening, a typical sign of a blindly scattered flood. UdpRcvbufErrors rises when the server process no longer picks the packets up fast enough. Finally the log file of the game:

tail -n 200 ShooterGame/Saved/Logs/ShooterGame.log

If there is a crash report in it while the packet counters look unremarkable, it was not an attack. Do without tcpdump during an incident, because the capture costs CPU time on a system that has none to spare right now. More characteristics are listed in the article Detecting a DDoS attack on your server.

Where these measures stop

Everything described so far takes effect on the server, and that is exactly where the limit lies. A firewall rule can only drop what has already arrived. The bottleneck, however, sits in front of it, on the line.

The numbers are unambiguous. A 1 Gbps uplink is saturated at around 1.49 million packets per second with the smallest possible packets, regardless of what the server intends to do with them. A real UDP flood against an ARK game server at KernelHost, port 7777, reached over 112.2 Gbps and over 8.7 million packets per second, which averages out to roughly 1.6 kilobytes per packet. That is 112 times a 1 Gbps line and still more than eleven times a 10 Gbps line.

The second bottleneck is reached just as quickly: with an ordinary ruleset, a single CPU core drops a few hundred thousand packets per second, depending on the hardware. At 8.7 million that calculation does not work out even with many cores. The rule matches correctly and the server is offline anyway.

Volumetric attacks therefore have to be filtered in the network in front of the server. On the server itself the problem cannot be solved, neither with more hardware nor with a better ruleset.

What KernelHost puts in front of it

The included always-on protection on every server

Every KernelHost server runs a two-layer always-on DDoS protection, with nothing to order and nothing to configure. The first layer is a global scrubbing network with 17 Tbps of mitigation capacity: volumetric attacks are caught close to their source, long before they reach the datacenter. The second layer is Arbor real-time filtering with 3.2 Tbps on premise in the maincubes datacenter in Frankfurt am Main, Germany. It does the fine-grained work on layers 3, 4 and 7 and knows the protocol patterns of common game servers.

Three properties make the difference. The protection is permanently active, so there is no reaction time in which an attack would first have to be detected. No null-routing is used: the attacked IP address stays in the network and only the malicious packets are dropped. And it costs nothing extra. What that looks like for game servers is described in the article Real-time game server DDoS protection.

Advanced DDoS Protection for projects under permanent attack

Some clusters are not hit once, they are hit for weeks, every evening at the same time and with changing patterns. For those there is Advanced DDoS Protection from €50.00 per month, PrePaid and therefore with no minimum term, no notice period, no contract and no setup fee.

You get a dedicated protected IP address from the Frankfurt core. Your server is moved onto it inside the KernelHost network, so nothing has to be rebuilt on your side. The difference comes afterwards: you manage the protection rules yourself in the customer panel, separately per port and protocol, and changes take effect in real time, without a ticket. As the protection profile you pick the title that the port in question serves, available for over 40 games, services and protocols, including ARK: Survival Evolved. For a cluster that means the game profile on the game ports, a tighter limit on the query port and a rule of its own for a web panel, instead of the same compromise everywhere.

The two layers compared

Feature Included always-on protection Advanced DDoS Protection
Cost no surcharge, part of every server package from €50.00 per month, PrePaid with no minimum term
Activation already running, nothing to order ordered in the customer panel, ready within minutes
IP address the IP address of your server an additional dedicated protected IP from the Frankfurt core
Capacity 17 Tbps global scrubbing network plus 3.2 Tbps Arbor real-time filtering in Frankfurt am Main the same capacity, with your own ruleset in front of it
Rules detected and maintained automatically self-managed per port and protocol, effective in real time
Protection profile automatic, optimized for game server traffic matched to the specific game, over 40 games, services and protocols
Null-routing no no
Useful for every server and every cluster projects that are attacked deliberately and continuously

Common mistakes and their fixes

Only TCP opened, the server runs but nobody gets in: the game traffic of ARK is UDP, and a rule for tcp dport 7777 changes nothing about that. Check with ss -ulnp and open the ports as udp dport.

The server is reachable but does not appear in the server list: usually the query port is closed or the rate limit is too tight. Open 27015 UDP and raise the limit. As a check, nft list set inet ark queryflood shows which addresses are being limited.

Your own status bot reports the server as offline although players are on it: a Discord bot queries from a single source address, often several times per second and separately for every map, and therefore runs into the same limit as an attacker. Put an exception for that address in front of the limit rule.

SSH no longer works after loading the ruleset: the wrong address was in adminips, or SSH runs on a different port. You get back onto the server through the VNC console in the customer panel, since there is no IPMI or iDRAC on the dedicated servers and KVM root servers. Run nft flush ruleset there as the emergency brake, then correct the file.

sysctl cannot set the conntrack values: the parameters under net.netfilter only exist once the module is loaded. Load it with modprobe nf_conntrack and run sysctl --system again.

A supposed attack is really a mod: if the packet counters are normal and there is a crash report in ShooterGame.log, the cause was not the network. After an update in the Workshop that is the most likely explanation, especially when it is always the same map that is affected.

The whole cluster goes offline at once: all instances hang off the same IP address, so an attack hits everything in one go, transfers included. A dedicated protected IP solves exactly this pattern, because the filtering then sits in front of the address instead of on the server behind it.

In short

Open only the game ports, the query port and the access for your own address, rate limit the query port per source, keep RCON off the internet and measure packet rates before you assume a cause. That costs nothing and covers everyday operations. Everything beyond that is no longer decided on the server: the included always-on protection, with 17 Tbps of mitigation capacity in the global scrubbing network and 3.2 Tbps of Arbor real-time filtering in Frankfurt am Main, absorbs it at no surcharge and without null-routing. Under permanent fire, Advanced DDoS Protection adds a dedicated protected IP with rules you set yourself. The operator is KernelHost GmbH, based in Vienna, Austria.

Frequently asked questions

My ARK server went offline in the middle of a raid. What do I check first?
The packet rate on the network card, not the game log. Read /sys/class/net/eth0/statistics/rx_packets twice, one second apart. A cluster with fifty players normally sits in the low five-digit range, while six- or seven-digit values are an attack. If the counters look unremarkable and there is a crash report in ShooterGame.log, it was not an attack but usually a mod.
Which ports does an ARK server really need?
7777 UDP for the game traffic, and on ARK: Survival Evolved additionally 7778 UDP, because the engine opens a second socket there. ARK: Survival Ascended does not need that second port. On top of that comes the query port 27015 UDP for the server list and optionally 27020 TCP for RCON. Everything else can stay closed.
Should I simply close query port 27015?
No. Your server would then disappear from the server list. Rate limit it per source address instead, for example to ten queries per second with a small burst. That is enough for real players and for your monitoring, but it drops a source that sends thousands of requests per second.
Can a plugin or the anti-cheat stop a DDoS attack?
No. Both run in the same process as the game and only check once a packet is already being processed. If that process is saturated, the protection logic goes down with it. Plugins and anti-cheat help against cheaters and troublemakers, not against attacks on availability.
Why does my firewall no longer help during a large attack?
Because it can only drop what has already arrived. A 1 Gbps uplink is saturated at around 1.49 million packets per second with the smallest possible packets. A real UDP flood against an ARK server reached over 112.2 Gbps and over 8.7 million packets per second. The rule matches correctly and the line is full anyway. Volumetric attacks have to be filtered in the network in front of the server.
Is my IP address taken offline during an attack?
Not at KernelHost. No null-routing is used. The attacked IP address stays in the network, only the malicious packets are dropped, and the connections of real players keep running.
Does DDoS protection at KernelHost cost extra?
No. Every server runs a two-layer always-on protection at no surcharge: a global scrubbing network with 17 Tbps of mitigation capacity and Arbor real-time filtering with 3.2 Tbps on premise in the maincubes datacenter in Frankfurt am Main. It is permanently active, so there is nothing for you to switch on.
When do I additionally need Advanced DDoS Protection?
When your cluster is attacked deliberately and continuously, for example every evening at the same time and with changing patterns. You get a dedicated protected IP for it and manage the protection rules yourself in the customer panel, separately per port and protocol, with a protection profile matched to the game. Changes take effect in real time. The price starts at €50.00 per month, PrePaid and with no minimum term.

ARK server Survival Evolved Survival Ascended Game server DDoS protection UDP flood nftables RCON Cluster